moose-inventory 2.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/release.yml +2 -0
  3. data/.gitignore +6 -1
  4. data/.rubocop.yml +21 -0
  5. data/BACKLOG.md +638 -9
  6. data/Gemfile +2 -0
  7. data/Gemfile.lock +1 -1
  8. data/README.md +315 -39
  9. data/Rakefile +2 -0
  10. data/bin/moose-inventory +2 -1
  11. data/docs/architecture/architecture-and-trust-boundaries.md +444 -0
  12. data/docs/compatibility/cli-output-compatibility.md +76 -0
  13. data/docs/governance/approval-register.md +37 -0
  14. data/docs/maintenance/database-backup-restore-guidance.md +162 -0
  15. data/docs/maintenance/package-maintenance-and-agent-boundaries.md +260 -0
  16. data/docs/process/conformance-gap-analysis-2026-05-28.md +192 -0
  17. data/docs/product/product-brief.md +161 -0
  18. data/docs/product/requirements-baseline.md +477 -0
  19. data/docs/qa/qa-documentation-and-release-gates.md +283 -0
  20. data/docs/release/package-provenance-hardening.md +126 -0
  21. data/docs/release/publishing.md +11 -3
  22. data/docs/release/release-environment-protection.md +78 -0
  23. data/docs/release/release-readiness.md +23 -4
  24. data/docs/security/accepted-risk-register.md +84 -0
  25. data/docs/security/security-privacy-process.md +287 -0
  26. data/docs/security-audit-2026-05-26-rerun.md +2 -2
  27. data/docs/security-audit-2026-05-29-snapshot-import-fuzz.md +58 -0
  28. data/docs/ux/cli-workflow-notes.md +287 -0
  29. data/examples/ansible/ansible.cfg +3 -0
  30. data/examples/ansible/inventory/moose_inventory.yml +5 -0
  31. data/examples/ansible/inventory_plugins/moose_inventory.py +100 -0
  32. data/examples/ci/README.md +16 -0
  33. data/examples/ci/github-actions/inventory-review.yml +38 -0
  34. data/examples/ci/inventory/example-snapshot.yml +19 -0
  35. data/examples/ci/scripts/validate-inventory-snapshot.sh +30 -0
  36. data/lib/moose_inventory/cli/application.rb +135 -5
  37. data/lib/moose_inventory/cli/association_rendering.rb +74 -0
  38. data/lib/moose_inventory/cli/association_rendering_support.rb +89 -0
  39. data/lib/moose_inventory/cli/audit.rb +62 -0
  40. data/lib/moose_inventory/cli/audit_recording.rb +40 -0
  41. data/lib/moose_inventory/cli/child_relation_rendering.rb +110 -0
  42. data/lib/moose_inventory/cli/console.rb +135 -0
  43. data/lib/moose_inventory/cli/db.rb +64 -0
  44. data/lib/moose_inventory/cli/factory.rb +28 -0
  45. data/lib/moose_inventory/cli/formatter.rb +8 -12
  46. data/lib/moose_inventory/cli/group.rb +5 -2
  47. data/lib/moose_inventory/cli/group_add.rb +11 -9
  48. data/lib/moose_inventory/cli/group_addchild.rb +23 -65
  49. data/lib/moose_inventory/cli/group_addhost.rb +16 -67
  50. data/lib/moose_inventory/cli/group_addvar.rb +27 -47
  51. data/lib/moose_inventory/cli/group_get.rb +8 -42
  52. data/lib/moose_inventory/cli/group_list.rb +7 -40
  53. data/lib/moose_inventory/cli/group_listvars.rb +9 -55
  54. data/lib/moose_inventory/cli/group_rm.rb +12 -10
  55. data/lib/moose_inventory/cli/group_rmchild.rb +26 -82
  56. data/lib/moose_inventory/cli/group_rmhost.rb +18 -53
  57. data/lib/moose_inventory/cli/group_rmvar.rb +30 -41
  58. data/lib/moose_inventory/cli/group_tags.rb +33 -0
  59. data/lib/moose_inventory/cli/helpers.rb +68 -1
  60. data/lib/moose_inventory/cli/host.rb +6 -3
  61. data/lib/moose_inventory/cli/host_add.rb +69 -29
  62. data/lib/moose_inventory/cli/host_addgroup.rb +22 -58
  63. data/lib/moose_inventory/cli/host_addvar.rb +28 -52
  64. data/lib/moose_inventory/cli/host_get.rb +9 -37
  65. data/lib/moose_inventory/cli/host_list.rb +24 -21
  66. data/lib/moose_inventory/cli/host_listvars.rb +9 -62
  67. data/lib/moose_inventory/cli/host_rm.rb +60 -42
  68. data/lib/moose_inventory/cli/host_rmgroup.rb +25 -44
  69. data/lib/moose_inventory/cli/host_rmvar.rb +31 -45
  70. data/lib/moose_inventory/cli/host_tags.rb +33 -0
  71. data/lib/moose_inventory/cli/listvars_support.rb +55 -0
  72. data/lib/moose_inventory/cli/plan_rendering.rb +50 -0
  73. data/lib/moose_inventory/cli/relation_transaction_support.rb +51 -0
  74. data/lib/moose_inventory/cli/tag_support.rb +97 -0
  75. data/lib/moose_inventory/cli/variable_rendering.rb +67 -0
  76. data/lib/moose_inventory/config/config.rb +185 -108
  77. data/lib/moose_inventory/db/db.rb +170 -195
  78. data/lib/moose_inventory/db/exceptions.rb +6 -3
  79. data/lib/moose_inventory/db/models.rb +16 -0
  80. data/lib/moose_inventory/db/schema_migrations.rb +248 -0
  81. data/lib/moose_inventory/inventory_context.rb +68 -2
  82. data/lib/moose_inventory/operations/add_associations.rb +20 -16
  83. data/lib/moose_inventory/operations/add_groups.rb +21 -13
  84. data/lib/moose_inventory/operations/add_hosts.rb +30 -17
  85. data/lib/moose_inventory/operations/add_variables.rb +77 -0
  86. data/lib/moose_inventory/operations/entity_variable_operation_support.rb +46 -0
  87. data/lib/moose_inventory/operations/group_child_relations.rb +23 -16
  88. data/lib/moose_inventory/operations/group_cleanup.rb +23 -8
  89. data/lib/moose_inventory/operations/import_inventory_snapshot.rb +41 -0
  90. data/lib/moose_inventory/operations/inventory_doctor.rb +172 -0
  91. data/lib/moose_inventory/operations/inventory_snapshot.rb +60 -0
  92. data/lib/moose_inventory/operations/inventory_snapshot_applier.rb +112 -0
  93. data/lib/moose_inventory/operations/inventory_snapshot_preview.rb +174 -0
  94. data/lib/moose_inventory/operations/inventory_snapshot_validator.rb +174 -0
  95. data/lib/moose_inventory/operations/operation_event_support.rb +27 -0
  96. data/lib/moose_inventory/operations/query_inventory/base_query.rb +24 -0
  97. data/lib/moose_inventory/operations/query_inventory/group_queries.rb +86 -0
  98. data/lib/moose_inventory/operations/query_inventory/host_queries.rb +106 -0
  99. data/lib/moose_inventory/operations/query_inventory.rb +47 -0
  100. data/lib/moose_inventory/operations/remove_associations.rb +30 -18
  101. data/lib/moose_inventory/operations/remove_groups.rb +12 -12
  102. data/lib/moose_inventory/operations/remove_hosts.rb +68 -0
  103. data/lib/moose_inventory/operations/remove_variables.rb +67 -0
  104. data/lib/moose_inventory/runtime_options.rb +31 -0
  105. data/lib/moose_inventory/version.rb +3 -1
  106. data/lib/moose_inventory.rb +10 -7
  107. data/moose-inventory.gemspec +19 -35
  108. data/scripts/check.sh +1 -0
  109. data/scripts/ci/check_generated_artifacts.sh +41 -0
  110. data/scripts/ci/check_permissions.sh +2 -0
  111. data/scripts/ci/check_rubocop.sh +30 -25
  112. data/scripts/ci/check_security.sh +4 -1
  113. data/scripts/files.rb +5 -4
  114. data/spec/examples/ci_examples_spec.rb +37 -0
  115. data/spec/lib/moose_inventory/ansible_plugin_examples_spec.rb +29 -0
  116. data/spec/lib/moose_inventory/cli/application_doctor_spec.rb +50 -0
  117. data/spec/lib/moose_inventory/cli/application_import_export_spec.rb +132 -0
  118. data/spec/lib/moose_inventory/cli/application_spec.rb +25 -15
  119. data/spec/lib/moose_inventory/cli/audit_spec.rb +56 -0
  120. data/spec/lib/moose_inventory/cli/cli_spec.rb +15 -19
  121. data/spec/lib/moose_inventory/cli/console_spec.rb +98 -0
  122. data/spec/lib/moose_inventory/cli/factory_spec.rb +27 -0
  123. data/spec/lib/moose_inventory/cli/formatter_spec.rb +95 -3
  124. data/spec/lib/moose_inventory/cli/group_add_spec.rb +140 -116
  125. data/spec/lib/moose_inventory/cli/group_addchild_spec.rb +89 -35
  126. data/spec/lib/moose_inventory/cli/group_addhost_spec.rb +81 -84
  127. data/spec/lib/moose_inventory/cli/group_addvar_spec.rb +65 -68
  128. data/spec/lib/moose_inventory/cli/group_get_spec.rb +17 -33
  129. data/spec/lib/moose_inventory/cli/group_list_spec.rb +16 -38
  130. data/spec/lib/moose_inventory/cli/group_listvar_spec.rb +33 -40
  131. data/spec/lib/moose_inventory/cli/group_rm_spec.rb +136 -96
  132. data/spec/lib/moose_inventory/cli/group_rmchild_spec.rb +66 -41
  133. data/spec/lib/moose_inventory/cli/group_rmhost_spec.rb +76 -78
  134. data/spec/lib/moose_inventory/cli/group_rmvar_spec.rb +57 -63
  135. data/spec/lib/moose_inventory/cli/group_spec.rb +2 -0
  136. data/spec/lib/moose_inventory/cli/helpers_spec.rb +146 -0
  137. data/spec/lib/moose_inventory/cli/host_add_spec.rb +170 -116
  138. data/spec/lib/moose_inventory/cli/host_addgroup_spec.rb +100 -83
  139. data/spec/lib/moose_inventory/cli/host_addvar_spec.rb +92 -74
  140. data/spec/lib/moose_inventory/cli/host_get_spec.rb +14 -33
  141. data/spec/lib/moose_inventory/cli/host_list_spec.rb +41 -33
  142. data/spec/lib/moose_inventory/cli/host_listvar_spec.rb +45 -53
  143. data/spec/lib/moose_inventory/cli/host_rm_spec.rb +66 -48
  144. data/spec/lib/moose_inventory/cli/host_rmgroup_spec.rb +73 -83
  145. data/spec/lib/moose_inventory/cli/host_rmvar_spec.rb +56 -63
  146. data/spec/lib/moose_inventory/cli/host_spec.rb +2 -0
  147. data/spec/lib/moose_inventory/cli/tags_spec.rb +81 -0
  148. data/spec/lib/moose_inventory/config/config_spec.rb +41 -3
  149. data/spec/lib/moose_inventory/db/db_spec.rb +396 -36
  150. data/spec/lib/moose_inventory/db/exceptions_spec.rb +18 -0
  151. data/spec/lib/moose_inventory/db/models_spec.rb +7 -3
  152. data/spec/lib/moose_inventory/db_lifecycle_spec.rb +73 -0
  153. data/spec/lib/moose_inventory/inventory_context_spec.rb +10 -0
  154. data/spec/lib/moose_inventory/operations/add_associations_spec.rb +34 -0
  155. data/spec/lib/moose_inventory/operations/add_groups_spec.rb +15 -0
  156. data/spec/lib/moose_inventory/operations/add_hosts_spec.rb +13 -0
  157. data/spec/lib/moose_inventory/operations/add_variables_spec.rb +103 -0
  158. data/spec/lib/moose_inventory/operations/group_child_relations_spec.rb +46 -0
  159. data/spec/lib/moose_inventory/operations/import_inventory_snapshot_spec.rb +239 -0
  160. data/spec/lib/moose_inventory/operations/inventory_doctor_spec.rb +77 -0
  161. data/spec/lib/moose_inventory/operations/inventory_snapshot_spec.rb +50 -0
  162. data/spec/lib/moose_inventory/operations/operation_event_support_spec.rb +78 -0
  163. data/spec/lib/moose_inventory/operations/query_inventory_spec.rb +146 -0
  164. data/spec/lib/moose_inventory/operations/remove_associations_spec.rb +35 -0
  165. data/spec/lib/moose_inventory/operations/remove_groups_spec.rb +21 -0
  166. data/spec/lib/moose_inventory/operations/remove_hosts_spec.rb +55 -0
  167. data/spec/lib/moose_inventory/operations/remove_variables_spec.rb +83 -0
  168. data/spec/shared/shared_config_setup.rb +4 -3
  169. data/spec/spec_helper.rb +50 -40
  170. data/spec/support/cli_harness.rb +33 -0
  171. metadata +81 -41
