1

I'm working on a module and there is a sub module for scanning barcodes that requires this, quagga.
Currently you have to manually download the library and put it into the libraries dir. If I add this as a dependency to the module you cannot install it without doing this first.

Can I have composer or something download a git repo to the libraries when installing the submodule?

Edit:
libraries.yml

form:
  version: VERSION
  css:
    layout:
      css/commerce_pos_barcode_scanning.css: {}
  js:
    js/commerce_pos_barcode_scanning.js: {}
  dependencies:
    - core/jquery
    - core/drupal
    - commerce_pos/quagga
quagga:
  remote: https://github.com/serratus/quaggaJS.git
  version: 1.0.0
  license:
    name: MIT
    url: https://github.com/serratus/quaggaJS/blob/master/LICENSE
    gpl-compatible: yes
  js:
    /libraries/webrtc/adapter-latest.js: {}
    /libraries/quagga/quagga.min.js: {}

install.yml

function commerce_pos_barcode_scanning_requirements($phase) {
  $requirements = [];
  if ($phase == 'install' || $phase == 'runtime') {
    $path = 'libraries/quagga/quagga.min.js';
    if (!file_exists($path)) {
      $requirements['commerce_pos_barcode_scanning'] = [
        'title' => t('POS Barcode Scanning'),
        'description' => t('To scan barcodes, you need to install the quagga JavaScript library. <a href="/modules/contrib/commerce_pos/modules/barcode_scanning/README.md">How To</a>'),
        'severity' => REQUIREMENT_WARNING,
      ];
    }
    else {
      $requirements['commerce_pos_barcode_scanning'] = [
        'title' => t('POS Barcode Scanning'),
        'severity' => REQUIREMENT_OK,
        'value' => t('quagga JavaScript library has been configured.'),
      ];
    }
  }

  return $requirements;
}
  • It's a JS lib hosted on GitHub OK. So you can either go for a *.libraries.yml pulling that in automatically or use hook_requirements to declare this dep explicitly though this will not prevent your library from being installable if the requirement isn't met. It just creates a warning or error message on the status page. – leymannx Feb 13 at 7:58
  • But maybe you can it get it to work somehow with a composer.json in your module. Though I'm not sure about how this works for (JS) libs not packaged for Composer usage. – leymannx Feb 13 at 7:59
  • @leymannx Thank you for the response. The submodule has a libraries and install already. These do not download the library, just warn that we need it. I'll add them to the Q. – Derek C. Feb 14 at 4:16
  • This is outside the scope of composer, see getcomposer.org/doc/faqs/… – Hudri Feb 14 at 12:30
  • Just as a side note: Quagga is available on asset-packagist.org (but this still is a foreign repo that has to be added to the root project) – Hudri Feb 14 at 13:22
0

You can edit file composer.js

find "web/libraries/{$name}": ["type:drupal-library"], change to

"web/libraries/{$name}": [
                "type:drupal-library",
                "type:bower-asset",
                "type:npm-asset",
                "vendor:npm-asset",
                "vendor:bower-asset",

            ],

add repositories

{
            "type": "package",
            "package": {
                "name": "serratus/quaggaJS",
                "version": "0.12.1",
                "type": "drupal-library",
                "source": {
                    "url": "https://github.com/serratus/quaggaJS.git",
                    "type": "git",
                    "reference": "master"
                },
                "dist": {
                    "url": "https://github.com/serratus/quaggaJS/zipball/master/serratus-quaggaJS-v0.12.1-14-g862df88.zip",
                    "type": "zip"
                },
                "require": {
                    "composer/installers": "^1.0.20"
                }
            }
        }

and run composer require "serratus/quaggaJS"

  • OP is asking how to manage dependencies for a (contrib) module. – leymannx Feb 13 at 7:49
  • ley is right here I believe. I understand how composer works for a project, but not for a module honestly. – Derek C. Feb 14 at 4:18
  • While not the answer to the question, this IMHO is the way better solution than leymannx's anwer. Manually create the composer entry. Don't mix composer-managed and self-downloaded shared libs. What happens when another module wants the same lib with conflicting version requirements? – Hudri Feb 14 at 9:52
  • @Hudri – This version argument doesn't count when you define a proper library with a proper version. The question is just how this library could be downloaded automatically. – leymannx Feb 14 at 12:52
  • I was hopefully going to make it so that this library would auto install when enabling this sub-module, correct. This would go in the project's composer rather than the modules correct? Not what I want sadly – Derek C. Feb 17 at 17:49
0

To have this be done automatically people will simply configure their project's composer.json themselves. So I'd recommend to just explain one more time how this is supposed to be done via Composer on your project's page on drupal.org or in the documentation to your module.


Another inadvisable approach would be to provided a Drush command to download the library. Like Semantic UI API does it. Browse their code on GitLab. The command has not been ported to D8 yet. But I think you'll get the idea. Probably worth looking at their 8.x-1.x branch as well. And see how they solved it in D8.

Below code is from 7.x-1.x. SEMANTIC_UI_DOWNLOAD_URL leads to a Zip file on GitHub.

  $args = func_get_args();
  if ($args[0]) {
    $path = $args[0];
  }
  else {
    //we have dependencies on libraries module so no need to check for that
    //TODO: any way to get path for libraries directory?
    //Just in case if it is site specific? e.g. sites/domain.com/libraries ?
    $path = drush_get_context('DRUSH_DRUPAL_ROOT') . '/sites/all/libraries/semantic_ui';
  }
  // Create the path if it does not exist yet. Added substr check for preventing 
  // any wrong attempts or hacks !
  if (substr($path, -11) == 'semantic_ui' && !is_dir($path)) {
    drush_mkdir($path);
  }
  if (is_dir($path . '/dist')) {
    drush_log(dt('Semantic Ui already present at @path. No download required.', array('@path' => $path)), 'ok');
  }
  elseif (drush_op('chdir', $path) &&
      drush_shell_exec('wget ' . SEMANTIC_UI_DOWNLOAD_URL . '  -O semantic_ui.zip') &&
      drush_shell_exec('unzip semantic_ui.zip') &&
      drush_shell_exec('rm -rf semantic_ui.zip') &&
      drush_shell_exec('mv Semantic-UI-master/dist/* .') &&
      drush_shell_exec('rm -rf Semantic-UI-master')) {
    drush_log(dt('The latest Semantic Ui library has been downloaded to @path', array('@path' => $path)), 'success');
  }
  else {
    drush_log(dt('Drush was unable to download the Semantic Ui library to @path', array('@path' => $path)), 'error');
  }
  • 1
    IMHO a bad idea. What happens when another module wants the same lib with conflicting version requirements? This approach kind of contradicts using composer at all. – Hudri Feb 14 at 9:54
  • @Hudri – Of course you also register it as a proper library. Do you know any other way to auto-download a third-party lib not packaged for Composer from a contrib module? – leymannx Feb 14 at 12:04
  • 1
    I don't know any solution, and composer doesn't even want to this – Hudri Feb 14 at 12:27
  • 1
    Yes, this is a solution and it does answer the OP's question. I just think it is a problematic advice to bypass a composer limitation this way, that's why I've given a -1. You don't need to download it manually, but you have to manually add the foreign repo to the root project. – Hudri Feb 14 at 13:18
  • Or don't put the lib in a shared, composer-managed folder, then this is fine too. – Hudri Feb 14 at 13:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.