Add state option to git_config module (#50578)
* Add state option to git_config module State present/absent option works like --set/--unset option for 'git config'. * Change git_config to avoid useless parameter passed to git command When unsetting value, command was : git config --unset foo ''. Now command is : git config --unset foo. * Add some integration tests to git_config module * Add missing aliases file * Change set up method Using git command seems to cause troubles on some OS : changing config by changing '.gitconfig' file. * Remove some distros from tests pool Git is not installed or is out of date on these distros. * Fix aliases to skip tests on centos6 * Refactor tests of the git_config module * Add use case when state=absent and value is defined
This commit is contained in:
parent
984777b3d0
commit
2f85d62989
15 changed files with 257 additions and 5 deletions
|
@ -51,6 +51,14 @@ options:
|
||||||
also specify the repo parameter. It defaults to system only when
|
also specify the repo parameter. It defaults to system only when
|
||||||
not using I(list_all)=yes.
|
not using I(list_all)=yes.
|
||||||
choices: [ "local", "global", "system" ]
|
choices: [ "local", "global", "system" ]
|
||||||
|
state:
|
||||||
|
description:
|
||||||
|
- "Indicates the setting should be set/unset.
|
||||||
|
This parameter has higher precedence than I(value) parameter:
|
||||||
|
when I(state)=absent and I(value) is defined, I(value) is discarded."
|
||||||
|
choices: [ 'present', 'absent' ]
|
||||||
|
default: 'present'
|
||||||
|
version_added: '2.8'
|
||||||
value:
|
value:
|
||||||
description:
|
description:
|
||||||
- When specifying the name of a single setting, supply a value to
|
- When specifying the name of a single setting, supply a value to
|
||||||
|
@ -69,6 +77,12 @@ EXAMPLES = '''
|
||||||
scope: global
|
scope: global
|
||||||
value: status
|
value: status
|
||||||
|
|
||||||
|
# Unset some settings in ~/.gitconfig
|
||||||
|
- git_config:
|
||||||
|
name: alias.ci
|
||||||
|
scope: global
|
||||||
|
state: absent
|
||||||
|
|
||||||
# Or system-wide:
|
# Or system-wide:
|
||||||
- git_config:
|
- git_config:
|
||||||
name: alias.remotev
|
name: alias.remotev
|
||||||
|
@ -149,9 +163,10 @@ def main():
|
||||||
name=dict(type='str'),
|
name=dict(type='str'),
|
||||||
repo=dict(type='path'),
|
repo=dict(type='path'),
|
||||||
scope=dict(required=False, type='str', choices=['local', 'global', 'system']),
|
scope=dict(required=False, type='str', choices=['local', 'global', 'system']),
|
||||||
|
state=dict(required=False, type='str', default='present', choices=['present', 'absent']),
|
||||||
value=dict(required=False)
|
value=dict(required=False)
|
||||||
),
|
),
|
||||||
mutually_exclusive=[['list_all', 'name'], ['list_all', 'value']],
|
mutually_exclusive=[['list_all', 'name'], ['list_all', 'value'], ['list_all', 'state']],
|
||||||
required_if=[('scope', 'local', ['repo'])],
|
required_if=[('scope', 'local', ['repo'])],
|
||||||
required_one_of=[['list_all', 'name']],
|
required_one_of=[['list_all', 'name']],
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
|
@ -175,6 +190,12 @@ def main():
|
||||||
else:
|
else:
|
||||||
scope = 'system'
|
scope = 'system'
|
||||||
|
|
||||||
|
if params['state'] == 'absent':
|
||||||
|
unset = 'unset'
|
||||||
|
params['value'] = None
|
||||||
|
else:
|
||||||
|
unset = None
|
||||||
|
|
||||||
if params['value']:
|
if params['value']:
|
||||||
new_value = params['value']
|
new_value = params['value']
|
||||||
else:
|
else:
|
||||||
|
@ -212,16 +233,22 @@ def main():
|
||||||
k, v = value.split('=', 1)
|
k, v = value.split('=', 1)
|
||||||
config_values[k] = v
|
config_values[k] = v
|
||||||
module.exit_json(changed=False, msg='', config_values=config_values)
|
module.exit_json(changed=False, msg='', config_values=config_values)
|
||||||
elif not new_value:
|
elif not new_value and not unset:
|
||||||
module.exit_json(changed=False, msg='', config_value=out.rstrip())
|
module.exit_json(changed=False, msg='', config_value=out.rstrip())
|
||||||
|
elif unset and not out:
|
||||||
|
module.exit_json(changed=False, msg='no setting to unset')
|
||||||
else:
|
else:
|
||||||
old_value = out.rstrip()
|
old_value = out.rstrip()
|
||||||
if old_value == new_value:
|
if old_value == new_value:
|
||||||
module.exit_json(changed=False, msg="")
|
module.exit_json(changed=False, msg="")
|
||||||
|
|
||||||
if not module.check_mode:
|
if not module.check_mode:
|
||||||
new_value_quoted = shlex_quote(new_value)
|
if unset:
|
||||||
cmd = ' '.join(args + [new_value_quoted])
|
args.insert(len(args) - 1, "--" + unset)
|
||||||
|
cmd = ' '.join(args)
|
||||||
|
else:
|
||||||
|
new_value_quoted = shlex_quote(new_value)
|
||||||
|
cmd = ' '.join(args + [new_value_quoted])
|
||||||
(rc, out, err) = module.run_command(cmd, cwd=dir)
|
(rc, out, err) = module.run_command(cmd, cwd=dir)
|
||||||
if err:
|
if err:
|
||||||
module.fail_json(rc=rc, msg=err, cmd=cmd)
|
module.fail_json(rc=rc, msg=err, cmd=cmd)
|
||||||
|
@ -232,7 +259,7 @@ def main():
|
||||||
before_header=' '.join(args),
|
before_header=' '.join(args),
|
||||||
before=old_value + "\n",
|
before=old_value + "\n",
|
||||||
after_header=' '.join(args),
|
after_header=' '.join(args),
|
||||||
after=new_value + "\n"
|
after=(new_value or '') + "\n"
|
||||||
),
|
),
|
||||||
changed=True
|
changed=True
|
||||||
)
|
)
|
||||||
|
|
2
test/integration/targets/git_config/aliases
Normal file
2
test/integration/targets/git_config/aliases
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
shippable/posix/group3
|
||||||
|
|
2
test/integration/targets/git_config/files/gitconfig
Normal file
2
test/integration/targets/git_config/files/gitconfig
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[http]
|
||||||
|
proxy = foo
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
- import_tasks: setup_no_value.yml
|
||||||
|
|
||||||
|
- name: testing exclusion between state and list_all parameters
|
||||||
|
git_config:
|
||||||
|
list_all: true
|
||||||
|
state: absent
|
||||||
|
register: result
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- name: assert git_config failed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is failed
|
||||||
|
- "result.msg == 'parameters are mutually exclusive: list_all, state'"
|
||||||
|
...
|
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
- import_tasks: setup_no_value.yml
|
||||||
|
|
||||||
|
- name: setting value without state
|
||||||
|
git_config:
|
||||||
|
name: "{{ option_name }}"
|
||||||
|
value: "{{ option_value }}"
|
||||||
|
scope: "{{ option_scope }}"
|
||||||
|
register: set_result
|
||||||
|
|
||||||
|
- name: getting value without state
|
||||||
|
git_config:
|
||||||
|
name: "{{ option_name }}"
|
||||||
|
scope: "{{ option_scope }}"
|
||||||
|
register: get_result
|
||||||
|
|
||||||
|
- name: assert set changed and value is correct
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- set_result.changed == true
|
||||||
|
- set_result.diff.before == "\n"
|
||||||
|
- set_result.diff.after == option_value + "\n"
|
||||||
|
- get_result.changed == false
|
||||||
|
- get_result.config_value == option_value
|
||||||
|
...
|
|
@ -0,0 +1,27 @@
|
||||||
|
---
|
||||||
|
- import_tasks: setup_no_value.yml
|
||||||
|
|
||||||
|
- name: setting value with state=present
|
||||||
|
git_config:
|
||||||
|
name: "{{ option_name }}"
|
||||||
|
value: "{{ option_value }}"
|
||||||
|
scope: "{{ option_scope }}"
|
||||||
|
state: present
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: getting value with state=present
|
||||||
|
git_config:
|
||||||
|
name: "{{ option_name }}"
|
||||||
|
scope: "{{ option_scope }}"
|
||||||
|
state: present
|
||||||
|
register: get_result
|
||||||
|
|
||||||
|
- name: assert set changed and value is correct with state=present
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- set_result.changed == true
|
||||||
|
- set_result.diff.before == "\n"
|
||||||
|
- set_result.diff.after == option_value + "\n"
|
||||||
|
- get_result.changed == false
|
||||||
|
- get_result.config_value == option_value
|
||||||
|
...
|
23
test/integration/targets/git_config/tasks/main.yml
Normal file
23
test/integration/targets/git_config/tasks/main.yml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
---
|
||||||
|
# test code for the git_config module
|
||||||
|
|
||||||
|
- name: setup
|
||||||
|
import_tasks: setup.yml
|
||||||
|
|
||||||
|
- block:
|
||||||
|
# testing parameters exclusion: state and list_all
|
||||||
|
- import_tasks: exclusion_state_list-all.yml
|
||||||
|
# testing get/set option without state
|
||||||
|
- import_tasks: get_set_no_state.yml
|
||||||
|
# testing get/set option with state=present
|
||||||
|
- import_tasks: get_set_state_present.yml
|
||||||
|
# testing state=absent without value to delete
|
||||||
|
- import_tasks: unset_no_value.yml
|
||||||
|
# testing state=absent with value to delete
|
||||||
|
- import_tasks: unset_value.yml
|
||||||
|
# testing state=absent with value to delete and a defined value parameter
|
||||||
|
- import_tasks: precedence_between_unset_and_value.yml
|
||||||
|
# testing state=absent with check mode
|
||||||
|
- import_tasks: unset_check_mode.yml
|
||||||
|
when: git_installed is succeeded and git_version.stdout is version(git_version_supporting_includes, ">=")
|
||||||
|
...
|
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
- import_tasks: setup_value.yml
|
||||||
|
|
||||||
|
- name: unsetting value
|
||||||
|
git_config:
|
||||||
|
name: "{{ option_name }}"
|
||||||
|
scope: "{{ option_scope }}"
|
||||||
|
state: absent
|
||||||
|
value: bar
|
||||||
|
register: unset_result
|
||||||
|
|
||||||
|
- name: getting value
|
||||||
|
git_config:
|
||||||
|
name: "{{ option_name }}"
|
||||||
|
scope: "{{ option_scope }}"
|
||||||
|
register: get_result
|
||||||
|
|
||||||
|
- name: assert unset changed and deleted value
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- unset_result.changed == true
|
||||||
|
- unset_result.diff.before == option_value + "\n"
|
||||||
|
- unset_result.diff.after == "\n"
|
||||||
|
- get_result.config_value == ''
|
||||||
|
...
|
11
test/integration/targets/git_config/tasks/setup.yml
Normal file
11
test/integration/targets/git_config/tasks/setup.yml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
- name: verify that git is installed so this test can continue
|
||||||
|
command: which git
|
||||||
|
register: git_installed
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- name: get git version, only newer than {{git_version_supporting_includes}} has includes option
|
||||||
|
shell: "git --version | grep 'git version' | sed 's/git version //'"
|
||||||
|
register: git_version
|
||||||
|
ignore_errors: yes
|
||||||
|
...
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
# ------
|
||||||
|
# set up : deleting gitconfig file
|
||||||
|
- name: set up without value
|
||||||
|
file:
|
||||||
|
path: ~/.gitconfig
|
||||||
|
state: absent
|
||||||
|
...
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
# ------
|
||||||
|
# set up : set gitconfig with value
|
||||||
|
- name: set up with value
|
||||||
|
copy:
|
||||||
|
src: gitconfig
|
||||||
|
dest: ~/.gitconfig
|
||||||
|
...
|
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
- import_tasks: setup_value.yml
|
||||||
|
|
||||||
|
- name: unsetting value with check mode
|
||||||
|
git_config:
|
||||||
|
name: "{{ option_name }}"
|
||||||
|
scope: "{{ option_scope }}"
|
||||||
|
state: absent
|
||||||
|
check_mode: yes
|
||||||
|
register: unset_result
|
||||||
|
|
||||||
|
- name: getting value
|
||||||
|
git_config:
|
||||||
|
name: "{{ option_name }}"
|
||||||
|
scope: "{{ option_scope }}"
|
||||||
|
register: get_result
|
||||||
|
|
||||||
|
- name: assert unset changed but dit not delete value
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- unset_result.changed == true
|
||||||
|
- unset_result.diff.before == option_value + "\n"
|
||||||
|
- unset_result.diff.after == "\n"
|
||||||
|
- get_result.config_value == option_value
|
||||||
|
...
|
23
test/integration/targets/git_config/tasks/unset_no_value.yml
Normal file
23
test/integration/targets/git_config/tasks/unset_no_value.yml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
---
|
||||||
|
- import_tasks: setup_no_value.yml
|
||||||
|
|
||||||
|
- name: unsetting value
|
||||||
|
git_config:
|
||||||
|
name: "{{ option_name }}"
|
||||||
|
scope: "{{ option_scope }}"
|
||||||
|
state: absent
|
||||||
|
register: unset_result
|
||||||
|
|
||||||
|
- name: getting value
|
||||||
|
git_config:
|
||||||
|
name: "{{ option_name }}"
|
||||||
|
scope: "{{ option_scope }}"
|
||||||
|
register: get_result
|
||||||
|
|
||||||
|
- name: assert unsetting didn't change
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- unset_result.changed == false
|
||||||
|
- unset_result.msg == 'no setting to unset'
|
||||||
|
- get_result.config_value == ''
|
||||||
|
...
|
24
test/integration/targets/git_config/tasks/unset_value.yml
Normal file
24
test/integration/targets/git_config/tasks/unset_value.yml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
---
|
||||||
|
- import_tasks: setup_value.yml
|
||||||
|
|
||||||
|
- name: unsetting value
|
||||||
|
git_config:
|
||||||
|
name: "{{ option_name }}"
|
||||||
|
scope: "{{ option_scope }}"
|
||||||
|
state: absent
|
||||||
|
register: unset_result
|
||||||
|
|
||||||
|
- name: getting value
|
||||||
|
git_config:
|
||||||
|
name: "{{ option_name }}"
|
||||||
|
scope: "{{ option_scope }}"
|
||||||
|
register: get_result
|
||||||
|
|
||||||
|
- name: assert unset changed and deleted value
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- unset_result.changed == true
|
||||||
|
- unset_result.diff.before == option_value + "\n"
|
||||||
|
- unset_result.diff.after == "\n"
|
||||||
|
- get_result.config_value == ''
|
||||||
|
...
|
6
test/integration/targets/git_config/vars/main.yml
Normal file
6
test/integration/targets/git_config/vars/main.yml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
git_version_supporting_includes: 1.7.10
|
||||||
|
option_name: http.proxy
|
||||||
|
option_value: 'foo'
|
||||||
|
option_scope: global
|
||||||
|
...
|
Loading…
Reference in a new issue