hammer_cli 3.6.0 → 3.8.0

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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/bin/hammer +1 -6
  3. data/config/cli_config.template.yml +3 -3
  4. data/doc/release_notes.md +24 -0
  5. data/lib/hammer_cli/abstract.rb +1 -1
  6. data/lib/hammer_cli/defaults_commands.rb +0 -1
  7. data/lib/hammer_cli/help/builder.rb +7 -8
  8. data/lib/hammer_cli/i18n/find_task.rb +88 -0
  9. data/lib/hammer_cli/i18n.rb +4 -0
  10. data/lib/hammer_cli/logger.rb +2 -2
  11. data/lib/hammer_cli/modules.rb +1 -1
  12. data/lib/hammer_cli/options/normalizers.rb +4 -7
  13. data/lib/hammer_cli/options/validators/dsl.rb +1 -1
  14. data/lib/hammer_cli/output/adapter/csv.rb +0 -1
  15. data/lib/hammer_cli/output/dsl.rb +1 -1
  16. data/lib/hammer_cli/output/fields.rb +1 -1
  17. data/lib/hammer_cli/output/formatters.rb +4 -4
  18. data/lib/hammer_cli/settings.rb +7 -0
  19. data/lib/hammer_cli/ssloptions.rb +3 -3
  20. data/lib/hammer_cli/subcommand.rb +1 -0
  21. data/lib/hammer_cli/task_helper.rb +84 -0
  22. data/lib/hammer_cli/testing/output_matchers.rb +1 -1
  23. data/lib/hammer_cli/utils.rb +1 -13
  24. data/lib/hammer_cli/version.rb +1 -1
  25. data/locale/Makefile.def +29 -7
  26. data/locale/ca/LC_MESSAGES/hammer-cli.mo +0 -0
  27. data/locale/cs_CZ/LC_MESSAGES/hammer-cli.mo +0 -0
  28. data/locale/de/LC_MESSAGES/hammer-cli.mo +0 -0
  29. data/locale/en/LC_MESSAGES/hammer-cli.mo +0 -0
  30. data/locale/en_GB/LC_MESSAGES/hammer-cli.mo +0 -0
  31. data/locale/es/LC_MESSAGES/hammer-cli.mo +0 -0
  32. data/locale/fr/LC_MESSAGES/hammer-cli.mo +0 -0
  33. data/locale/it/LC_MESSAGES/hammer-cli.mo +0 -0
  34. data/locale/ja/LC_MESSAGES/hammer-cli.mo +0 -0
  35. data/locale/ka/LC_MESSAGES/hammer-cli.mo +0 -0
  36. data/locale/ko/LC_MESSAGES/hammer-cli.mo +0 -0
  37. data/locale/pt_BR/LC_MESSAGES/hammer-cli.mo +0 -0
  38. data/locale/ru/LC_MESSAGES/hammer-cli.mo +0 -0
  39. data/locale/zh_CN/LC_MESSAGES/hammer-cli.mo +0 -0
  40. data/locale/zh_TW/LC_MESSAGES/hammer-cli.mo +0 -0
  41. data/man/hammer.1.gz +0 -0
  42. data/test/functional/defaults_test.rb +0 -1
  43. data/test/functional/help_test.rb +1 -1
  44. data/test/test_helper.rb +1 -1
  45. data/test/unit/abstract_test.rb +54 -54
  46. data/test/unit/apipie/command_test.rb +27 -28
  47. data/test/unit/apipie/option_builder_test.rb +28 -28
  48. data/test/unit/apipie/option_definition_test.rb +6 -6
  49. data/test/unit/apipie/test_helper.rb +3 -0
  50. data/test/unit/bash_test.rb +21 -21
  51. data/test/unit/command_extensions_test.rb +68 -68
  52. data/test/unit/completer_test.rb +57 -57
  53. data/test/unit/csv_parser_test.rb +12 -12
  54. data/test/unit/defaults_test.rb +3 -3
  55. data/test/unit/exception_handler_test.rb +3 -3
  56. data/test/unit/help/builder_test.rb +7 -7
  57. data/test/unit/help/definition/abstract_item_test.rb +2 -2
  58. data/test/unit/help/definition/list_test.rb +2 -2
  59. data/test/unit/help/definition/note_test.rb +2 -2
  60. data/test/unit/help/definition/section_test.rb +2 -2
  61. data/test/unit/help/definition/text_test.rb +2 -2
  62. data/test/unit/help/definition_test.rb +36 -36
  63. data/test/unit/help/text_builder_test.rb +39 -39
  64. data/test/unit/history_test.rb +8 -8
  65. data/test/unit/i18n_test.rb +2 -2
  66. data/test/unit/logger_test.rb +3 -3
  67. data/test/unit/main_test.rb +7 -7
  68. data/test/unit/modules_test.rb +24 -25
  69. data/test/unit/option_builder_test.rb +1 -1
  70. data/test/unit/options/matcher_test.rb +15 -15
  71. data/test/unit/options/normalizers_test.rb +92 -88
  72. data/test/unit/options/option_definition_test.rb +13 -13
  73. data/test/unit/options/option_family_test.rb +7 -7
  74. data/test/unit/options/sources/saved_defaults_test.rb +0 -4
  75. data/test/unit/options/validators/dsl_test.rb +35 -35
  76. data/test/unit/output/adapter/abstract_test.rb +13 -13
  77. data/test/unit/output/adapter/base_test.rb +36 -36
  78. data/test/unit/output/adapter/csv_test.rb +44 -44
  79. data/test/unit/output/adapter/json_test.rb +38 -38
  80. data/test/unit/output/adapter/table_test.rb +47 -55
  81. data/test/unit/output/adapter/yaml_test.rb +38 -38
  82. data/test/unit/output/definition_test.rb +43 -43
  83. data/test/unit/output/dsl_test.rb +19 -19
  84. data/test/unit/output/field_filter_test.rb +10 -10
  85. data/test/unit/output/fields_test.rb +27 -27
  86. data/test/unit/output/formatters_test.rb +39 -39
  87. data/test/unit/output/output_test.rb +14 -14
  88. data/test/unit/output/record_collection_test.rb +18 -18
  89. data/test/unit/settings_test.rb +35 -35
  90. data/test/unit/utils_test.rb +30 -27
  91. metadata +10 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a6293c3d040b5065886e9b590864901ce167d8599cb09e1d2acb4c0f941aae0f