@@ -1,7 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Configuration
2
4
 
3
5
  require 'yaml'
4
6
 
7
+ require_relative '../runtime_options'
8
+
5
9
  module Moose
6
10
  module Inventory
7
11
  ##
@@ -11,16 +15,16 @@ module Moose
11
15
  extend self
12
16
  # rubocop:enable Style/ModuleFunction
13
17
 
14
- @_argv = []
18
+ @_argv = []
15
19
  @_confopts = {}
16
20
  @_settings = {}
21
+ @runtime_options = nil
17
22
 
18
- attr_reader :_argv
19
- attr_reader :_confopts
20
- attr_reader :_settings
23
+ attr_reader :_argv, :_confopts, :_settings
21
24
 
22
25
  #----------------------
23
26
  def self.init(args)
27
+ reset_runtime_state
24
28
  @_argv = args.dup
25
29
 
26
30
  top_level_help
@@ -28,6 +32,46 @@ module Moose
28
32
  ansible_args
29
33
  resolve_config_file
30
34
  load
35
+ refresh_runtime_options
36
+ end
37
+
38
+ def self.reset_runtime_state
39
+ @_argv = []
40
+ @_confopts = default_confopts
41
+ @_settings = {}
42
+ @runtime_options = nil
43
+ end
44
+
45
+ def self.default_confopts
46
+ { env: '', format: 'json', ansible: false, trace: false }
47
+ end
48
+
49
+ def self.runtime_options
50
+ @runtime_options ||= build_runtime_options
51
+ end
52
+
53
+ def self.application_args
54
+ runtime_options.argv
55
+ end
56
+
57
+ def self.output_format
58
+ runtime_options.output_format
59
+ end
60
+
61
+ def self.ansible?
62
+ runtime_options.ansible? || @_confopts[:ansible] == true
63
+ end
64
+
65
+ def self.trace_enabled?
66
+ runtime_options.trace? || @_confopts[:trace] == true
67
+ end
68
+
69
+ def self.db_settings
70
+ @_settings[:config][:db]
71
+ end
72
+
73
+ def self._runtime_options
74
+ @runtime_options
31
75
  end
