hammer_cli 3.6.0 → 3.8.0

Sign up to get free protection for your applications and to get access to all the features.
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