ansible-collections / community.general

Ansible Community General Collection
https://galaxy.ansible.com/ui/repo/published/community/general/
GNU General Public License v3.0
825 stars 1.53k forks source link

Composer 'create-project' is not idempotent #725

Open geerlingguy opened 4 years ago

geerlingguy commented 4 years ago
SUMMARY

I'm switching over to using the composer module for some of my PHP projects, and one thing I noticed is that there's no simple way of making the composer module idempotent when using create-project:

    - name: Create Drupal project.
      composer:
        command: create-project
        arguments: drupal/recommended-project "{{ drupal_core_path }}"
        working_dir: "{{ drupal_core_path }}"
        no_dev: true
      become_user: www-data

When I run that, the first time, it creates the project without issue, but after that, it tries running the command again, regardless of whether the project already exists, and I get an error:

[InvalidArgumentException]
Project directory "/var/www/drupal" is not empty.

I propose that we maybe check if a composer.json file is already present in the directory when the command is set to create-project, and if so, skip the task? Or maybe add a force option if you want to let users still force it if a project is already there. Could also add a warning in the output if skipped due to existing composer.json.

ISSUE TYPE
COMPONENT NAME

plugins/modules/packaging/language/composer.py

ANSIBLE VERSION
ansible 2.9.11
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/Users/jgeerling/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.7/site-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 3.7.7 (default, Apr  9 2020, 17:13:06) [Clang 11.0.3 (clang-1103.0.32.29)]
CONFIGURATION
N/A
OS / ENVIRONMENT

macOS 10.15.5

STEPS TO REPRODUCE

On an Ubuntu system with Apache and Composer installed:

---
- hosts: all
  tasks:
    - name: Ensure Drupal docroot exists.
      file:
        path: "{{ drupal_core_path }}"
        state: directory
        owner: www-data
        group: www-data

    - name: Create Drupal project.
      composer:
        command: create-project
        arguments: drupal/recommended-project "{{ drupal_core_path }}"
        working_dir: "{{ drupal_core_path }}"
        no_dev: true
      become_user: www-data

Run the tasks a second time, and observe the result.

EXPECTED RESULTS

On second run, the create-project task would be skipped and playbook would not fail.

ACTUAL RESULTS

On second run, the create-project task fails with:

[InvalidArgumentException]
Project directory "/var/www/drupal" is not empty.
ansibullbot commented 4 years ago

Files identified in the description:

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

ansibullbot commented 4 years ago

cc @dmtrs @resmo click here for bot help

geerlingguy commented 4 years ago

Workaround: you can add a stat to check if the composer.json file already exists:

    - name: Check if Drupal project already exists.
      stat:
        path: "{{ drupal_core_path }}/composer.json"
      register: drupal_composer_json

    - name: Create Drupal project.
      composer:
        command: create-project
        arguments: drupal/recommended-project "{{ drupal_core_path }}"
        working_dir: "{{ drupal_core_path }}"
        no_dev: true
      become_user: www-data
      when: not drupal_composer_json.stat.exists
virain commented 3 years ago

If the composer is overtime during the download, some files will still be generated, and the project directory is not empty when running again

aminvakil commented 3 years ago

+label waiting_on_contributor

ansibullbot commented 1 year ago

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help