32
76
 
33
77
  #----------------------
@@ -51,50 +95,26 @@ module Moose
51
95
  # -- trace => Enable more complete exceptions for db transactions
52
96
  # Default is not to trace.
53
97
 
54
- @_confopts = { env: '', format: 'json', ansible: false, trace: false }
55
-
56
- # Check for two-part flags
57
- %w(config env format).each do |var|
58
- @_argv.each_with_index do |val, index|
59
- next if val != "--#{var}"
60
- @_confopts[var.to_sym] = @_argv[index + 1]
61
- 1.downto(0) { |offset| @_argv.delete_at(index + offset) }
62
- break
63
- end
64
- end
65
-
66
- # Check for one-part flags
67
- %w(ansible trace).each do |var|
68
- @_argv.each_with_index do |val, index|
69
- next if val != "--#{var}"
70
- @_confopts[var.to_sym] = true
71
- @_argv.delete_at(index)
72
- break
73
- end
74
- end
75
-
76
- # Sanity
77
- # - Ansible output format must be json - pjson is permitted, but yaml is not.
78
- if @_confopts[:ansible] == true
79
- unless @_confopts[:format] =~ /p|pjson|j|json/
80
- @_confopts[:format] = 'json'
81
- end
82
- end
98
+ extract_value_flags(%w[config env format])
99
+ extract_boolean_flags(%w[ansible trace])
100
+ normalize_ansible_format!
83
101
  end