4
- data.tar.gz: e5f30fd542b84ca83f3bed8748d0914cc44efeccf6c85c22a17c6ef1895b5d0f
3
+ metadata.gz: 9c1d1eca37ea41bee11e7826fbfc491b99bce78026eee0f3ae72acaa2b472503
4
+ data.tar.gz: f327b7901efa9824e5118ac7e20daa42835e8d01813be55e2db4001697249a39
5
5
  SHA512:
6
- metadata.gz: e137dc396915144be972cae6b0824862d68536084d7d2670829e7f895f711e7d214e15f1214f0722657898bc45654284689ed98858f23d022472747bec05500e
7
- data.tar.gz: e48ab29d2b54d9ef05bfc89839597dd9ecff9f2538509a638420cf487f971f7919b51a7720200c7a0fdf1904445f1c52bdd01a1e0d9eadad4199251870db0fbc
6
+ metadata.gz: e945cf3fb8671ec5089e45e4a75f47cd906c99b47124b5887b8b8ed627fb6a41145218fd07638b78208ac8e845342e9e4f7a2418b4c5b5f091eeaafc6a74d4a6
7
+ data.tar.gz: c56001b49b27c10ba388e84791b1b0794a5a7873a0320877cd0a73e393b1bd1da1b64b6e745d54bf618f0fda71f56c174cc4d74fa1128963b6a4895a97b70aa4
data/bin/hammer CHANGED
@@ -56,12 +56,7 @@ end
56
56
  # load user's settings
57
57
  require 'hammer_cli/settings'
58
58
 
59
- CFG_PATH = ['~/.hammer/', '/etc/hammer/', "#{::RbConfig::CONFIG['sysconfdir']}/hammer/"].uniq
60
- HammerCLI::Settings.load_from_paths CFG_PATH
61
-
62
- CFG_PATH_LOCAL = ['./config/']
63
-
64
- HammerCLI::Settings.load_from_paths CFG_PATH_LOCAL
59
+ HammerCLI::Settings.load_from_defaults
65
60
 
66
61
  if preparser.config
67
62
  if File.file? preparser.config
@@ -7,7 +7,7 @@
7
7
  # Location of shell history file
8
8
  :history_file: '~/.hammer/history'
9
9
  # Mark translated strings with X characters (for developers)
10
- #:mark_translated: false
10
+ # :mark_translated: false
11
11
  # Hide headers from output of list actions
12
12
  # :no_headers: true
13
13
  # Choose capitalization for JSON/YAML output.
@@ -17,7 +17,7 @@
17
17
  # Enable/disable color output of logger in Clamp commands
18
18
  :watch_plain: false
19
19
 
20
- # Forece relaod of Apipie cache with every Hammer invocation
20
+ # Force reload of Apipie cache with every Hammer invocation
21
21
  :reload_cache: false
