Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Composer 'require' command is not idempotent with Composer v2 #1179

Closed
geerlingguy opened this issue Oct 26, 2020 · 7 comments · Fixed by #1180
Closed

Composer 'require' command is not idempotent with Composer v2 #1179

geerlingguy opened this issue Oct 26, 2020 · 7 comments · Fixed by #1180
Labels
bug This issue/PR relates to a bug needs_triage python3

Comments

@geerlingguy
Copy link
Contributor

SUMMARY

The require command for the composer module seems to no longer be idempotent. If I require one or more packages using the composer module, the module always reports 'changed', thus breaking idempotence in my playbooks.

It does seem to still work, installing the required package, but it just always reports a change.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

community.general.composer

ANSIBLE VERSION
# ansible --version
ansible 2.10.1
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.6/dist-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 3.6.9 (default, Jul 17 2020, 12:50:27) [GCC 8.4.0]
CONFIGURATION
N/A
OS / ENVIRONMENT

Linux (CentOS, Ubuntu) and macOS (10.15)

STEPS TO REPRODUCE
- name: Install dependencies with composer require.
  composer:
    command: require
    arguments: "drush/drush:^10.1"
    working_dir: "/var/www/drupal"
  become: false
  environment:
    COMPOSER_PROCESS_TIMEOUT: 1200
    COMPOSER_MEMORY_LIMIT: '-1'
EXPECTED RESULTS

If running that task two times in a row, the second run would report ok with no changes.

ACTUAL RESULTS

The second time the task runs, it still reports a change:

    TASK [geerlingguy.drupal : Install dependencies with composer require (this may take a while).] ***
    task path: /Users/jgeerling/Dropbox/VMs/roles/geerlingguy.drupal/tasks/build-composer-project.yml:36
    redirecting (type: connection) ansible.builtin.docker to community.general.docker
    <instance> ESTABLISH DOCKER CONNECTION FOR USER: root
    <instance> EXEC ['/usr/local/bin/docker', b'exec', b'-i', 'instance', '/bin/sh', '-c', "/bin/sh -c 'echo ~ && sleep 0'"]
    <instance> EXEC ['/usr/local/bin/docker', b'exec', b'-i', 'instance', '/bin/sh', '-c', '/bin/sh -c \'( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1603724927.233592-2797-186180795085662 `" && echo ansible-tmp-1603724927.233592-2797-186180795085662="` echo /root/.ansible/tmp/ansible-tmp-1603724927.233592-2797-186180795085662 `" ) && sleep 0\'']
    redirecting (type: modules) ansible.builtin.composer to community.general.composer
    Using module file /Users/jgeerling/.ansible/collections/ansible_collections/community/general/plugins/modules/composer.py
    <instance> PUT /Users/jgeerling/.ansible/tmp/ansible-local-99444fg58b7oc/tmpwxfpvg5d TO /root/.ansible/tmp/ansible-tmp-1603724927.233592-2797-186180795085662/AnsiballZ_composer.py
    <instance> EXEC ['/usr/local/bin/docker', b'exec', b'-i', 'instance', '/bin/sh', '-c', "/bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1603724927.233592-2797-186180795085662/ /root/.ansible/tmp/ansible-tmp-1603724927.233592-2797-186180795085662/AnsiballZ_composer.py && sleep 0'"]
    <instance> EXEC ['/usr/local/bin/docker', b'exec', b'-i', 'instance', '/bin/sh', '-c', "/bin/sh -c 'COMPOSER_MEMORY_LIMIT=-1 COMPOSER_PROCESS_TIMEOUT=1200 /usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1603724927.233592-2797-186180795085662/AnsiballZ_composer.py && sleep 0'"]
    <instance> EXEC ['/usr/local/bin/docker', b'exec', b'-i', 'instance', '/bin/sh', '-c', "/bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1603724927.233592-2797-186180795085662/ > /dev/null 2>&1 && sleep 0'"]
    changed: [instance] => (item=drush/drush:^10.1) => {
        "ansible_loop_var": "item",
        "changed": true,
        "invocation": {
            "module_args": {
                "apcu_autoloader": false,
                "arguments": "drush/drush:^10.1",
                "classmap_authoritative": false,
                "command": "require",
                "executable": null,
                "global_command": false,
                "ignore_platform_reqs": false,
                "no_dev": true,
                "no_plugins": false,
                "no_scripts": false,
                "optimize_autoloader": true,
                "prefer_dist": false,
                "prefer_source": false,
                "working_dir": "/var/www/drupal"
            }
        },
        "item": "drush/drush:^10.1",
        "msg": "./composer.json has been updated Running composer update drush/drush Loading composer repositories with package information Updating dependencies Nothing to modify in lock file Installing dependencies from lock file (including require-dev) Nothing to install, update or remove Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead. Package phpunit/php-token-stream is abandoned, you should avoid using it. No replacement was suggested. Generating optimized autoload files 54 packages you are using are looking for funding. Use the `composer fund` command to find out more!",
        "stdout": "./composer.json has been updated\nRunning composer update drush/drush\nLoading composer repositories with package information\nUpdating dependencies\nNothing to modify in lock file\nInstalling dependencies from lock file (including require-dev)\nNothing to install, update or remove\nPackage container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.\nPackage phpunit/php-token-stream is abandoned, you should avoid using it. No replacement was suggested.\nGenerating optimized autoload files\n54 packages you are using are looking for funding.\nUse the `composer fund` command to find out more!\n",
        "stdout_lines": [
            "./composer.json has been updated",
            "Running composer update drush/drush",
            "Loading composer repositories with package information",
            "Updating dependencies",
            "Nothing to modify in lock file",
            "Installing dependencies from lock file (including require-dev)",
            "Nothing to install, update or remove",
            "Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.",
            "Package phpunit/php-token-stream is abandoned, you should avoid using it. No replacement was suggested.",
            "Generating optimized autoload files",
            "54 packages you are using are looking for funding.",
            "Use the `composer fund` command to find out more!"
        ]
    }