84
102
 
85
103
  #----------------------
86
104
  def self.top_level_help
87
- if @_argv[0] == 'help'
88
- puts 'Global flags:'
89
- printf ' %-31s %-10s', '--ansible', "# Force Ansible mode (automatically set when using ansible flags)\n"
90
- printf ' %-31s %-10s', '--config FILE', "# Specifies a configuration file to use\n"
91
- printf ' %-31s %-10s', '--env ENV', "# Specifies the environment section of the config to use\n"
92
- printf ' %-31s %-10s', '--format yaml|json|pjson', "# Format for the output of 'get', 'list', and 'listvars' subcommands\n"
93
- printf ' %-31s %-10s', '--trace', "# Enable more complete exception dumps for database transactions\n"
94
- puts "\nAnsible flags:"
95
- printf ' %-31s %-10s', '--host HOSTNAME', "# Retrieves host variables for the specified host (alias for 'host listvars HOSTNAME')\n"
96
- printf ' %-31s %-10s', '--list', "# Retrieves the list of groups (alias for 'group list')\n\n"
97
- end
105
+ return unless @_argv[0] == 'help'
106
+
107
+ puts 'Global flags:'
108
+ printf ' %-31s %-10s', '--ansible', "# Force Ansible mode (automatically set when using ansible flags)\n"
109
+ printf ' %-31s %-10s', '--config FILE', "# Specifies a configuration file to use\n"
110
+ printf ' %-31s %-10s', '--env ENV', "# Specifies the environment section of the config to use\n"
111
+ printf ' %-31s %-10s', '--format yaml|json|pjson',
112
+ "# Format for the output of 'get', 'list', and 'listvars' subcommands\n"
113
+ printf ' %-31s %-10s', '--trace', "# Enable more complete exception dumps for database transactions\n"
114
+ puts "\nAnsible flags:"
115
+ printf ' %-31s %-10s', '--host HOSTNAME',
116
+ "# Retrieves host variables for the specified host (alias for 'host listvars HOSTNAME')\n"
117
+ printf ' %-31s %-10s', '--list', "# Retrieves the list of groups (alias for 'group list')\n\n"
98
118
  end
