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.
- checksums.yaml +4 -4
- data/bin/hammer +1 -6
- data/config/cli_config.template.yml +3 -3
- data/doc/release_notes.md +24 -0
- data/lib/hammer_cli/abstract.rb +1 -1
- data/lib/hammer_cli/defaults_commands.rb +0 -1
- data/lib/hammer_cli/help/builder.rb +7 -8
- data/lib/hammer_cli/i18n/find_task.rb +88 -0
- data/lib/hammer_cli/i18n.rb +4 -0
- data/lib/hammer_cli/logger.rb +2 -2
- data/lib/hammer_cli/modules.rb +1 -1
- data/lib/hammer_cli/options/normalizers.rb +4 -7
- data/lib/hammer_cli/options/validators/dsl.rb +1 -1
- data/lib/hammer_cli/output/adapter/csv.rb +0 -1
- data/lib/hammer_cli/output/dsl.rb +1 -1
- data/lib/hammer_cli/output/fields.rb +1 -1
- data/lib/hammer_cli/output/formatters.rb +4 -4
- data/lib/hammer_cli/settings.rb +7 -0
- data/lib/hammer_cli/ssloptions.rb +3 -3
- data/lib/hammer_cli/subcommand.rb +1 -0
- data/lib/hammer_cli/task_helper.rb +84 -0
- data/lib/hammer_cli/testing/output_matchers.rb +1 -1
- data/lib/hammer_cli/utils.rb +1 -13
- data/lib/hammer_cli/version.rb +1 -1
- data/locale/Makefile.def +29 -7
- data/locale/ca/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/cs_CZ/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/de/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/en/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/en_GB/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/es/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/fr/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/it/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/ja/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/ka/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/ko/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/pt_BR/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/ru/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/zh_CN/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/zh_TW/LC_MESSAGES/hammer-cli.mo +0 -0
- data/man/hammer.1.gz +0 -0
- data/test/functional/defaults_test.rb +0 -1
- data/test/functional/help_test.rb +1 -1
- data/test/test_helper.rb +1 -1
- data/test/unit/abstract_test.rb +54 -54
- data/test/unit/apipie/command_test.rb +27 -28
- data/test/unit/apipie/option_builder_test.rb +28 -28
- data/test/unit/apipie/option_definition_test.rb +6 -6
- data/test/unit/apipie/test_helper.rb +3 -0
- data/test/unit/bash_test.rb +21 -21
- data/test/unit/command_extensions_test.rb +68 -68
- data/test/unit/completer_test.rb +57 -57
- data/test/unit/csv_parser_test.rb +12 -12
- data/test/unit/defaults_test.rb +3 -3
- data/test/unit/exception_handler_test.rb +3 -3
- data/test/unit/help/builder_test.rb +7 -7
- data/test/unit/help/definition/abstract_item_test.rb +2 -2
- data/test/unit/help/definition/list_test.rb +2 -2
- data/test/unit/help/definition/note_test.rb +2 -2
- data/test/unit/help/definition/section_test.rb +2 -2
- data/test/unit/help/definition/text_test.rb +2 -2
- data/test/unit/help/definition_test.rb +36 -36
- data/test/unit/help/text_builder_test.rb +39 -39
- data/test/unit/history_test.rb +8 -8
- data/test/unit/i18n_test.rb +2 -2
- data/test/unit/logger_test.rb +3 -3
- data/test/unit/main_test.rb +7 -7
- data/test/unit/modules_test.rb +24 -25
- data/test/unit/option_builder_test.rb +1 -1
- data/test/unit/options/matcher_test.rb +15 -15
- data/test/unit/options/normalizers_test.rb +92 -88
- data/test/unit/options/option_definition_test.rb +13 -13
- data/test/unit/options/option_family_test.rb +7 -7
- data/test/unit/options/sources/saved_defaults_test.rb +0 -4
- data/test/unit/options/validators/dsl_test.rb +35 -35
- data/test/unit/output/adapter/abstract_test.rb +13 -13
- data/test/unit/output/adapter/base_test.rb +36 -36
- data/test/unit/output/adapter/csv_test.rb +44 -44
- data/test/unit/output/adapter/json_test.rb +38 -38
- data/test/unit/output/adapter/table_test.rb +47 -55
- data/test/unit/output/adapter/yaml_test.rb +38 -38
- data/test/unit/output/definition_test.rb +43 -43
- data/test/unit/output/dsl_test.rb +19 -19
- data/test/unit/output/field_filter_test.rb +10 -10
- data/test/unit/output/fields_test.rb +27 -27
- data/test/unit/output/formatters_test.rb +39 -39
- data/test/unit/output/output_test.rb +14 -14
- data/test/unit/output/record_collection_test.rb +18 -18
- data/test/unit/settings_test.rb +35 -35
- data/test/unit/utils_test.rb +30 -27
- metadata +10 -21
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9c1d1eca37ea41bee11e7826fbfc491b99bce78026eee0f3ae72acaa2b472503
|
|
4
|
+
data.tar.gz: f327b7901efa9824e5118ac7e20daa42835e8d01813be55e2db4001697249a39
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
#
|
|
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
|
-
|
|
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
|
data/lib/hammer_cli/abstract.rb
CHANGED
|
@@ -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
|
|
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 '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
|
-
|
|
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
|
-
|
|
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(/^(.)/) {
|
|
50
|
-
|
|
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
|
-
|
|
58
|
-
|
|
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
|
-
|
|
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
|
|
data/lib/hammer_cli/i18n.rb
CHANGED
|
@@ -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
|
data/lib/hammer_cli/logger.rb
CHANGED
|
@@ -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
|
|
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
|
|
71
|
+
rescue ArgumentError
|
|
72
72
|
$stderr.puts _("File %s not writeable, won't log anything to the file!") % filename
|
|
73
73
|
end
|
|
74
74
|
|
data/lib/hammer_cli/modules.rb
CHANGED
|
@@ -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(
|
|
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
|
|
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
|
-
::
|
|
368
|
+
::Time.parse(date).iso8601
|
|
372
369
|
rescue ArgumentError
|
|
373
370
|
raise ArgumentError, _("'%s' is not a valid date.") % date
|
|
374
371
|
end
|
|
@@ -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
|
|
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
|
|
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,
|
|
88
|
-
|
|
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,
|
|
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
|
data/lib/hammer_cli/settings.rb
CHANGED
|
@@ -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
|
|
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
|
|
77
|
-
rescue SystemCallError
|
|
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
|
|
@@ -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
|
data/lib/hammer_cli/utils.rb
CHANGED
|
@@ -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]
|
|
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?
|
data/lib/hammer_cli/version.rb
CHANGED
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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
27
|
+
.PHONY: vars
|
|
28
|
+
vars:
|
|
29
|
+
@echo VERSION: $(VERSION)
|
|
30
|
+
@echo DOMAIN: $(DOMAIN)
|
|
18
31
|
|
|
19
32
|
.PHONY: all-mo
|
|
20
|
-
all-mo:
|
|
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
|
|
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
|
|
Binary file
|