From 24ea4b975de24496eca6af2971f2de1e8804ca10 Mon Sep 17 00:00:00 2001 From: Sargun Vohra Date: Thu, 12 Jan 2023 21:02:47 -0800 Subject: [PATCH 01/11] Yarn module: fix state=latest not working with global=true --- plugins/modules/yarn.py | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/plugins/modules/yarn.py b/plugins/modules/yarn.py index 2e96cb799d2..a2702c180f4 100644 --- a/plugins/modules/yarn.py +++ b/plugins/modules/yarn.py @@ -188,10 +188,12 @@ def __init__(self, module, **kwargs): elif self.name is not None: self.name_version = self.name - def _exec(self, args, run_in_check_mode=False, check_rc=True): + def _exec(self, args, run_in_check_mode=False, check_rc=True, unsupported_with_global=False): if not self.module.check_mode or (self.module.check_mode and run_in_check_mode): - if self.globally: + with_global_arg = self.globally and not unsupported_with_global + + if with_global_arg: # Yarn global arg is inserted before the command (e.g. `yarn global {some-command}`) args.insert(0, 'global') @@ -206,16 +208,23 @@ def _exec(self, args, run_in_check_mode=False, check_rc=True): cmd.append(self.registry) # If path is specified, cd into that path and run the command. + + path = self.path cwd = None - if self.path and not self.globally: - if not os.path.exists(self.path): + + if self.globally and unsupported_with_global: + _rc, out, _err = self.module.run_command(self.executable + ['global', 'dir'], check_rc=check_rc) + path=out.strip() + + if path and not with_global_arg: + if not os.path.exists(path): # Module will make directory if not exists. - os.makedirs(self.path) - if not os.path.isdir(self.path): - self.module.fail_json(msg="Path provided %s is not a directory" % self.path) - cwd = self.path + os.makedirs(path) + if not os.path.isdir(path): + self.module.fail_json(msg="Path provided %s is not a directory" % path) + cwd = path - if not os.path.isfile(os.path.join(self.path, 'package.json')): + if not os.path.isfile(os.path.join(path, 'package.json')): self.module.fail_json(msg="Package.json does not exist in provided path.") rc, out, err = self.module.run_command(cmd, check_rc=check_rc, cwd=cwd) @@ -276,9 +285,12 @@ def list_outdated(self): if not os.path.isfile(os.path.join(self.path, 'yarn.lock')): return outdated - cmd_result, err = self._exec(['outdated', '--json'], True, False) - if err: - self.module.fail_json(msg=err) + cmd_result, err = self._exec(['outdated', '--json'], True, False, unsupported_with_global=True) + + # the package.json in the global dir is missing a license field, so warnings are expected on stderr + for line in err.splitlines(): + if json.loads(line)['type'] == 'error': + self.module.fail_json(msg=err) if not cmd_result: return outdated From be1b4d189eca30e5ed679a79e77c47763de8426e Mon Sep 17 00:00:00 2001 From: Sargun Vohra Date: Thu, 12 Jan 2023 21:19:28 -0800 Subject: [PATCH 02/11] fix whitespace --- plugins/modules/yarn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/yarn.py b/plugins/modules/yarn.py index a2702c180f4..5dc3f3f5c63 100644 --- a/plugins/modules/yarn.py +++ b/plugins/modules/yarn.py @@ -214,7 +214,7 @@ def _exec(self, args, run_in_check_mode=False, check_rc=True, unsupported_with_g if self.globally and unsupported_with_global: _rc, out, _err = self.module.run_command(self.executable + ['global', 'dir'], check_rc=check_rc) - path=out.strip() + path = out.strip() if path and not with_global_arg: if not os.path.exists(path): From 4fa4a0a72fdbfebd85d26da96673ceef28092c51 Mon Sep 17 00:00:00 2001 From: Sargun Vohra Date: Mon, 16 Jan 2023 12:58:31 -0800 Subject: [PATCH 03/11] add changelog fragment --- changelogs/fragments/5829-fix-yarn-latest.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelogs/fragments/5829-fix-yarn-latest.yml diff --git a/changelogs/fragments/5829-fix-yarn-latest.yml b/changelogs/fragments/5829-fix-yarn-latest.yml new file mode 100644 index 00000000000..ed1c40d4bfd --- /dev/null +++ b/changelogs/fragments/5829-fix-yarn-latest.yml @@ -0,0 +1,2 @@ +bugfixes: + - yarn - fix state=latest not working with global=true https://github.com/ansible-collections/community.general/pull/5829). From 5d162de753fa2864ec3d9ae7a49470462561bef9 Mon Sep 17 00:00:00 2001 From: Sargun Vohra Date: Mon, 16 Jan 2023 13:10:24 -0800 Subject: [PATCH 04/11] add integration test cases --- tests/integration/targets/yarn/tasks/run.yml | 44 ++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/integration/targets/yarn/tasks/run.yml b/tests/integration/targets/yarn/tasks/run.yml index 367d7dcf2c6..a08069c7e33 100644 --- a/tests/integration/targets/yarn/tasks/run.yml +++ b/tests/integration/targets/yarn/tasks/run.yml @@ -135,3 +135,47 @@ assert: that: - yarn_uninstall_package is changed + + - name: 'Global install package with explicit version (older version of package)' + yarn: + global: true + executable: '{{ yarn_bin_path }}/yarn' + name: left-pad + version: 1.1.0 + state: present + environment: + PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}' + register: yarn_global_install_old_package + + - assert: + that: + - yarn_global_install_old_package is changed + + - name: 'Global upgrade old package' + yarn: + global: true + executable: '{{ yarn_bin_path }}/yarn' + name: left-pad + state: latest + environment: + PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}' + register: yarn_global_update_old_package + + - assert: + that: + - yarn_global_update_old_package is changed + + - name: 'Global remove a package' + yarn: + global: true + executable: '{{ yarn_bin_path }}/yarn' + name: left-pad + state: absent + environment: + PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}' + register: yarn_global_uninstall_package + + - name: 'Assert package removed' + assert: + that: + - yarn_global_uninstall_package is changed From 78ae0459acea68810b587095e065ee72e9b92fcc Mon Sep 17 00:00:00 2001 From: Sargun Vohra Date: Mon, 16 Jan 2023 13:40:08 -0800 Subject: [PATCH 05/11] add only tests for this PR (install+upgrade) --- tests/integration/targets/yarn/tasks/run.yml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/tests/integration/targets/yarn/tasks/run.yml b/tests/integration/targets/yarn/tasks/run.yml index a08069c7e33..e7fffbe07b8 100644 --- a/tests/integration/targets/yarn/tasks/run.yml +++ b/tests/integration/targets/yarn/tasks/run.yml @@ -164,18 +164,3 @@ - assert: that: - yarn_global_update_old_package is changed - - - name: 'Global remove a package' - yarn: - global: true - executable: '{{ yarn_bin_path }}/yarn' - name: left-pad - state: absent - environment: - PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}' - register: yarn_global_uninstall_package - - - name: 'Assert package removed' - assert: - that: - - yarn_global_uninstall_package is changed From 2886d4aff97c52efca66377f4362e0367276d2d5 Mon Sep 17 00:00:00 2001 From: Sargun Vohra Date: Mon, 16 Jan 2023 15:20:22 -0800 Subject: [PATCH 06/11] fix assuming default global dir --- changelogs/fragments/5829-fix-yarn-global.yml | 3 ++ changelogs/fragments/5829-fix-yarn-latest.yml | 2 -- plugins/modules/yarn.py | 26 ++++++--------- tests/integration/targets/yarn/tasks/run.yml | 33 ++++++++++++++----- 4 files changed, 37 insertions(+), 27 deletions(-) create mode 100644 changelogs/fragments/5829-fix-yarn-global.yml delete mode 100644 changelogs/fragments/5829-fix-yarn-latest.yml diff --git a/changelogs/fragments/5829-fix-yarn-global.yml b/changelogs/fragments/5829-fix-yarn-global.yml new file mode 100644 index 00000000000..39340933743 --- /dev/null +++ b/changelogs/fragments/5829-fix-yarn-global.yml @@ -0,0 +1,3 @@ +bugfixes: + - yarn - fix state=latest not working with global=true (https://github.com/ansible-collections/community.general/pull/5829). + - yarn - fix global=true to check for the configured global folder instead of assuming the default (https://github.com/ansible-collections/community.general/pull/5829) diff --git a/changelogs/fragments/5829-fix-yarn-latest.yml b/changelogs/fragments/5829-fix-yarn-latest.yml deleted file mode 100644 index ed1c40d4bfd..00000000000 --- a/changelogs/fragments/5829-fix-yarn-latest.yml +++ /dev/null @@ -1,2 +0,0 @@ -bugfixes: - - yarn - fix state=latest not working with global=true https://github.com/ansible-collections/community.general/pull/5829). diff --git a/plugins/modules/yarn.py b/plugins/modules/yarn.py index 5dc3f3f5c63..e8347a9a8d4 100644 --- a/plugins/modules/yarn.py +++ b/plugins/modules/yarn.py @@ -163,8 +163,6 @@ class Yarn(object): - DEFAULT_GLOBAL_INSTALLATION_PATH = os.path.expanduser('~/.config/yarn/global') - def __init__(self, module, **kwargs): self.module = module self.globally = kwargs['globally'] @@ -209,22 +207,17 @@ def _exec(self, args, run_in_check_mode=False, check_rc=True, unsupported_with_g # If path is specified, cd into that path and run the command. - path = self.path cwd = None - if self.globally and unsupported_with_global: - _rc, out, _err = self.module.run_command(self.executable + ['global', 'dir'], check_rc=check_rc) - path = out.strip() - - if path and not with_global_arg: - if not os.path.exists(path): + if self.path and not with_global_arg: + if not os.path.exists(self.path): # Module will make directory if not exists. - os.makedirs(path) - if not os.path.isdir(path): - self.module.fail_json(msg="Path provided %s is not a directory" % path) - cwd = path + os.makedirs(self.path) + if not os.path.isdir(self.path): + self.module.fail_json(msg="Path provided %s is not a directory" % self.path) + cwd = self.path - if not os.path.isfile(os.path.join(path, 'package.json')): + if not os.path.isfile(os.path.join(self.path, 'package.json')): self.module.fail_json(msg="Package.json does not exist in provided path.") rc, out, err = self.module.run_command(cmd, check_rc=check_rc, cwd=cwd) @@ -242,7 +235,7 @@ def list(self): missing.append(self.name) return installed, missing - result, error = self._exec(cmd, True, False) + result, error = self._exec(cmd, run_in_check_mode=True, check_rc=False) if error: self.module.fail_json(msg=error) @@ -352,7 +345,8 @@ def main(): # When installing globally, use the defined path for global node_modules if globally: - path = Yarn.DEFAULT_GLOBAL_INSTALLATION_PATH + _rc, out, _err = module.run_command([executable, 'global', 'dir'], check_rc=True) + path = out.strip() yarn = Yarn(module, name=name, diff --git a/tests/integration/targets/yarn/tasks/run.yml b/tests/integration/targets/yarn/tasks/run.yml index e7fffbe07b8..b4636a77962 100644 --- a/tests/integration/targets/yarn/tasks/run.yml +++ b/tests/integration/targets/yarn/tasks/run.yml @@ -39,6 +39,7 @@ package: 'iconv-lite' environment: PATH: "{{ node_bin_path }}:{{ansible_env.PATH}}" + YARN_IGNORE_ENGINES: true block: # Get the version of Yarn and register to a variable @@ -136,31 +137,45 @@ that: - yarn_uninstall_package is changed - - name: 'Global install package with explicit version (older version of package)' + - name: 'Global install binary with explicit version (older version of package)' yarn: global: true executable: '{{ yarn_bin_path }}/yarn' - name: left-pad - version: 1.1.0 + name: prettier + version: 2.0.0 state: present environment: PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}' - register: yarn_global_install_old_package + register: yarn_global_install_old_binary - assert: that: - - yarn_global_install_old_package is changed + - yarn_global_install_old_binary is changed - - name: 'Global upgrade old package' + - name: 'Global upgrade old binary' yarn: global: true executable: '{{ yarn_bin_path }}/yarn' - name: left-pad + name: prettier state: latest environment: PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}' - register: yarn_global_update_old_package + register: yarn_global_update_old_binary + + - assert: + that: + - yarn_global_update_old_binary is changed + + - name: 'Global remove a binary' + yarn: + global: true + executable: '{{ yarn_bin_path }}/yarn' + name: prettier + state: absent + environment: + PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}' + register: yarn_global_uninstall_binary - assert: that: - - yarn_global_update_old_package is changed + - yarn_global_uninstall_binary is changed From b2fd87fb88f6a2e1298c6f9279ee12f7b3a0d0b7 Mon Sep 17 00:00:00 2001 From: Sargun Vohra Date: Mon, 16 Jan 2023 15:26:26 -0800 Subject: [PATCH 07/11] fix list() not working when global=true and name a package with no binary --- changelogs/fragments/5829-fix-yarn-global.yml | 1 + plugins/modules/yarn.py | 21 ++++----- tests/integration/targets/yarn/tasks/run.yml | 43 +++++++++++++++++++ 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/changelogs/fragments/5829-fix-yarn-global.yml b/changelogs/fragments/5829-fix-yarn-global.yml index 39340933743..e67f45629d3 100644 --- a/changelogs/fragments/5829-fix-yarn-global.yml +++ b/changelogs/fragments/5829-fix-yarn-global.yml @@ -1,3 +1,4 @@ bugfixes: - yarn - fix state=latest not working with global=true (https://github.com/ansible-collections/community.general/pull/5829). - yarn - fix global=true to check for the configured global folder instead of assuming the default (https://github.com/ansible-collections/community.general/pull/5829) + - yarn - fix state=absent not working with global=true when the package does not include a binary (https://github.com/ansible-collections/community.general/pull/5829) diff --git a/plugins/modules/yarn.py b/plugins/modules/yarn.py index e8347a9a8d4..99fd2b3f789 100644 --- a/plugins/modules/yarn.py +++ b/plugins/modules/yarn.py @@ -235,24 +235,21 @@ def list(self): missing.append(self.name) return installed, missing - result, error = self._exec(cmd, run_in_check_mode=True, check_rc=False) + # `yarn global list` should be treated as "unsupported with global" even though it exists, + # because it only only lists binaries, but `yarn global add` can install libraries too. + result, error = self._exec(cmd, run_in_check_mode=True, check_rc=False, unsupported_with_global=True) if error: self.module.fail_json(msg=error) for json_line in result.strip().split('\n'): data = json.loads(json_line) - if self.globally: - if data['type'] == 'list' and data['data']['type'].startswith('bins-'): - # This is a string in format: 'bins-' - installed.append(data['data']['type'][5:]) - else: - if data['type'] == 'tree': - dependencies = data['data']['trees'] - - for dep in dependencies: - name, version = dep['name'].rsplit('@', 1) - installed.append(name) + if data['type'] == 'tree': + dependencies = data['data']['trees'] + + for dep in dependencies: + name, version = dep['name'].rsplit('@', 1) + installed.append(name) if self.name not in installed: missing.append(self.name) diff --git a/tests/integration/targets/yarn/tasks/run.yml b/tests/integration/targets/yarn/tasks/run.yml index b4636a77962..6521d45fcf0 100644 --- a/tests/integration/targets/yarn/tasks/run.yml +++ b/tests/integration/targets/yarn/tasks/run.yml @@ -179,3 +179,46 @@ - assert: that: - yarn_global_uninstall_binary is changed + + - name: 'Global install package with no binary with explicit version (older version of package)' + yarn: + global: true + executable: '{{ yarn_bin_path }}/yarn' + name: left-pad + version: 1.1.0 + state: present + environment: + PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}' + register: yarn_global_install_old_package + + - assert: + that: + - yarn_global_install_old_package is changed + + - name: 'Global upgrade old package with no binary' + yarn: + global: true + executable: '{{ yarn_bin_path }}/yarn' + name: left-pad + state: latest + environment: + PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}' + register: yarn_global_update_old_package + + - assert: + that: + - yarn_global_update_old_package is changed + + - name: 'Global remove a package with no binary' + yarn: + global: true + executable: '{{ yarn_bin_path }}/yarn' + name: left-pad + state: absent + environment: + PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}' + register: yarn_global_uninstall_package + + - assert: + that: + - yarn_global_uninstall_package is changed From 120dd0ac5e6adf470a940c1507f25e7a6e2df222 Mon Sep 17 00:00:00 2001 From: Sargun Vohra Date: Mon, 16 Jan 2023 15:32:27 -0800 Subject: [PATCH 08/11] remove ignores --- tests/sanity/ignore-2.11.txt | 1 - tests/sanity/ignore-2.12.txt | 1 - tests/sanity/ignore-2.13.txt | 1 - tests/sanity/ignore-2.14.txt | 1 - tests/sanity/ignore-2.15.txt | 1 - 5 files changed, 5 deletions(-) diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index 39b09d887a8..f5c8ea8aa94 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -24,6 +24,5 @@ plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/xfconf.py validate-modules:return-syntax-error -plugins/modules/yarn.py use-argspec-type-path tests/integration/targets/django_manage/files/base_test/simple_project/p1/manage.py compile-2.6 # django generated code tests/integration/targets/django_manage/files/base_test/simple_project/p1/manage.py compile-2.7 # django generated code diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index 47244bb5150..1961c120c92 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -19,4 +19,3 @@ plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/xfconf.py validate-modules:return-syntax-error -plugins/modules/yarn.py use-argspec-type-path diff --git a/tests/sanity/ignore-2.13.txt b/tests/sanity/ignore-2.13.txt index 47244bb5150..1961c120c92 100644 --- a/tests/sanity/ignore-2.13.txt +++ b/tests/sanity/ignore-2.13.txt @@ -19,4 +19,3 @@ plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/xfconf.py validate-modules:return-syntax-error -plugins/modules/yarn.py use-argspec-type-path diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index a2e9e373250..da647a0ebca 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -21,4 +21,3 @@ plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt' plugins/modules/xfconf.py validate-modules:return-syntax-error -plugins/modules/yarn.py use-argspec-type-path diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index a2e9e373250..da647a0ebca 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -21,4 +21,3 @@ plugins/modules/rax.py use-argspec-type-path # fix needed plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt' plugins/modules/xfconf.py validate-modules:return-syntax-error -plugins/modules/yarn.py use-argspec-type-path From c21f1a40b1b82b4d67ea09f18c752a0c178eb130 Mon Sep 17 00:00:00 2001 From: Sargun Vohra Date: Mon, 16 Jan 2023 15:36:32 -0800 Subject: [PATCH 09/11] whitespace --- plugins/modules/yarn.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/modules/yarn.py b/plugins/modules/yarn.py index 99fd2b3f789..df55925dba9 100644 --- a/plugins/modules/yarn.py +++ b/plugins/modules/yarn.py @@ -206,9 +206,7 @@ def _exec(self, args, run_in_check_mode=False, check_rc=True, unsupported_with_g cmd.append(self.registry) # If path is specified, cd into that path and run the command. - cwd = None - if self.path and not with_global_arg: if not os.path.exists(self.path): # Module will make directory if not exists. From 76755fcd8c23784b27e3713ca27e6100c79b0da3 Mon Sep 17 00:00:00 2001 From: Sargun Vohra Date: Tue, 17 Jan 2023 11:22:44 -0800 Subject: [PATCH 10/11] Update changelogs/fragments/5829-fix-yarn-global.yml Co-authored-by: Felix Fontein --- changelogs/fragments/5829-fix-yarn-global.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/changelogs/fragments/5829-fix-yarn-global.yml b/changelogs/fragments/5829-fix-yarn-global.yml index e67f45629d3..e03231df60f 100644 --- a/changelogs/fragments/5829-fix-yarn-global.yml +++ b/changelogs/fragments/5829-fix-yarn-global.yml @@ -1,4 +1,4 @@ bugfixes: - - yarn - fix state=latest not working with global=true (https://github.com/ansible-collections/community.general/pull/5829). - - yarn - fix global=true to check for the configured global folder instead of assuming the default (https://github.com/ansible-collections/community.general/pull/5829) - - yarn - fix state=absent not working with global=true when the package does not include a binary (https://github.com/ansible-collections/community.general/pull/5829) + - yarn - fix ``state=latest`` not working with ``global=true`` (https://github.com/ansible-collections/community.general/pull/5829). + - yarn - fix ``global=true`` to check for the configured global folder instead of assuming the default (https://github.com/ansible-collections/community.general/pull/5829) + - yarn - fix ``state=absent`` not working with ``global=true`` when the package does not include a binary (https://github.com/ansible-collections/community.general/pull/5829) From 74f8dfac091861e9db674f1222003757d7a84c6c Mon Sep 17 00:00:00 2001 From: Sargun Vohra Date: Sat, 11 Feb 2023 22:46:17 -0800 Subject: [PATCH 11/11] Update changelogs/fragments/5829-fix-yarn-global.yml Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- changelogs/fragments/5829-fix-yarn-global.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/fragments/5829-fix-yarn-global.yml b/changelogs/fragments/5829-fix-yarn-global.yml index e03231df60f..fade7d97f6e 100644 --- a/changelogs/fragments/5829-fix-yarn-global.yml +++ b/changelogs/fragments/5829-fix-yarn-global.yml @@ -1,4 +1,4 @@ bugfixes: - - yarn - fix ``state=latest`` not working with ``global=true`` (https://github.com/ansible-collections/community.general/pull/5829). + - yarn - fix ``state=latest`` not working with ``global=true`` (https://github.com/ansible-collections/community.general/issues/5712). - yarn - fix ``global=true`` to check for the configured global folder instead of assuming the default (https://github.com/ansible-collections/community.general/pull/5829) - yarn - fix ``state=absent`` not working with ``global=true`` when the package does not include a binary (https://github.com/ansible-collections/community.general/pull/5829)