hammer_cli_experimental 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ce65cc720807a281e46c4040d26602640d3387fa
4
+ data.tar.gz: b58b3bb257e583f7f75e455c4e8a38c83d9e4944
5
+ SHA512:
6
+ metadata.gz: d2e54f0104b094effe7a5b540722f747231448cef746b77b4a102adf249cf8fd541a9b772562b99a4bc877f9892a996a6c21d7851d10fe8bde03da7f69d2b716
7
+ data.tar.gz: b8ed54a79984674b8574285f5194a5a5c1c46c1708fe07c5d5443cfbe8cc0d9e57bca5a35070f3416cf0b828683c35aed77df7a07ff0be0ab3d194fd8e00ccbc
data/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # Experimental features for Hammer CLI
2
+
3
+ A hammer-cli plugin that contains features not mature enough to be merged into the core.
4
+
5
+ If you have a prototype of a feature which is either not completely stable or you're not sure if it's interesting for users and worth finishing, this is the right place to keep such code. The repository is open for innovative ideas. The only rule is that it must be possible to turn the feature off in the configuration.
6
+
7
+
8
+ ## Current features
9
+
10
+ ### Config command
11
+
12
+ A command for printing current hammer configuration. It can print config values split by the file it comes from or the final config mix.
13
+
14
+ ```
15
+ $ hammer config -h
16
+ Usage:
17
+ hammer config [OPTIONS]
18
+
19
+ Options:
20
+ --paths Show only used paths
21
+ --show List final configuration
22
+ --show-by-path List configurations from each of used files
23
+ -h, --help print help
24
+ ```
25
+
26
+ You can turn it on by following setting:
27
+ ```yaml
28
+ # Enable config command
29
+ :enable_config_command: true
30
+ ```
31
+
32
+ ### Fuzzy matching of subcommands
33
+
34
+ Enables using shortened versions of subcommend names as long as it matches only one subcommand.
35
+ Eg. `hammer org list`.
36
+
37
+ It also adds aliases of the most common commands:
38
+ ```
39
+ index -> list
40
+ show -> info
41
+ destroy -> delete
42
+ ```
43
+
44
+ You can turn it on by following setting:
45
+ ```yaml
46
+ # Enable fuzzy matching of subcommands
47
+ :enable_fuzzy_subcommands: true
48
+ ```
49
+
50
+ ### Enable full-help command
51
+
52
+ Adds a command for printing help for all hammer commands. It supports either plaintext or markdown format.
53
+
54
+ ```
55
+ $ hammer full-help -h
56
+ Usage:
57
+ hammer full-help [OPTIONS]
58
+
59
+ Options:
60
+ --md Format output in markdown
61
+ -h, --help print help
62
+
63
+ ```
64
+
65
+ You can turn it on by following setting:
66
+ ```yaml
67
+ # Enable full-help command
68
+ :enable_full_help_command: true
69
+ ```
70
+
71
+ ### Condensed help
72
+
73
+ Squeeze options that reference the same resource with different identifiers, eg. `--organization[-id|-label]`. Highly experimental.
74
+
75
+ You can turn it on by following setting:
76
+ ```yaml
77
+ # Enable condensed help, highly experimental
78
+ :enable_help: true
79
+ ```
80
+
81
+ ## License
82
+
83
+ This project is licensed under the GPLv3+.
@@ -0,0 +1,15 @@
1
+ :experimental:
2
+ # Enable/disable foreman commands
3
+ :enable_module: true
4
+
5
+ # Enable condensed help, highly experimental
6
+ :enable_help: false
7
+
8
+ # Enable config command
9
+ :enable_config_command: false
10
+
11
+ # Enable fuzzy matching of subcommands
12
+ :enable_fuzzy_subcommands: false
13
+
14
+ # Enable full-help command
15
+ :enable_full_help_command: false
@@ -0,0 +1,9 @@
1
+ require 'hammer_cli'
2
+
3
+ module HammerCLIExperimental
4
+
5
+ require 'hammer_cli_experimental/help' if HammerCLI::Settings.get(:experimental, :enable_help)
6
+ require 'hammer_cli_experimental/config' if HammerCLI::Settings.get(:experimental, :enable_config_command)
7
+ require 'hammer_cli_experimental/subcommands' if HammerCLI::Settings.get(:experimental, :enable_fuzzy_subcommands)
8
+ require 'hammer_cli_experimental/full_help' if HammerCLI::Settings.get(:experimental, :enable_full_help_command)
9
+ end
@@ -0,0 +1,36 @@
1
+ require 'hammer_cli/abstract'
2
+
3
+ module HammerCLIExperimental
4
+ class ConfigCommand < HammerCLI::AbstractCommand
5
+
6
+ option '--paths', :flag, _("Show only used paths")
7
+ option '--show', :flag, _("List final configuration")
8
+ option '--show-by-path', :flag, _("List configurations from each of used files")
9
+
10
+ def validate_options
11
+ validator.one_of(:option_paths, :option_show, :option_show_by_path).required
12
+ end
13
+
14
+ def execute
15
+ if option_paths?
16
+ puts settings.path_history
17
+ elsif option_show?
18
+ puts settings.settings.to_yaml
19
+ elsif option_show_by_path?
20
+ settings.path_history.each do |cfg_file|
21
+ puts cfg_file
22
+ puts YAML::load(File.open(cfg_file)).to_yaml
23
+ puts
24
+ end
25
+ end
26
+ HammerCLI::EX_OK
27
+ end
28
+
29
+ protected
30
+ def settings
31
+ HammerCLI::Settings
32
+ end
33
+ end
34
+
35
+ HammerCLI::MainCommand.subcommand "config", _("Print current hammer config"), HammerCLIExperimental::ConfigCommand
36
+ end
@@ -0,0 +1,85 @@
1
+ require 'hammer_cli/abstract'
2
+
3
+ module HammerCLIExperimental
4
+ class FullHelpCommand < HammerCLI::AbstractCommand
5
+ option "--md", :flag, _("Format output in markdown")
6
+
7
+ def execute
8
+ @adapter = option_md? ? MDAdapter.new : TxtAdapter.new
9
+ print_heading
10
+ print_help
11
+ HammerCLI::EX_OK
12
+ end
13
+
14
+ private
15
+
16
+ def print_heading
17
+ @adapter.print_heading('Hammer CLI help')
18
+ @adapter.print_toc(HammerCLI::MainCommand)
19
+ end
20
+
21
+ def print_help(name='hammer', command=HammerCLI::MainCommand, desc='')
22
+ @adapter.print_command(name, desc, command.new(name).help)
23
+
24
+ command.recognised_subcommands.each do |sub_cmd|
25
+ print_help(@adapter.command_name(name, sub_cmd.names.first), sub_cmd.subcommand_class, sub_cmd.description)
26
+ end
27
+ end
28
+
29
+ class MDAdapter
30
+ def command_name(parent, command_name)
31
+ "#{parent} #{command_name}"
32
+ end
33
+
34
+ def print_command(name, description, help)
35
+ print_heading(name, name.split.length)
36
+ puts description
37
+ puts
38
+ puts "```"
39
+ puts help
40
+ puts "```"
41
+ puts
42
+ end
43
+
44
+ def print_toc(cmd)
45
+ names = cmd.recognised_subcommands.collect do |sub_cmd|
46
+ sub_cmd.names[0]
47
+ end
48
+ names.sort.each do |name|
49
+ puts "- [%s](#hammer-%s)" % [name, name.gsub(' ', '-')]
50
+ end
51
+ puts
52
+ end
53
+
54
+ def print_heading(text, level=1)
55
+ puts '#'*level + ' ' + text
56
+ end
57
+ end
58
+
59
+
60
+ class TxtAdapter
61
+ def command_name(parent, command_name)
62
+ "#{parent} > #{command_name}"
63
+ end
64
+
65
+ def print_command(name, description, help)
66
+ print_heading(name, 2)
67
+ puts description
68
+ puts
69
+ puts help
70
+ puts
71
+ end
72
+
73
+ def print_toc(cmd)
74
+ end
75
+
76
+ def print_heading(text, level=1)
77
+ ch = (level > 1) ? '-' : '='
78
+ puts text
79
+ puts ch * text.length
80
+ end
81
+ end
82
+ end
83
+
84
+ HammerCLI::MainCommand.subcommand "full-help", _("Print help for all hammer commands"), HammerCLIExperimental::FullHelpCommand
85
+ end
@@ -0,0 +1,143 @@
1
+ require 'colorize'
2
+
3
+ module HammerCLIExperimental
4
+
5
+ class CondensedBuilder < HammerCLI::Help::Builder
6
+
7
+ def default_label_indent
8
+ 29
9
+ end
10
+
11
+ def add_list(heading, items)
12
+ if is_option_list?(items)
13
+ add_option_list(heading, items)
14
+ else
15
+ super
16
+ end
17
+ end
18
+
19
+ def add_option_list(heading, items)
20
+ collect_squeezable_names(items)
21
+
22
+ items = squeeze_option_flags(items)
23
+ items.sort! do |a, b|
24
+ a[0] <=> b[0]
25
+ end
26
+
27
+ puts
28
+ heading(heading)
29
+
30
+ label_width = default_label_indent
31
+ items.each do |item|
32
+ label, description = item
33
+ label_width = label.size if label.size > label_width
34
+ end
35
+
36
+ items.each do |item|
37
+ label, description = item
38
+ description.each_line do |line|
39
+ puts " %-#{label_width}s %s" % [label, line]
40
+ label = ''
41
+ end
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ STATIC_RESOURCES = [
48
+ 'owner',
49
+ 'puppet_class'
50
+ ]
51
+
52
+ def collect_squeezable_names(items)
53
+ @squeezable_names = items.map do |i|
54
+ i.referenced_resource if i.respond_to? :referenced_resource
55
+ end.compact
56
+ @squeezable_names += STATIC_RESOURCES
57
+ @squeezable_names = @squeezable_names.uniq
58
+ end
59
+
60
+ attr_reader :squeezable_names
61
+
62
+ def squeeze_option_flags(items)
63
+ help_items = []
64
+ squeezable_names.each do |resource_name|
65
+ selected = select_options_for_resource(resource_name, items)
66
+ next if selected.empty?
67
+ items -= selected
68
+ help_items += squeezed_help(selected)
69
+ end
70
+ help_items += items.map do |i|
71
+ [i.help[0], i.help[1].capitalize] if !is_squeezable?(i)
72
+ end.compact
73
+ help_items
74
+ end
75
+
76
+ def select_options_for_resource(resource_name, options)
77
+ result = options.select { |opt| opt.respond_to?(:referenced_resource) && (opt.referenced_resource == resource_name) }
78
+ if result.count <= 1
79
+ result = options.select { |opt| opt.switches[0].start_with?("--#{resource_name.gsub('_', '-')}") }
80
+ result.each { |opt| opt.referenced_resource = resource_name }
81
+ end
82
+ result
83
+ end
84
+
85
+ def squeezed_help(options)
86
+ prefix = common_prefix(options.map { |opt| opt.switches[0] })
87
+ if prefix == '--'
88
+ # return help for the original options when there's no common prefix
89
+ return options.map { |opt| [opt.help[0], opt.help[1]] }
90
+ end
91
+
92
+ appendix_items = options.map do |opt|
93
+ opt.switches[0][prefix.length, opt.switches[0].length]
94
+ end
95
+ appendix_items = appendix_items.select { |i| !i.empty? }
96
+
97
+ if !appendix_items.empty?
98
+ appendix = ('[' + appendix_items.join('|') + ']').yellow
99
+ # length of colors gets calculated wrong, we need padding to workaround the problem
100
+ padding = ' ' * 14
101
+ end
102
+
103
+ resource_name = options[0].referenced_resource
104
+ if options.find{|opt| opt.type.end_with?('_IDS')}
105
+ resource_name = ApipieBindings::Inflector.pluralize(resource_name)
106
+ end
107
+
108
+ # TODO: translate the description
109
+ type = resource_name.upcase
110
+ desc = resource_name.gsub('_', ' ').capitalize
111
+
112
+ [["#{prefix}#{appendix} #{type}", "#{padding}#{desc}"]]
113
+ end
114
+
115
+ def common_prefix(items)
116
+ shortest_length = items.map(&:length).min
117
+ i = 0
118
+ while (i < shortest_length) && chars_equal(i, items)
119
+ i += 1
120
+ end
121
+ items[0][0, i]
122
+ end
123
+
124
+ def chars_equal(index, items)
125
+ items.map {|i| i[index] }.uniq.length == 1
126
+ end
127
+
128
+ def is_squeezable?(item)
129
+ item.respond_to?(:referenced_resource) && item.referenced_resource
130
+ end
131
+
132
+ def is_option_list?(items)
133
+ (items.size > 0) && (items[0].is_a?(Clamp::Option::Definition))
134
+ end
135
+ end
136
+ end
137
+
138
+
139
+ class HammerCLI::AbstractCommand
140
+ def help
141
+ self.class.help(invocation_path, HammerCLIExperimental::CondensedBuilder.new(context[:is_tty?]))
142
+ end
143
+ end
@@ -0,0 +1,29 @@
1
+ require 'hammer_cli/abstract'
2
+
3
+ module HammerCLIExperimental
4
+ module Subcommands
5
+ def find_subcommand(name)
6
+ subcommand = super
7
+ if subcommand.nil?
8
+ case name
9
+ when 'index'
10
+ name = 'list'
11
+ when 'show'
12
+ name = 'info'
13
+ when 'destroy'
14
+ name = 'delete'
15
+ end
16
+ find_subcommand_starting_with(name)
17
+ else
18
+ subcommand
19
+ end
20
+ end
21
+
22
+ def find_subcommand_starting_with(name)
23
+ subcommands = recognised_subcommands.select { |sc| sc.names.any? { |n| n.start_with?(name) } }
24
+ subcommands[0] if subcommands.length == 1
25
+ end
26
+ end
27
+ end
28
+
29
+ HammerCLI::AbstractCommand.extend(HammerCLIExperimental::Subcommands)
@@ -0,0 +1,5 @@
1
+ module HammerCLIExperimental
2
+ def self.version
3
+ @version ||= Gem::Version.new '0.0.1'
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hammer_cli_experimental
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Tomáš Strachota
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-06-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: hammer_cli
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.4.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.4.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: colorize
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: 'Experimental extensions for Hammer CLI
42
+
43
+ '
44
+ email: tstracho@redhat.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files:
48
+ - README.md
49
+ files:
50
+ - README.md
51
+ - config/experimental.yml
52
+ - lib/hammer_cli_experimental.rb
53
+ - lib/hammer_cli_experimental/config.rb
54
+ - lib/hammer_cli_experimental/full_help.rb
55
+ - lib/hammer_cli_experimental/help.rb
56
+ - lib/hammer_cli_experimental/subcommands.rb
57
+ - lib/hammer_cli_experimental/version.rb
58
+ homepage: http://github.com/tstrachota/hammer-cli-experimental
59
+ licenses:
60
+ - GPL v3+
61
+ metadata: {}
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 2.5.1
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: Experimental extensions for Hammer CLI
82
+ test_files: []