99
119
 
100
120
  #----------------------
@@ -108,95 +128,152 @@ module Moose
108
128
 
109
129
  case @_argv[0]
110
130
  when '--list'
111
- @_confopts[:ansible] = true
112
- @_confopts[:format] = 'json' unless @_confopts[:format] =~ /p|pjson|j|json/
113
- @_argv.clear
114
- @_argv.concat(%w(group list)).flatten
131
+ apply_ansible_alias!(%w[group list])
115
132
  when '--host'
116
- @_confopts[:ansible] = true
117
- @_confopts[:format] = 'json' unless @_confopts[:format] =~ /p|pjson|j|json/
118
133
  host = @_argv[1]
119
- @_argv.clear
120
- @_argv.concat(['host', 'listvars', host.to_s]).flatten
134
+ apply_ansible_alias!(['host', 'listvars', host.to_s])
121
135
  end
122
136
  end
123
137
 
124
138
  #----------------------
125
139
  def self.resolve_config_file
126
- if !@_confopts[:config].nil?
127
- path = File.expand_path(@_confopts[:config])
128
- if File.exist?(path)
129
- @_confopts[:config] = path
130
- else
131
- fail("The configuration file #{path} does not exist")
132
- end
133
- else
134
- possibles = ['./.moose-tools/inventory/config',
135
- '~/.moose-tools/inventory/config',
136
- '~/local/etc/moose-tools/inventory/config',
137
- '/etc/moose-tools/inventory/config']
138
- possibles.each do |f|
139
- file = File.expand_path(f)
140
- @_confopts[:config] = file if File.exist?(file)
141
- end
142
- end
140
+ explicit_path = @_confopts[:config]
141
+ @_confopts[:config] = if explicit_path.nil?
142
+ find_default_config_file
143
+ else
144
+ validated_config_path(explicit_path)
145
+ end
143
146
 