22
22
 
23
23
  # Directory where the logs are stored. The default is /var/log/hammer/ and the log file is named hammer.log
@@ -75,5 +75,5 @@
75
75
  # Certs from the local storage are used only when neither :ssl_ca_file: nor :ssl_ca_path: is cofigured.
76
76
  #:local_ca_store_path: '~/.hammer/certs'
77
77
 
78
- # Allows setting the SSL version to use when making API calls
78
+ # Allows setting the SSL version to use when making API calls
79
79
  #:ssl_version: 'TLSv1_2'
data/doc/release_notes.md CHANGED
@@ -1,5 +1,29 @@
1
1
  Release notes
2
2
  =============
3
+ ### 3.8.0 (2023-08-25)
4
+ * Consider false values in string#format, [#36588](http://projects.theforeman.org/issues/36588)
5
+ * Drop unicode gem ([PR #376](https://github.com/theforeman/hammer-cli/pull/376))
6
+ * Improve regex for keyvaluelist normalizer, [#36258](http://projects.theforeman.org/issues/36258)
7
+ * Fix minitest ([PR #375](https://github.com/theforeman/hammer-cli/pull/375))
8
+ * Add ga to run tests on ruby 3+
9
+ * Wrap commands with class.new to clone, [#36592](http://projects.theforeman.org/issues/36592)
10
+ * Try to upgrade ci_reporter, [#36592](http://projects.theforeman.org/issues/36592)
11
+ * Update minitest version, [#36592](http://projects.theforeman.org/issues/36592)
12
+ * Improve rakefile tx commands, [#36283](http://projects.theforeman.org/issues/36283)
13
+ * Move makefile targets to rakefile, [#36283](http://projects.theforeman.org/issues/36283)
14
+ * Update transifex automation, [#36283](http://projects.theforeman.org/issues/36283)
15
+ * Add packit config ([PR #370](https://github.com/theforeman/hammer-cli/pull/370))
16
+ * Bump to 3.8.0-develop
17
+
18
+ ### 3.7.0 (2023-05-23)
19
+ * Honor tz in datetime normalizer ([PR #369](https://github.com/theforeman/hammer-cli/pull/369)), [#36418](http://projects.theforeman.org/issues/36418)
20
+ * Remove unused code, [#36337](http://projects.theforeman.org/issues/36337)
21
+ * Fix ambiguous operator warnings, [#36337](http://projects.theforeman.org/issues/36337)
22
+ * Update rake and clamp deps, [#36337](http://projects.theforeman.org/issues/36337)
23
+ * Fix config template typos ([PR #365](https://github.com/theforeman/hammer-cli/pull/365))
24
+ * Load ssl key using openssl::pkey.read ([PR #364](https://github.com/theforeman/hammer-cli/pull/364)), [#34853](http://projects.theforeman.org/issues/34853)
25
+ * Bump to 3.7.0-develop
26
+
3
27
  ### 3.6.0 (2023-02-23)
4
28
  * Update apipie-bindings to 0.6.0
5
29
  * Include makefile.def in the gem
@@ -192,7 +192,7 @@ module HammerCLI
192
192
 
193
193
  def self.output(definition=nil, &block)
194
194
  dsl = HammerCLI::Output::Dsl.new
195
- dsl.build &block if block_given?
195
+ dsl.build(&block) if block_given?
196
196
  output_definition.append definition.fields unless definition.nil?
197
197
  output_definition.append dsl.fields
198
198
  end
@@ -1,4 +1,3 @@
1
- require 'hammer_cli'
2
1
  require 'yaml'
3
2
  module HammerCLI
4
3
  class BaseDefaultsProvider
@@ -1,4 +1,3 @@
1
- require 'unicode'
2
1
  module HammerCLI
3
2
  module Help
4
3
  class Builder < Clamp::Help::Builder
@@ -14,7 +13,7 @@ module HammerCLI
14
13
  def add_usage(invocation_path, usage_descriptions)
15
14
  heading(Clamp.message(:usage_heading))
16
15
  usage_descriptions.each do |usage|
17
- puts " #{HammerCLI.expand_invocation_path(invocation_path)} #{usage}".rstrip
16
+ line " #{HammerCLI.expand_invocation_path(invocation_path)} #{usage}".rstrip
18
17
  end
19
18
  end
20
19
 
@@ -24,7 +23,7 @@ module HammerCLI
24
23
  end
25
24
  items.reject! {|item| item.respond_to?(:hidden?) && item.hidden?}
26
25
 
27
- puts
26
+ line
28
27
  heading(heading)
29
28
 
30
29
  label_width = DEFAULT_LABEL_INDENT
@@ -46,16 +45,16 @@ module HammerCLI
46
45
  else
47
46
  item.help
48
47
  end
49
- description.gsub(/^(.)/) { Unicode.capitalize(Regexp.last_match(1)) }.wrap.each_line do |line|
50
- puts " %-#{label_width}s %s" % [label, line]
48
+ description.gsub(/^(.)/) { Regexp.last_match(1).capitalize }.wrap.each_line do |line|
49
+ line " %-#{label_width}s %s" % [label, line]
51
50
  label = ''
52
51
  end
53
52
  end
54
53
  end
55
54
 
56
55
  def add_text(content)
57
- puts
58
- puts content
56
+ line
57
+ line content
59
58
  end
60
59
 
61
60
  protected
@@ -63,7 +62,7 @@ module HammerCLI
63
62
  def heading(label)
64
63
  label = "#{label}:"
65
64
  label = HighLine.color(label, :bold) if @richtext
66
- puts label
65
+ line label
67
66
  end
68
67
  end
69
68
  end
@@ -1,10 +1,13 @@
1
1
  require 'rake'
2
+ require_relative '../task_helper'
2
3
 
3
4
  module HammerCLI
4
5
  module I18n
5
6
  class FindTask
6
7
  include Rake::DSL
7
8
 
9
+ MIN_TRANSLATION_PERC = 50
10
+
8
11
  def initialize(domain, version)
9
12
  @domain = domain
10
13
  @version = version
@@ -30,6 +33,91 @@ module HammerCLI
30
33
  task :find => [:setup] do
31
34
  Rake::Task["gettext:po:update"].invoke
32
35
  end
36
+
37
+ desc 'Check languages with 50% or more coverage and create needed files'
38
+ task :find_new do
39
+ client = HammerCLI::TaskHelper::I18n::TxApiClient.new(domain: @domain)
40
+ stats = client.language_stats_collection
41
+ lang_percentages = stats['data'].each_with_object({}) do |lang, res|
42
+ res[lang['id'].split(':').last] = (lang['attributes']['translated_strings'] * 100.0 / lang['attributes']['total_strings']).round
43
+ end
44
+ lang_percentages.select { |_, v| v >= MIN_TRANSLATION_PERC }.each_key do |lang|
45
+ lang_dir = File.join(@domain.locale_dir, lang)
46
+ FileUtils.mkpath(lang_dir)
47
+ FileUtils.cp(File.join(@domain.locale_dir, "#{@domain.domain_name}.pot"), File.join(lang_dir, "#{@domain.domain_name}.po"))
48
+ end
49
+ end
50
+ end
51
+
52
+ namespace :tx do
53
+ desc 'Pull translations from transifex'
54
+ task :pull do
55
+ raise 'Command tx not found. Make sure you have transifex-client installed and configured.' unless system("command -v tx >/dev/null 2>&1")
56
+
57
+ sh "tx pull -f"
58
+ edit_files = Dir.glob(File.join(@domain.locale_dir, '**', '*.edit.po'))
59
+ edit_files.each do |edit_file|
60
+ `sed -i 's/^\\("Project-Id-Version: \\).*$/\\1#{@domain.domain_name} #{@version}\\\\n"/' #{edit_file};`
61
+ end
62
+ end
63
+
64
+ desc 'Merge .edit.po into .po'
65
+ task :update_po do
66
+ edit_files = Dir.glob(File.join(@domain.locale_dir, '**', '*.edit.po'))
67
+ edit_files.each do |edit_file|
68
+ po_file = edit_file.gsub('.edit.po', '.po')
69
+ sh "msgcat --use-first --no-location #{edit_file} #{po_file} --output-file #{po_file}"
70
+ end
71
+ end
72
+
73
+ desc 'Generate MO files from PO files'
74
+ task :all_mo do
75
+ po_files = Dir.glob(File.join(@domain.locale_dir, '**', "#{@domain.domain_name}.po"))
76
+ po_files.each do |po_file|
77
+ dir = File.dirname(po_file) + '/LC_MESSAGES'
78
+ FileUtils.mkdir_p(dir)
79
+ sh "msgfmt -o #{dir}/#{@domain.domain_name}.mo #{po_file}"
80
+ end
81
+ end
82
+
83
+ desc 'Download and merge translations from Transifex'
84
+ task :update do
85
+ Rake::Task['gettext:find_new'].invoke
86
+ Rake::Task['gettext:find'].invoke
87
+ Rake::Task['tx:pull'].invoke
88
+ Rake::Task['tx:update_po'].invoke
89
+ Rake::Task['tx:all_mo'].invoke
90
+ locale_dir = File.expand_path(@domain.locale_dir, __dir__)
91
+ sh "git add #{locale_dir}"
92
+ sh 'git commit -m "i18n - extracting new, pulling from tx"'
93
+ puts 'Changes commited!'
94
+ end
95
+
96
+ desc 'Check for malformed strings'
97
+ task :check do
98
+ raise 'Command pofilter not found. Make sure you have translate-toolkit installed.' unless system("command -v pofilter >/dev/null 2>&1")
99
+
100
+ po_files = Dir.glob(File.join(@domain.locale_dir, '**',"#{@domain.domain_name}.po"))
101
+ po_files.each do |po_file|
102
+ pox_file = po_file.gsub('.po', '.pox')
103
+ sh "msgfmt -c #{po_file}"
104
+ sh "pofilter --nofuzzy -t variables -t blank -t urls -t emails -t long -t newlines -t endwhitespace -t endpunc \
105
+ -t puncspacing -t options -t printf -t validchars --gnome #{po_file} > #{pox_file};"
106
+ sh("! grep -q msgid #{pox_file}") do |ok, _|
107
+ sh "cat #{pox_file}" unless ok
108
+ abort "See errors above for #{pox_file}."
109
+ end
110
+ end
111
+ end
112
+
113
+ desc 'Clean everything, removes *.edit.po, *.po.timestamp and *.pox files'
114
+ task :clean do
115
+ edit_files = Dir.glob(File.join(@domain.locale_dir, '**', '*.edit.po'))
116
+ timestamp_files = Dir.glob(File.join(@domain.locale_dir, '**', '*.po.time_stamp'))
117
+ pox_files = Dir.glob(File.join(@domain.locale_dir, '**', '*.pox'))
118
+ messages_file = Dir.glob(File.join(@domain.locale_dir, '..', 'messages.mo'))
119
+ FileUtils.rm_f(edit_files + timestamp_files + pox_files + messages_file)
120
+ end
33
121
  end
34
122
  end
35
123
 
@@ -137,6 +137,10 @@ module HammerCLI
137
137
  File.expand_path(File.join(File.dirname(__FILE__), '../../locale/Makefile.def'))
138
138
  end
139
139
 
140
+ def self.find_by_name(name)
141
+ domains.find { |domain| domain.class.to_s.split('::').first.underscore == name }
142
+ end
143
+
140
144
  init
141
145
  end
142
146
  end
@@ -54,7 +54,7 @@ module HammerCLI
54
54
  log_dir = File.expand_path(HammerCLI::Settings.get(:log_dir) || DEFAULT_LOG_DIR)
55
55
  begin
56
56
  FileUtils.mkdir_p(log_dir, :mode => 0750)
57
- rescue Errno::EACCES => e
57
+ rescue Errno::EACCES
58
58
  $stderr.puts _("No permissions to create log dir %s.") % log_dir
59
59
  end
60
60
 
@@ -68,7 +68,7 @@ module HammerCLI
68
68
  :size => (HammerCLI::Settings.get(:log_size) || 1)*1024*1024) # 1MB
69
69
  # set owner and group (it's ignored if attribute is nil)
70
70
  FileUtils.chown HammerCLI::Settings.get(:log_owner), HammerCLI::Settings.get(:log_group), filename
71
- rescue ArgumentError => e
71
+ rescue ArgumentError
72
72
  $stderr.puts _("File %s not writeable, won't log anything to the file!") % filename
73
73
  end
74
74
 
@@ -67,7 +67,7 @@ module HammerCLI
67
67
 
68
68
  def self.load(name)
69
69
  load! name
70
- rescue Exception => e
70
+ rescue Exception
71
71
  false
72
72
  end
73
73
 
@@ -50,9 +50,7 @@ module HammerCLI
50
50
  end
51
51
 
52
52
  class KeyValueList < AbstractNormalizer
53
-
54
- PAIR_RE = '([^,=]+)=([^,\{\[]+|[\{\[][^\{\}\[\]]*[\}\]])'
55
- FULL_RE = "^((%s)[,]?)+$" % PAIR_RE
53
+ FULL_RE = '([^=,]+)=([\{\[][^\{\}\[\]]*[\}\]]|[^\0]+?)(?=,[^,]+=|$)'
56
54
 
57
55
  class << self
58
56
  def completion_type
@@ -68,7 +66,6 @@ module HammerCLI
68
66
  def format(val)
69
67
  return {} unless val.is_a?(String)
70
68
  return {} if val.empty?
71
-
72
69
  if valid_key_value?(val)
73
70
  parse_key_value(val)
74
71
  else
@@ -89,7 +86,7 @@ module HammerCLI
89
86
 
90
87
  def parse_key_value(val)
91
88
  result = {}
92
- val.scan(Regexp.new(PAIR_RE)) do |key, value|
89
+ val.scan(Regexp.new(FULL_RE)) do |key, value|
93
90
  value = value.strip
94
91
  if value.start_with?('[')
95
92
  value = value.scan(/[^,\[\]]+/)
@@ -298,7 +295,7 @@ module HammerCLI
298
295
  json_string = ::File.exist?(::File.expand_path(val)) ? super(val) : val
299
296
  ::JSON.parse(json_string)
300
297
 
301
- rescue ::JSON::ParserError => e
298
+ rescue ::JSON::ParserError
302
299
  raise ArgumentError, _("Unable to parse JSON input.")
303
300
  end
304
301
 
@@ -368,7 +365,7 @@ module HammerCLI
368
365
 
369
366
  def format(date)
370
367
  raise ArgumentError unless date
371
- ::DateTime.parse(date).to_s
368
+ ::Time.parse(date).iso8601
372
369
  rescue ArgumentError
373
370
  raise ArgumentError, _("'%s' is not a valid date.") % date
374
371
  end
@@ -152,7 +152,7 @@ module HammerCLI
152
152
  end
153
153
 
154
154
  def run(&block)
155
- self.instance_eval &block
155
+ self.instance_eval(&block)
156
156
  end
157
157
  end
158
158
  end
@@ -94,7 +94,6 @@ module HammerCLI::Output::Adapter
94
94
  @name = nil
95
95
  @prefixes = []
96
96
  @suffixes = []
97
- @data
98
97
  end
99
98
 
100
99
  def append_suffix(suffix)
@@ -12,7 +12,7 @@ module HammerCLI::Output
12
12
  end
13
13
 
14
14
  def build(&block)
15
- self.instance_eval &block
15
+ self.instance_eval(&block)
16
16
  end
17
17
 
18
18
  protected
@@ -72,7 +72,7 @@ module Fields
72
72
  def initialize(options={}, &block)
73
73
  super(options)
74
74
  dsl = HammerCLI::Output::Dsl.new
75
- dsl.build &block if block_given?
75
+ dsl.build(&block) if block_given?
76
76
  dsl.fields.each { |f| f.parent = self }
77
77
  self.output_definition.append dsl.fields
78
78
  end
@@ -13,7 +13,7 @@ module HammerCLI::Output
13
13
 
14
14
  def register_formatter(type, *formatters)
15
15
  if @_formatters[type].nil?
16
- @_formatters[type] = FormatterContainer.new *formatters
16
+ @_formatters[type] = FormatterContainer.new(*formatters)
17
17
  else
18
18
  formatters.each { |f| @_formatters[type].add_formatter(f) }
19
19
  end
@@ -84,8 +84,8 @@ module HammerCLI::Output
84
84
  tags.map { |t| HammerCLI::Output::Utils.tag_to_feature(t) }
85
85
  end
86
86
 
87
- def format(data, field_params={})
88
- c = HighLine.color(data.to_s, @color)
87
+ def format(data, _={})
88
+ HighLine.color(data.to_s, @color)
89
89
  end
90
90
  end
91
91
 
@@ -97,7 +97,7 @@ module HammerCLI::Output
97
97
  tags.map { |t| HammerCLI::Output::Utils.tag_to_feature(t) }
98
98
  end
99
99
 
100
- def format(string_date, field_params={})
100
+ def format(string_date, _={})
101
101
  t = DateTime.parse(string_date.to_s)
102
102
  t.strftime("%Y/%m/%d %H:%M:%S")
103
103
  rescue ArgumentError
@@ -4,6 +4,8 @@ require 'logging'
4
4
  module HammerCLI
5
5
 
6
6
  class Settings
7
+ CFG_PATH = ['~/.hammer/', '/etc/hammer/', "#{::RbConfig::CONFIG['sysconfdir']}/hammer/"].uniq
8
+ CFG_PATH_LOCAL = ['./config/']
7
9
 
8
10
  def self.get(*keys)
9
11
  keys.inject(settings) do |value, key|
@@ -41,6 +43,11 @@ module HammerCLI
41
43
  end
42
44
  end
43
45
 
46
+ def self.load_from_defaults
47
+ load_from_paths CFG_PATH
48
+ load_from_paths CFG_PATH_LOCAL
49
+ end
50
+
44
51
  def self.load(settings_hash)
45
52
  deep_merge!(settings, settings_hash)
46
53
  end
@@ -68,13 +68,13 @@ module HammerCLI
68
68
 
69
69
  def read_certificate(path)
70
70
  OpenSSL::X509::Certificate.new(File.read(path)) unless path.nil?
71
- rescue SystemCallError => e
71
+ rescue SystemCallError
72
72
  warn _("Could't read SSL client certificate %s.") % path
73
73
  end
74
74
 
75
75
  def read_key(path)
76
- OpenSSL::PKey::RSA.new(File.read(path)) unless path.nil?
77
- rescue SystemCallError => e
76
+ OpenSSL::PKey.read(File.read(path)) unless path.nil?
77
+ rescue SystemCallError
78
78
  warn _("Could't read SSL client key %s.") % path
79
79
  end
80
80
  end
@@ -11,6 +11,7 @@ module HammerCLI
11
11
  @subcommand_class = subcommand_class
12
12
  @hidden = options[:hidden]
13
13
  @warning = options[:warning]
14
+ super(@names, @description, @subcommand_class)
14
15
  end
15
16
 
16
17
  def hidden?
@@ -0,0 +1,84 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+ require 'openssl'
4
+ require 'json'
5
+
6
+ module HammerCLI
7
+ module TaskHelper
8
+ module I18n
9
+ class TxApiClient
10
+ class GeneralError < StandardError
11
+ def initialize(error)
12
+ msg = case error
13
+ when Hash
14
+ "#{error['title']}: #{error['detail']}"
15
+ when Array
16
+ error.join("\n")
17
+ else
18
+ error.to_s
19
+ end
20
+ super(msg)
21
+ end
22
+ end
23
+
24
+ TX_CONFIG_RC_FILE = '~/.transifexrc'
25
+ TX_BASE_API_URL = 'https://rest.api.transifex.com'
26
+
27
+ def initialize(domain:)
28
+ @domain = domain
29
+ end
30
+
31
+ def language_stats_collection
32
+ make_call(
33
+ path: '/resource_language_stats',
34
+ params: {
35
+ 'filter[project]' => 'o:foreman:p:foreman',
36
+ 'filter[resource]' => "o:foreman:p:foreman:r:#{@domain.domain_name}"
37
+ }
38
+ )
39
+ end
40
+
41
+ private
42
+
43
+ def make_call(path:, params: {}, http_method: :GET, content_type: 'application/vnd.api+json', body: nil)
44
+ url = URI(TX_BASE_API_URL + path)
45
+ url.query = URI.encode_www_form(params)
46
+
47
+ body = Net::HTTP.start(url.host, url.port, use_ssl: true) do |https|
48
+ request = Object.const_get("Net::HTTP::#{http_method.to_s.capitalize}").new(url)
49
+ request["accept"] = 'application/vnd.api+json'
50
+ request["content-type"] = content_type
51
+ request["authorization"] = "Bearer #{api_token}"
52
+ request.body = body
53
+
54
+ response = https.request(request).read_body
55
+ JSON.parse(response) rescue { 'errors' => ['Could not parse response']}
56
+ end
57
+ return body unless body['errors']
58
+
59
+ raise GeneralError.new(body['errors']&.first)
60
+ end
61
+
62
+ def api_token
63
+ return ENV['TX_TOKEN'] if ENV['TX_TOKEN']
64
+
65
+ token = nil
66
+ config_file = File.expand_path(TX_CONFIG_RC_FILE)
67
+ if File.exist?(config_file)
68
+ File.open(config_file) do |file|
69
+ file.find do |line|
70
+ match = line.match(/^(?<type>token|password)\s*=\s*(?<token>\S+)$/)
71
+ next unless match
72
+
73
+ token = match[:token]
74
+ end
75
+ end
76
+ end
77
+ raise GeneralError.new("Could not find API token. Set it in #{config_file} or TX_TOKEN.") unless token
78
+
79
+ token
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -2,7 +2,7 @@ module HammerCLI
2
2
  module Testing
3
3
  module OutputMatchers
4
4
  class MatcherBase
5
- include MiniTest::Assertions
5
+ include Minitest::Assertions
6
6
 
7
7
  def initialize(expected="")
8
8
  @expected = expected
@@ -6,7 +6,7 @@ class String
6
6
  if params.is_a? Hash
7
7
  array_params = self.scan(/%[<{]([^>}]*)[>}]/).collect do |name|
8
8
  name = name[0]
9
- params[name.to_s] || params[name.to_sym]
9
+ !params[name.to_s].nil? ? params[name.to_s].to_s : params[name.to_sym].to_s
10
10
  end
11
11
  self.gsub(/%[<]([^>]*)[>]/, '%')
12
12
  .gsub(/%[{]([^}]*)[}]/, '%s')
@@ -48,18 +48,6 @@ class String
48
48
  end
49
49
  end
50
50
 
51
- class Hash
52
- # for ruby < 2.5.0
53
- def transform_keys
54
- result = {}
55
- each do |key, value|
56
- new_key = yield key
57
- result[new_key] = value
58
- end
59
- result
60
- end
61
- end
62
-
63
51
  module HammerCLI
64
52
 
65
53
  def self.tty?
@@ -1,5 +1,5 @@
1
1
  module HammerCLI
2
2
  def self.version
3
- @version ||= Gem::Version.new "3.6.0"
3
+ @version ||= Gem::Version.new "3.8.0"
4
4
  end
5
5
  end
data/locale/Makefile.def CHANGED
@@ -3,7 +3,19 @@
3
3
  #
4
4
  # Run make help to list available targets
5
5
  #
6
-
6
+ define DOMAIN_CMD
7
+ require "rubygems";
8
+ require "hammer_cli";
9
+ HammerCLI::Settings.load_from_defaults;
10
+ HammerCLI::Modules.load_all;
11
+ spec = Gem::Specification::load(Dir.glob("../*.gemspec").first);
12
+ i18n_domain = spec.respond_to?(:metadata) && spec.metadata["i18n_domain"];
13
+ puts i18n_domain || HammerCLI::I18n.find_by_name(spec.name)&.domain_name || spec.name
14
+ endef
15
+ ifeq ($(origin DOMAIN), undefined)
16
+ DOMAIN := $(shell bundle exec ruby -e '$(DOMAIN_CMD)')
17
+ endif
18
+ VERSION = $(shell ruby -rrubygems -e 'puts Gem::Specification::load(Dir.glob("../*.gemspec").first).version')
7
19
  POTFILE = $(DOMAIN).pot
8
20
  MOFILE = $(DOMAIN).mo
9
21
  POFILES = $(shell find . -name '$(DOMAIN).po')
@@ -12,12 +24,17 @@ POXFILES = $(patsubst %.po,%.pox,$(POFILES))
12
24
  EDITFILES = $(patsubst %.po,%.edit.po,$(POFILES))
13
25
  TIMESTAMPFILES = $(patsubst %.po,%.po.time_stamp,$(POFILES))
14
26
 
15
- %.mo: %.po
16
- mkdir -p $(shell dirname $@)/LC_MESSAGES
17
- msgfmt -o $(shell dirname $@)/LC_MESSAGES/$(MOFILE) $<
27
+ .PHONY: vars
28
+ vars:
29
+ @echo VERSION: $(VERSION)
30
+ @echo DOMAIN: $(DOMAIN)
18
31
 
19
32
  .PHONY: all-mo
20
- all-mo: $(MOFILES) ## Generate MO files from PO files (default)
33
+ all-mo: ## Generate MO files from PO files (default)
34
+ for po_file in $(POFILES); do \
35
+ mkdir -p $$(dirname $$po_file)/LC_MESSAGES; \
36
+ msgfmt -o $$(dirname $$po_file)/LC_MESSAGES/$(MOFILE) $$po_file; \
37
+ done
21
38
 
22
39
  # Check for malformed strings
23
40
  %.pox: %.po
@@ -44,7 +61,7 @@ uniq-po: ## Unify duplicate translations in .po files
44
61
  .PHONY: tx-pull
45
62
  tx-pull: $(EDITFILES)
46
63
  @command -v tx >/dev/null 2>&1 || { echo "Command tx not found. Make sure you have transifex-client installed and configured." >&2; exit 1; }
47
- tx pull -f
64
+ cd .. && tx pull -f
48
65
  for f in $(EDITFILES); do \
49
66
  sed -i 's/^\("Project-Id-Version: \).*$$/\1$(DOMAIN) $(VERSION)\\n"/' $$f; \
50
67
  done
@@ -61,8 +78,13 @@ update-po:
61
78
  extract-strings:
62
79
  bundle exec rake gettext:find
63
80
 
81
+ # Check languages with 50% or more coverage and create needed files
82
+ .PHONY: find-new
83
+ find-new:
84
+ bundle exec rake gettext:find_new
85
+
64
86
  .PHONY: tx-update
65
- tx-update: extract-strings tx-pull update-po $(MOFILES) ## Download and merge translations from Transifex
87
+ tx-update: find-new extract-strings tx-pull update-po all-mo ## Download and merge translations from Transifex
66
88
  git add ../locale
67
89
  git commit -m "i18n - extracting new, pulling from tx"
68
90
  @echo Changes commited!
Binary file
Binary file
Binary file