1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2026-06-11 10:35:34 +00:00

[PR #12084/8468fea3 backport][stable-12] composer: config file hash to evaluate whether a change occurred (#12131)

composer: config file hash to evaluate whether a change occurred (#12084)

* composer: Use config file hash to evaluate whether a change occurred (instead of unreliable output). Ensure `--working-dir` option consistently comes first (sudo-friendly)

* Update plugins/modules/composer.py



* whitespace fixes + changelog fragment

* Update changelogs/fragments/composer-working-dir-and-config-sha256.yaml



* Update changelogs/fragments/composer-working-dir-and-config-sha256.yaml



* Update plugins/modules/composer.py



* fragment

* ruff format  plugins/modules/composer.py

---------



(cherry picked from commit 8468fea3b0)

Co-authored-by: Raphaël Droz <raphael@droz.eu>
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
patchback[bot] 2026-05-30 14:34:42 +02:00 committed by GitHub
parent fee35e6ec2
commit 410383e95f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 143 additions and 8 deletions

View file

@ -186,9 +186,10 @@ def composer_command(module, command, arguments=None, options=None):
if global_command:
global_arg = ["global"]
working_dir_option = []
else:
global_arg = []
options.extend(["--working-dir", module.params["working_dir"]])
working_dir_option = ["--working-dir", module.params["working_dir"]]
if module.params["executable"] is None:
php_path = module.get_bin_path("php", True, ["/usr/local/bin"])
@ -200,10 +201,50 @@ def composer_command(module, command, arguments=None, options=None):
else:
composer_path = module.params["composer_executable"]
cmd = [php_path, composer_path] + global_arg + command + options + arguments
cmd = [php_path, composer_path] + working_dir_option + global_arg + command + options + arguments
return module.run_command(cmd)
def get_composer_home(module):
"""Get the composer home directory by running 'composer config --global home'."""
if module.params["executable"] is None:
php_path = module.get_bin_path("php", True, ["/usr/local/bin"])
else:
php_path = module.params["executable"]
if module.params["composer_executable"] is None:
composer_path = module.get_bin_path("composer", True, ["/usr/local/bin"])
else:
composer_path = module.params["composer_executable"]
cmd = [php_path, composer_path, "config", "--global", "--no-interaction", "home"]
rc, out, err = module.run_command(cmd)
if rc == 0:
return out.strip()
return None
def get_config_files(module):
"""Get list of config files that might be changed by 'composer config'."""
files = ["composer.json", "auth.json"]
global_command = module.params["global_command"]
working_dir = module.params["working_dir"]
if global_command:
composer_home = get_composer_home(module)
if composer_home:
files = [os.path.join(composer_home, f) for f in files]
elif working_dir:
files = [os.path.join(working_dir, f) for f in files]
return files
def hash_config_files(module, files):
"""Return a dict mapping file path to its sha256 hash (or None if the file does not exist)."""
return {f: (module.sha256(f) if os.path.isfile(f) else None) for f in files}
def main():
module = AnsibleModule(
argument_spec=dict(
@ -280,6 +321,12 @@ def main():
else:
module.exit_json(skipped=True, msg=f"command '{command}' does not support check mode, skipping")
# For 'config' command in non-check mode, use sha256 hashing to detect changes
use_hash_detection = command == "config" and not module.check_mode
if use_hash_detection:
config_files = get_config_files(module)
hashes_before = hash_config_files(module, config_files)
rc, out, err = composer_command(module, [command], arguments, options)
if rc != 0:
@ -288,7 +335,12 @@ def main():
else:
# Composer version > 1.0.0-alpha9 now use stderr for standard notification messages
output = parse_out(out + err)
module.exit_json(changed=has_changed(output), msg=output, stdout=out + err)
if use_hash_detection:
hashes_after = hash_config_files(module, config_files)
changed = hashes_before != hashes_after
else:
changed = has_changed(output)
module.exit_json(changed=changed, msg=output, stdout=out + err)
if __name__ == "__main__":