144
- if @_confopts[:config].nil?
145
- fail('No configuration either given or found in standard locations.')
146
- end
147
+ raise('No configuration either given or found in standard locations.') if @_confopts[:config].nil?
147
148
  end
148
149
 
149
150
  #----------------------
150
151
  def self.symbolize_keys(hash)
151
- # rubocop:disable Style/EachWithObject
152
- hash.inject({}) do |result, (key, value)|
153
- new_key = case key
154
- when String then key.to_sym
155
- else key
156
- end
157
- new_value = case value
158
- when Hash then symbolize_keys(value)
159
- else value
160
- end
161
- result[new_key] = new_value
162
- result
152
+ hash.each_with_object({}) do |(key, value), result|
153
+ result[symbolize_key(key)] = value.is_a?(Hash) ? symbolize_keys(value) : value
163
154
  end
164
- # rubocop:enable Style/EachWithObject
165
155
  end
166
156
 
167
157
  #----------------------
168
- # rubocop:disable PerceivedComplexity
169
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize
170
158
  def self.load
171
- newsets = symbolize_keys(YAML.safe_load_file(
172
- @_confopts[:config],
173
- aliases: false,
174
- permitted_classes: [],
175
- permitted_symbols: []
176
- ))
177
-
159
+ newsets = load_config_file(@_confopts[:config])
178
160
  path = @_confopts[:config]
179
161
 
180
- # Get the "general" section
181
- @_settings[:general] = newsets[:general]
182
- @_settings[:general].nil? && fail("Missing 'general' root in #{path}")
162
+ @_settings[:general] = fetch_general_settings(newsets, path)
163
+
164
+ env, settings = resolve_environment_settings(newsets, path)
165
+ @_settings[:config] = settings
166
+ @_settings[:config].nil? && raise("Missing '#{env}' root in #{path}")
167
+ end
168
+
169
+ def self.load_config_file(path)
170
+ symbolize_keys(YAML.safe_load_file(
171
+ path,
172
+ aliases: false,
173
+ permitted_classes: [],
174
+ permitted_symbols: []
175
+ ))
176
+ end
183
177
 
184
- # Get the config for the correct environment
178
+ def self.fetch_general_settings(newsets, path)
179
+ general = newsets[:general]
180
+ general.nil? && raise("Missing 'general' root in #{path}")
181
+ general
182
+ end
183
+
184
+ def self.resolve_environment_settings(newsets, path)
185
+ env = selected_environment(newsets, path)
186
+ [env, newsets[env.to_sym]]
187
+ end
185
188
 
186
- if @_confopts[:env] && !@_confopts[:env].empty?
187
- env = @_confopts[:env]
188
- @_settings[:config] = newsets[@_confopts[:env].to_sym]
189
- else
190
- env = @_settings[:general][:defaultenv]
191
- (env.nil? || env.empty?) && fail("No defaultenv set in #{path}")
192
- @_settings[:config] = newsets[env.to_sym]
189
+ def self.selected_environment(newsets, path)
190
+ return @_confopts[:env] if @_confopts[:env] && !@_confopts[:env].empty?
191
+
192
+ env = newsets.dig(:general, :defaultenv)
193
+ (env.nil? || env.empty?) && raise("No defaultenv set in #{path}")
194
+ env
195
+ end
196
+
197
+ def self.standard_config_paths
198
+ ['./.moose-tools/inventory/config',
199
+ '~/.moose-tools/inventory/config',
200
+ '~/local/etc/moose-tools/inventory/config',
201
+ '/etc/moose-tools/inventory/config']
202
+ end
203
+
204
+ def self.find_default_config_file
205
+ standard_config_paths.map { |path| File.expand_path(path) }.find do |path|
206
+ File.exist?(path)
193
207
  end
208
+ end
209
+
210
+ def self.validated_config_path(path)
211
+ expanded = File.expand_path(path)
212
+ raise("The configuration file #{expanded} does not exist") unless File.exist?(expanded)
213
+
214
+ expanded
215
+ end
216
+
217
+ def self.extract_value_flags(flags)
218
+ flags.each { |flag| extract_value_flag(flag) }
219
+ end
220
+
221
+ def self.extract_value_flag(flag)
222
+ index = @_argv.index("--#{flag}")
223
+ return if index.nil?
194
224
 
195
- @_settings[:config].nil? && fail("Missing '#{env}' root in #{path}")
225
+ value = @_argv[index + 1]
226
+ raise("Expected a value after --#{flag}") if value.nil? || value.start_with?('--')
227
+
228
+ @_confopts[flag.to_sym] = value
229
+ @_argv.slice!(index, 2)
230
+ end
231
+
232
+ def self.extract_boolean_flags(flags)
233
+ flags.each { |flag| extract_boolean_flag(flag) }
234
+ end
235
+
236
+ def self.extract_boolean_flag(flag)
237
+ index = @_argv.index("--#{flag}")
238
+ return if index.nil?
239
+
240
+ @_confopts[flag.to_sym] = true
241
+ @_argv.delete_at(index)
242
+ end
243
+
244
+ def self.normalize_ansible_format!
245
+ return unless @_confopts[:ansible] == true
246
+ return if @_confopts[:format] =~ /p|pjson|j|json/
247
+
248
+ @_confopts[:format] = 'json'
249
+ end
250
+
251
+ def self.apply_ansible_alias!(argv)
252
+ @_confopts[:ansible] = true
253
+ normalize_ansible_format!
254
+ @_argv = argv
255
+ end
256
+
257
+ def self.refresh_runtime_options
258
+ @runtime_options = build_runtime_options
259
+ end
260
+
261
+ def self.build_runtime_options
262
+ Moose::Inventory::RuntimeOptions.new(
263
+ argv: @_argv.dup,
264
+ config: @_confopts[:config],
265
+ env: @_confopts[:env],
266
+ format: @_confopts[:format],
267
+ flags: {
268
+ ansible: @_confopts[:ansible],
269
+ trace: @_confopts[:trace]
270
+ }
271
+ )
272
+ end
196
273
 
197
- # And now we should have a valid config stuffed into @_options[:config]
274
+ def self.symbolize_key(key)
275
+ key.is_a?(String) ? key.to_sym : key
198
276
  end
199
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/AbcSize
200
277
  end
201
278
  end
202
279
  end