Related: geerlingguy/ansible-role-drupal#83

@geerlingguy
Copy link
Contributor Author

Just noting, for reference, the difference in stdout between the same composer require command in:

Version 1.10.16:

./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.
Package phpunit/php-token-stream is abandoned, you should avoid using it. No replacement was suggested.
Writing lock file
Generating autoload files
54 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

(and an aside: under v1 I got a PHP fatal error from the memory limit, so had to add COMPOSER_MEMORY_LIMIT=-1)

Version 2.0.2:

./composer.json has been updated
Running composer update drush/drush
Loading composer repositories with package information
Updating dependencies
Nothing to modify in lock file
Installing dependencies from lock file (including require-dev)
Nothing to install, update or remove
Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.
Package phpunit/php-token-stream is abandoned, you should avoid using it. No replacement was suggested.
Generating autoload files
54 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

@geerlingguy
Copy link
Contributor Author

geerlingguy commented Oct 26, 2020

It looks like the problem is the following has_changed check needs updating to account for the differnce in v2:

def has_changed(string):
    return "Nothing to install or update" not in string

In v2, the string is now:

Nothing to install, update or remove

(It also includes another line Nothing to modify in lock file).

geerlingguy added a commit to geerlingguy/community.general that referenced this issue Oct 26, 2020
geerlingguy added a commit to geerlingguy/community.general that referenced this issue Oct 26, 2020
felixfontein pushed a commit that referenced this issue Oct 26, 2020
* Issue #1179: Add new statement to composer require changed check for v2.

* Issue #1179: Add changelog fragment.
patchback bot pushed a commit that referenced this issue Oct 26, 2020
* Issue #1179: Add new statement to composer require changed check for v2.

* Issue #1179: Add changelog fragment.

(cherry picked from commit 19fdfcf)
felixfontein pushed a commit that referenced this issue Oct 26, 2020
* Issue #1179: Add new statement to composer require changed check for v2.

* Issue #1179: Add changelog fragment.

(cherry picked from commit 19fdfcf)

Co-authored-by: Jeff Geerling <geerlingguy@mac.com>
@geoffreyvanwyk
Copy link

This bug has resurfaced with Ansible 2.11.7 with Composer 2.1.14.

@felixfontein
Copy link
Collaborator

@geoffreyvanwyk there is no Ansible version 2.11.7. The versions jumped from 2.10.x to 3.x.y.

@geoffreyvanwyk
Copy link

@felixfontein This is the output of ansible --version on Ubuntu 20.04 on WSL:

ansible [core 2.11.7]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/scholar/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/scholar/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.8.10 (default, Nov 26 2021, 20:14:08) [GCC 9.3.0]
  jinja version = 2.10.1
  libyaml = True

@geoffreyvanwyk
Copy link

Any way, it looks like it is working properly. Must have been a mistake on my part somewhere.

@felixfontein
Copy link
Collaborator

@geoffreyvanwyk that's the ansible-core version. Or more precisely, the version of the ansible CLI program, which is part of the ansible-core package. The ansible package has a dependency on the ansible-core package, but has no direct way of printing its version; usually pip show ansible is the best way to figure out its version. (If you installed ansible with your system's package manager, that might not work though.) It's definitely confusing :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue/PR relates to a bug needs_triage python3
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants