command_kit 0.4.0 → 0.5.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/.github/workflows/ruby.yml +2 -0
- data/.rubocop.yml +3 -0
- data/ChangeLog.md +18 -0
- data/LICENSE.txt +1 -1
- data/README.md +4 -1
- data/command_kit.gemspec +7 -2
- data/examples/subcommands/cli/config/get.rb +47 -0
- data/examples/subcommands/cli/config/set.rb +44 -0
- data/examples/subcommands/cli/config.rb +23 -0
- data/examples/subcommands/cli/list.rb +35 -0
- data/examples/subcommands/cli/update.rb +47 -0
- data/examples/subcommands/cli.rb +55 -0
- data/lib/command_kit/completion/install.rb +276 -0
- data/lib/command_kit/env/home.rb +1 -1
- data/lib/command_kit/env/prefix.rb +41 -0
- data/lib/command_kit/env/shell.rb +58 -0
- data/lib/command_kit/inflector.rb +1 -1
- data/lib/command_kit/options/parser.rb +1 -1
- data/lib/command_kit/os/linux.rb +1 -1
- data/lib/command_kit/os.rb +1 -1
- data/lib/command_kit/printing/tables/table_formatter.rb +2 -2
- data/lib/command_kit/version.rb +1 -1
- data/lib/command_kit/xdg.rb +1 -1
- metadata +12 -66
- data/spec/arguments/argument_spec.rb +0 -133
- data/spec/arguments/argument_value_spec.rb +0 -66
- data/spec/arguments_spec.rb +0 -279
- data/spec/bug_report_spec.rb +0 -266
- data/spec/colors_spec.rb +0 -771
- data/spec/command_kit_spec.rb +0 -8
- data/spec/command_name_spec.rb +0 -130
- data/spec/command_spec.rb +0 -123
- data/spec/commands/auto_load/subcommand_spec.rb +0 -82
- data/spec/commands/auto_load_spec.rb +0 -159
- data/spec/commands/auto_require_spec.rb +0 -142
- data/spec/commands/fixtures/test_auto_load/cli/commands/test1.rb +0 -10
- data/spec/commands/fixtures/test_auto_load/cli/commands/test2.rb +0 -10
- data/spec/commands/fixtures/test_auto_require/lib/test_auto_require/cli/commands/test1.rb +0 -10
- data/spec/commands/help_spec.rb +0 -66
- data/spec/commands/parent_command_spec.rb +0 -40
- data/spec/commands/subcommand_spec.rb +0 -99
- data/spec/commands_spec.rb +0 -839
- data/spec/description_spec.rb +0 -179
- data/spec/edit_spec.rb +0 -72
- data/spec/env/home_spec.rb +0 -46
- data/spec/env/path_spec.rb +0 -84
- data/spec/env_spec.rb +0 -123
- data/spec/examples_spec.rb +0 -211
- data/spec/exception_handler_spec.rb +0 -103
- data/spec/file_utils_spec.rb +0 -59
- data/spec/fixtures/template.erb +0 -5
- data/spec/help/man_spec.rb +0 -345
- data/spec/help_spec.rb +0 -94
- data/spec/inflector_spec.rb +0 -166
- data/spec/interactive_spec.rb +0 -415
- data/spec/main_spec.rb +0 -179
- data/spec/man_spec.rb +0 -46
- data/spec/open_app_spec.rb +0 -85
- data/spec/options/option_spec.rb +0 -343
- data/spec/options/option_value_spec.rb +0 -171
- data/spec/options/parser_spec.rb +0 -255
- data/spec/options/quiet_spec.rb +0 -51
- data/spec/options/verbose_spec.rb +0 -51
- data/spec/options/version_spec.rb +0 -146
- data/spec/options_spec.rb +0 -465
- data/spec/os/linux_spec.rb +0 -164
- data/spec/os_spec.rb +0 -233
- data/spec/package_manager_spec.rb +0 -806
- data/spec/pager_spec.rb +0 -217
- data/spec/printing/fields_spec.rb +0 -167
- data/spec/printing/indent_spec.rb +0 -132
- data/spec/printing/lists_spec.rb +0 -99
- data/spec/printing/tables/border_style.rb +0 -43
- data/spec/printing/tables/cell_builer_spec.rb +0 -135
- data/spec/printing/tables/row_builder_spec.rb +0 -165
- data/spec/printing/tables/style_spec.rb +0 -377
- data/spec/printing/tables/table_builder_spec.rb +0 -252
- data/spec/printing/tables/table_formatter_spec.rb +0 -1180
- data/spec/printing/tables_spec.rb +0 -1069
- data/spec/printing_spec.rb +0 -106
- data/spec/program_name_spec.rb +0 -70
- data/spec/spec_helper.rb +0 -3
- data/spec/stdio_spec.rb +0 -264
- data/spec/sudo_spec.rb +0 -51
- data/spec/terminal_spec.rb +0 -231
- data/spec/usage_spec.rb +0 -237
- data/spec/xdg_spec.rb +0 -191
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f815869f166ce21da0c32699e8dcd7cebdb17cdbcc74fba1be3572ebb2d15a0
|
4
|
+
data.tar.gz: 2e2db9a8f190308d473959274dad507095baba55e0e73f7fcd969a4f23267054
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0055ba75d1dc4aef15bf280ed86f5d4a514e5e95c00bc1285c9f29327d5b03ab4415a6001bc4ee05be04bb5504b2d6a0a8de0d33f6048a1ea333adb93915f54
|
7
|
+
data.tar.gz: a198cc0fe966abb5f20f5025b52144bce290d06602e93afd13e2eca03d8aa87477511a598562f023ef921490084c200896c453e78b75d9061216dc8e548f923b
|
data/.github/workflows/ruby.yml
CHANGED
data/.rubocop.yml
CHANGED
@@ -152,3 +152,6 @@ Bundler/OrderedGems: { Enabled: false }
|
|
152
152
|
Layout/SpaceInsideArrayLiteralBrackets: { Enabled: false }
|
153
153
|
|
154
154
|
Naming/HeredocDelimiterNaming: { Enabled: false }
|
155
|
+
|
156
|
+
# I prefer to use explicit parenthesis for compound logical statements
|
157
|
+
Style/RedundantParentheses: { Enabled: false }
|
data/ChangeLog.md
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
### 0.5.0 / 2024-01-04
|
2
|
+
|
3
|
+
* Added {CommandKit::Env::Shell}.
|
4
|
+
* Added {CommandKit::Env::Prefix}.
|
5
|
+
* Added {CommandKit::Completion::Install}.
|
6
|
+
|
7
|
+
### 0.4.1 / 2024-01-03
|
8
|
+
|
9
|
+
* Added more examples of how to define sub-commands and sub-sub-commands.
|
10
|
+
|
11
|
+
#### CommandKit::Options::Parser
|
12
|
+
|
13
|
+
* Do not override the command's `usage` if it's already been set.
|
14
|
+
|
15
|
+
#### CommandKit::Printing::Tables
|
16
|
+
|
17
|
+
* Format the table output as UTF-8 to allow UTF-8 data in the formatted table.
|
18
|
+
|
1
19
|
### 0.4.0 / 2022-11-11
|
2
20
|
|
3
21
|
* Added {CommandKit::BugReport}.
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -214,11 +214,14 @@ end
|
|
214
214
|
* [CommandKit::Commands](https://rubydoc.info/gems/command_kit/CommandKit/Commands)
|
215
215
|
* [CommandKit::Commands::AutoLoad](https://rubydoc.info/gems/command_kit/CommandKit/Commands/AutoLoad)
|
216
216
|
* [CommandKit::Commands::AutoRequire](https://rubydoc.info/gems/command_kit/CommandKit/Commands/AutoRequire)
|
217
|
+
* [CommandKit::Completion::Install](https://rubydoc.info/gems/command_kit/CommandKit/Completion/Install)
|
217
218
|
* [CommandKit::Description](https://rubydoc.info/gems/command_kit/CommandKit/Description)
|
218
219
|
* [CommandKit::Edit](https://rubydoc.info/gems/command_kit/CommandKit/Edit)
|
219
220
|
* [CommandKit::Env](https://rubydoc.info/gems/command_kit/CommandKit/Env)
|
220
221
|
* [CommandKit::Env::Home](https://rubydoc.info/gems/command_kit/CommandKit/Env/Home)
|
221
222
|
* [CommandKit::Env::Path](https://rubydoc.info/gems/command_kit/CommandKit/Env/Path)
|
223
|
+
* [CommandKit::Env::Prefix](https://rubydoc.info/gems/command_kit/CommandKit/Env/Prefix)
|
224
|
+
* [CommandKit::Env::Shell](https://rubydoc.info/gems/command_kit/CommandKit/Env/Shell)
|
222
225
|
* [CommandKit::Examples](https://rubydoc.info/gems/command_kit/CommandKit/Examples)
|
223
226
|
* [CommandKit::ExceptionHandler](https://rubydoc.info/gems/command_kit/CommandKit/ExceptionHandler)
|
224
227
|
* [CommandKit::FileUtils](https://rubydoc.info/gems/command_kit/CommandKit/FileUtils)
|
@@ -253,7 +256,7 @@ Twitter.
|
|
253
256
|
|
254
257
|
## Copyright
|
255
258
|
|
256
|
-
Copyright (c) 2021-
|
259
|
+
Copyright (c) 2021-2024 Hal Brodigan
|
257
260
|
|
258
261
|
See {file:LICENSE.txt} for details.
|
259
262
|
|
data/command_kit.gemspec
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'yaml'
|
2
4
|
|
3
5
|
Gem::Specification.new do |gem|
|
@@ -20,12 +22,15 @@ Gem::Specification.new do |gem|
|
|
20
22
|
gem.homepage = gemspec['homepage']
|
21
23
|
gem.metadata = gemspec['metadata'] if gemspec['metadata']
|
22
24
|
|
23
|
-
glob =
|
25
|
+
glob = ->(patterns) { gem.files & Dir[*patterns] }
|
24
26
|
|
25
27
|
gem.files = if gemspec['files'] then glob[gemspec['files']]
|
26
28
|
else `git ls-files`.split($/)
|
27
29
|
end
|
28
30
|
|
31
|
+
# exclude test files from the packages gem
|
32
|
+
gem.files -= glob[gemspec['test_files'] || 'spec/{**/}*']
|
33
|
+
|
29
34
|
gem.executables = gemspec.fetch('executables') do
|
30
35
|
glob['bin/*'].map { |path| File.basename(path) }
|
31
36
|
end
|
@@ -43,7 +48,7 @@ Gem::Specification.new do |gem|
|
|
43
48
|
gem.required_rubygems_version = gemspec['required_rubygems_version']
|
44
49
|
gem.post_install_message = gemspec['post_install_message']
|
45
50
|
|
46
|
-
split =
|
51
|
+
split = ->(string) { string.split(/,\s*/) }
|
47
52
|
|
48
53
|
if gemspec['dependencies']
|
49
54
|
gemspec['dependencies'].each do |name,versions|
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'command_kit/command'
|
2
|
+
|
3
|
+
module Foo
|
4
|
+
class CLI
|
5
|
+
class Config < CommandKit::Command
|
6
|
+
#
|
7
|
+
# The `config get` sub-command.
|
8
|
+
#
|
9
|
+
class Get < CommandKit::Command
|
10
|
+
|
11
|
+
usage '[options] NAME'
|
12
|
+
|
13
|
+
argument :name, required: false,
|
14
|
+
desc: 'Configuration variable name'
|
15
|
+
|
16
|
+
description 'Gets a configuration variable'
|
17
|
+
|
18
|
+
CONFIG = {
|
19
|
+
'name' => 'John Smith',
|
20
|
+
'email' => 'john.smith@example.com'
|
21
|
+
}
|
22
|
+
|
23
|
+
#
|
24
|
+
# Runs the `config get` sub-command.
|
25
|
+
#
|
26
|
+
# @param [String, nil] name
|
27
|
+
# The optional name argument.
|
28
|
+
#
|
29
|
+
def run(name=nil)
|
30
|
+
if name
|
31
|
+
unless CONFIG.has_key?(name)
|
32
|
+
print_error "unknown config variable: #{name}"
|
33
|
+
exit(1)
|
34
|
+
end
|
35
|
+
|
36
|
+
puts CONFIG.fetch(name)
|
37
|
+
else
|
38
|
+
CONFIG.each do |name,value|
|
39
|
+
puts "#{name}:\t#{value}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'command_kit/command'
|
2
|
+
|
3
|
+
module Foo
|
4
|
+
class CLI
|
5
|
+
class Config < CommandKit::Command
|
6
|
+
#
|
7
|
+
# The `config set` sub-command.
|
8
|
+
#
|
9
|
+
class Set < CommandKit::Command
|
10
|
+
|
11
|
+
usage '[options] NAME'
|
12
|
+
|
13
|
+
argument :name, required: true,
|
14
|
+
desc: 'Configuration variable name to set'
|
15
|
+
|
16
|
+
argument :value, required: true,
|
17
|
+
desc: 'Configuration variable value to set'
|
18
|
+
|
19
|
+
description 'Sets a configuration variable'
|
20
|
+
|
21
|
+
CONFIG = {
|
22
|
+
'name' => 'John Smith',
|
23
|
+
'email' => 'john.smith@example.com'
|
24
|
+
}
|
25
|
+
|
26
|
+
#
|
27
|
+
# Runs the `config get` sub-command.
|
28
|
+
#
|
29
|
+
# @param [String] name
|
30
|
+
# The name argument.
|
31
|
+
#
|
32
|
+
def run(name,value)
|
33
|
+
unless CONFIG.has_key?(name)
|
34
|
+
print_error "unknown config variable: #{name}"
|
35
|
+
exit(1)
|
36
|
+
end
|
37
|
+
|
38
|
+
puts "Configuration variable #{name} was #{CONFIG.fetch(name)}, but is now #{value}"
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'command_kit/command'
|
2
|
+
require 'command_kit/commands'
|
3
|
+
|
4
|
+
require_relative 'config/get'
|
5
|
+
require_relative 'config/set'
|
6
|
+
|
7
|
+
module Foo
|
8
|
+
class CLI
|
9
|
+
#
|
10
|
+
# The `config` sub-command.
|
11
|
+
#
|
12
|
+
class Config < CommandKit::Command
|
13
|
+
|
14
|
+
include CommandKit::Commands
|
15
|
+
|
16
|
+
command Get
|
17
|
+
command Set
|
18
|
+
|
19
|
+
description 'Get or set the configuration'
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'command_kit/command'
|
2
|
+
|
3
|
+
module Foo
|
4
|
+
class CLI
|
5
|
+
#
|
6
|
+
# The `list` sub-command.
|
7
|
+
#
|
8
|
+
class List < CommandKit::Command
|
9
|
+
|
10
|
+
usage '[options] [NAME]'
|
11
|
+
|
12
|
+
argument :name, required: false,
|
13
|
+
desc: 'Optional name to list'
|
14
|
+
|
15
|
+
description 'Lists the contents'
|
16
|
+
|
17
|
+
ITEMS = %w[foo bar baz]
|
18
|
+
|
19
|
+
#
|
20
|
+
# Runs the `list` sub-command.
|
21
|
+
#
|
22
|
+
# @param [String, nil] name
|
23
|
+
# The optional name argument.
|
24
|
+
#
|
25
|
+
def run(name=nil)
|
26
|
+
if name
|
27
|
+
puts ITEMS.grep(name)
|
28
|
+
else
|
29
|
+
puts ITEMS
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'command_kit/command'
|
2
|
+
|
3
|
+
module Foo
|
4
|
+
class CLI
|
5
|
+
#
|
6
|
+
# The `update` sub-command.
|
7
|
+
#
|
8
|
+
class Update < CommandKit::Command
|
9
|
+
|
10
|
+
usage '[options] [NAME]'
|
11
|
+
|
12
|
+
option :quiet, short: '-q',
|
13
|
+
desc: 'Suppresses logging messages'
|
14
|
+
|
15
|
+
argument :name, required: false,
|
16
|
+
desc: 'Optional name to update'
|
17
|
+
|
18
|
+
description 'Updates an item or all items'
|
19
|
+
|
20
|
+
ITEMS = %w[foo bar baz]
|
21
|
+
|
22
|
+
#
|
23
|
+
# Runs the `update` sub-command.
|
24
|
+
#
|
25
|
+
# @param [String, nil] name
|
26
|
+
# The optional name argument.
|
27
|
+
#
|
28
|
+
def run(name=nil)
|
29
|
+
if name
|
30
|
+
unless ITEMS.include?(name)
|
31
|
+
print_error "unknown item: #{name}"
|
32
|
+
exit(1)
|
33
|
+
end
|
34
|
+
|
35
|
+
puts "Updating #{name} ..." unless options[:quiet]
|
36
|
+
sleep 1
|
37
|
+
puts "Item #{name} updated." unless options[:quiet]
|
38
|
+
else
|
39
|
+
puts "Updating ..." unless options[:quiet]
|
40
|
+
sleep 2
|
41
|
+
puts "All items updated." unless options[:quiet]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.expand_path('../../../lib',__FILE__))
|
4
|
+
|
5
|
+
require 'command_kit/commands'
|
6
|
+
|
7
|
+
require_relative 'cli/config'
|
8
|
+
require_relative 'cli/list'
|
9
|
+
require_relative 'cli/update'
|
10
|
+
|
11
|
+
module Foo
|
12
|
+
#
|
13
|
+
# The main CLI command.
|
14
|
+
#
|
15
|
+
class CLI
|
16
|
+
|
17
|
+
include CommandKit::Commands
|
18
|
+
|
19
|
+
class << self
|
20
|
+
# The global configuration file setting.
|
21
|
+
#
|
22
|
+
# @return [String, nil]
|
23
|
+
attr_accessor :config_file
|
24
|
+
end
|
25
|
+
|
26
|
+
command_name 'foo'
|
27
|
+
|
28
|
+
# Commands must be explicitly registered, unless
|
29
|
+
# CommandKit::Commands::AutoLoad.new(...) is included.
|
30
|
+
command Config
|
31
|
+
command List
|
32
|
+
command Update
|
33
|
+
|
34
|
+
# Commands may have aliases
|
35
|
+
command_aliases['ls'] = 'list'
|
36
|
+
command_aliases['up'] = 'update'
|
37
|
+
|
38
|
+
# Global options may be defined which are parsed before the sub-command's
|
39
|
+
# options are parsed and the sub-command is executed.
|
40
|
+
option :config_file, short: '-C',
|
41
|
+
value: {
|
42
|
+
type: String,
|
43
|
+
usage: 'FILE'
|
44
|
+
},
|
45
|
+
desc: 'Global option to set the config file' do |file|
|
46
|
+
CLI.config_file = file
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
if $0 == __FILE__
|
53
|
+
# Normally you would invoke Foo::CLI.start from a bin/ script.
|
54
|
+
Foo::CLI.start
|
55
|
+
end
|
@@ -0,0 +1,276 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'command_kit/printing'
|
4
|
+
require 'command_kit/env/home'
|
5
|
+
require 'command_kit/env/shell'
|
6
|
+
require 'command_kit/env/prefix'
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
module CommandKit
|
10
|
+
module Completion
|
11
|
+
#
|
12
|
+
# Mixins that adds methods for installing shell completion files.
|
13
|
+
#
|
14
|
+
# ## Environment Variables
|
15
|
+
#
|
16
|
+
# * `SHELL` - The current shell.
|
17
|
+
# * `PREFIX` - The optional root prefix of the file-system.
|
18
|
+
#
|
19
|
+
# @api public
|
20
|
+
#
|
21
|
+
# @since 0.5.0
|
22
|
+
#
|
23
|
+
module Install
|
24
|
+
include Printing
|
25
|
+
include Env::Home
|
26
|
+
include Env::Shell
|
27
|
+
include Env::Prefix
|
28
|
+
|
29
|
+
# The installation directory for completion files for the current shell.
|
30
|
+
#
|
31
|
+
# @return [String, nil]
|
32
|
+
# * Bash
|
33
|
+
# * Regular users: `~/.local/share/bash-completion/completions`
|
34
|
+
# * Root users:`$PREFIX/usr/local/share/bash-completion/completions`
|
35
|
+
# * Zsh: `$PREFIX/usr/local/share/zsh/site-functions`
|
36
|
+
# * Fish:
|
37
|
+
# * Regular users: `~/.config/fish/completions`
|
38
|
+
# * Root users: `$PREFIX/usr/local/share/fish/completions`
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
attr_reader :completions_dir
|
42
|
+
|
43
|
+
#
|
44
|
+
# Initialize {#completions_dir} based on the `SHELL` environment variable
|
45
|
+
# and the UID of the process.
|
46
|
+
#
|
47
|
+
# @param [Hash{Symbol => Object}] kwargs
|
48
|
+
# Additional keyword arguments.
|
49
|
+
#
|
50
|
+
# @api public
|
51
|
+
#
|
52
|
+
def initialize(**kwargs)
|
53
|
+
super(**kwargs)
|
54
|
+
|
55
|
+
@completions_dir = case shell_type
|
56
|
+
when :bash
|
57
|
+
if Process.uid == 0
|
58
|
+
File.join(root,'usr','local','share','bash-completion','completions')
|
59
|
+
else
|
60
|
+
xdg_data_home = env.fetch('XDG_DATA_HOME') do
|
61
|
+
File.join(home_dir,'.local','share')
|
62
|
+
end
|
63
|
+
|
64
|
+
File.join(xdg_data_home,'bash-completion','completions')
|
65
|
+
end
|
66
|
+
when :zsh
|
67
|
+
File.join(root,'usr','local','share','zsh','site-functions')
|
68
|
+
when :fish
|
69
|
+
if Process.uid == 0
|
70
|
+
File.join(root,'usr','local','share','fish','completions')
|
71
|
+
else
|
72
|
+
xdg_config_home = env.fetch('XDG_CONFIG_HOME') do
|
73
|
+
File.join(home_dir,'.config')
|
74
|
+
end
|
75
|
+
|
76
|
+
File.join(xdg_config_home,'fish','completions')
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Prints the shell completion file to stdout.
|
83
|
+
#
|
84
|
+
# @param [String] path
|
85
|
+
# The path to the shell completion file.
|
86
|
+
#
|
87
|
+
# @param [Hash{Symbol => Object}] kwargs
|
88
|
+
# Additional keyword arguments.
|
89
|
+
#
|
90
|
+
# @option kwargs [:bash, :zsh, :fish] :type (:bash)
|
91
|
+
# The type of the completion file.
|
92
|
+
#
|
93
|
+
# @example Prints a Bash completion file:
|
94
|
+
# print_completion_file 'path/to/completions/foo'
|
95
|
+
#
|
96
|
+
# @example Prints a Zsh completion file:
|
97
|
+
# print_completion_file 'path/to/completions/foo', type: :zsh
|
98
|
+
#
|
99
|
+
# @example Prints a Fish completion file:
|
100
|
+
# print_completion_file 'path/to/completions/foo', type: :fish
|
101
|
+
#
|
102
|
+
# @api public
|
103
|
+
#
|
104
|
+
def print_completion_file(path,**kwargs)
|
105
|
+
write_completion_file(path,stdout,**kwargs)
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
# Installs the shell completion file into {#completions_dir}.
|
110
|
+
#
|
111
|
+
# @param [String] path
|
112
|
+
# The path to the shell completion file.
|
113
|
+
#
|
114
|
+
# @param [:bash, :zsh, :fish] type
|
115
|
+
# The type of the shell completion file.
|
116
|
+
#
|
117
|
+
# @example Install a Bash completion file:
|
118
|
+
# install_completion_file 'path/to/completions/foo'
|
119
|
+
#
|
120
|
+
# @example Install a Zsh completion file:
|
121
|
+
# install_completion_file 'path/to/completions/foo', type: :zsh
|
122
|
+
#
|
123
|
+
# @example Install a Fish completion file:
|
124
|
+
# install_completion_file 'path/to/completions/foo', type: :fish
|
125
|
+
#
|
126
|
+
# @api public
|
127
|
+
#
|
128
|
+
def install_completion_file(path, type: :bash)
|
129
|
+
completion_file = normalize_completion_file(path, type: type)
|
130
|
+
completion_path = File.join(@completions_dir,completion_file)
|
131
|
+
|
132
|
+
begin
|
133
|
+
::FileUtils.mkdir_p(@completions_dir)
|
134
|
+
rescue Errno::EACCES
|
135
|
+
print_error "cannot write to #{shell_type} completions directory: #{@completions_dir}"
|
136
|
+
exit(-1)
|
137
|
+
end
|
138
|
+
|
139
|
+
begin
|
140
|
+
File.open(completion_path,'w') do |output|
|
141
|
+
write_completion_file(path,output, type: type)
|
142
|
+
end
|
143
|
+
rescue Errno::EACCES
|
144
|
+
print_error "cannot write to #{shell_type} completion file: #{completion_path}"
|
145
|
+
exit(-1)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
#
|
150
|
+
# Uninstalls a shell completion file for the specified command.
|
151
|
+
#
|
152
|
+
# @param [String] command
|
153
|
+
# The command to uninstall the completions for.
|
154
|
+
#
|
155
|
+
# @example Removes the completion file for the command 'foo':
|
156
|
+
# uninstall_completion_file_for 'foo'
|
157
|
+
#
|
158
|
+
# @api public
|
159
|
+
#
|
160
|
+
def uninstall_completion_file_for(command)
|
161
|
+
completion_file = completion_file_for_command(command)
|
162
|
+
completion_path = File.join(@completions_dir,completion_file)
|
163
|
+
|
164
|
+
begin
|
165
|
+
::FileUtils.rm_f(completion_path)
|
166
|
+
rescue Errno::EACCES
|
167
|
+
print_error "cannot remove #{shell_type} completion file: #{completion_path}"
|
168
|
+
exit(-1)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
private
|
173
|
+
|
174
|
+
#
|
175
|
+
# Calculates the installed completion file for the given command.
|
176
|
+
#
|
177
|
+
# @param [String] command
|
178
|
+
# The command name.
|
179
|
+
#
|
180
|
+
# @return [String]
|
181
|
+
# The path to the completion file for the command.
|
182
|
+
#
|
183
|
+
# @api private
|
184
|
+
#
|
185
|
+
def completion_file_for_command(command)
|
186
|
+
case shell_type
|
187
|
+
when :bash then command
|
188
|
+
when :zsh then "_#{command}"
|
189
|
+
when :fish then "#{command}.fish"
|
190
|
+
when nil
|
191
|
+
if shell then print_error("cannot identify shell: #{shell}")
|
192
|
+
else print_error("cannot identify shell")
|
193
|
+
end
|
194
|
+
|
195
|
+
exit(-1)
|
196
|
+
else
|
197
|
+
print_error("completions not support for the #{shell_type} shell: #{shell}")
|
198
|
+
exit(-1)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
#
|
203
|
+
# Calculates the installation path for the given completion file.
|
204
|
+
#
|
205
|
+
# @param [String] path
|
206
|
+
# The path to the completion file that will be installed.
|
207
|
+
#
|
208
|
+
# @param [:bash, :zsh, :fish] type
|
209
|
+
# The type of the shell completion file.
|
210
|
+
#
|
211
|
+
# @return [String]
|
212
|
+
# The installation path for the completion file.
|
213
|
+
#
|
214
|
+
# @api private
|
215
|
+
#
|
216
|
+
def normalize_completion_file(path, type: :bash)
|
217
|
+
ext = File.extname(path)
|
218
|
+
file = File.basename(path,ext)
|
219
|
+
|
220
|
+
case [shell_type, type]
|
221
|
+
when [:bash, :bash] # no-op
|
222
|
+
when [:zsh, :zsh],
|
223
|
+
[:zsh, :bash]
|
224
|
+
unless file.start_with?('_')
|
225
|
+
file = "_#{file}"
|
226
|
+
end
|
227
|
+
when [:fish, :fish]
|
228
|
+
file = "#{file}.fish"
|
229
|
+
else
|
230
|
+
if shell_type
|
231
|
+
print_error("cannot install #{type} completion file into the #{shell_type} shell: #{path}")
|
232
|
+
elsif shell
|
233
|
+
print_error("cannot identify shell: #{shell}")
|
234
|
+
else
|
235
|
+
print_error("cannot identify shell")
|
236
|
+
end
|
237
|
+
|
238
|
+
exit(-1)
|
239
|
+
end
|
240
|
+
|
241
|
+
return file
|
242
|
+
end
|
243
|
+
|
244
|
+
#
|
245
|
+
# Writes the shell completion file to the output
|
246
|
+
#
|
247
|
+
# @param [String] path
|
248
|
+
# The path to the shell completion file.
|
249
|
+
#
|
250
|
+
# @param [IO] output
|
251
|
+
# The output stream to write to.
|
252
|
+
#
|
253
|
+
# @param [:bash, :zsh, :fish] type
|
254
|
+
# The type of the shell completion file.
|
255
|
+
#
|
256
|
+
# @api private
|
257
|
+
#
|
258
|
+
def write_completion_file(path,output, type: :bash)
|
259
|
+
if shell_type == :zsh && type == :bash
|
260
|
+
file_name = File.basename(path,File.extname(path))
|
261
|
+
command = file_name.sub(/\A_/,'')
|
262
|
+
|
263
|
+
# add the #compdef magic comments for zsh
|
264
|
+
output.puts "#compdef #{command}"
|
265
|
+
output.puts
|
266
|
+
end
|
267
|
+
|
268
|
+
File.open(path) do |file|
|
269
|
+
file.each_line do |line|
|
270
|
+
output.write(line)
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
data/lib/command_kit/env/home.rb
CHANGED
@@ -20,7 +20,7 @@ module CommandKit
|
|
20
20
|
module ModuleMethods
|
21
21
|
#
|
22
22
|
# Extends {ClassMethods} or {ModuleMethods}, depending on whether
|
23
|
-
# {Env::Home} is being included into a class or a module
|
23
|
+
# {Env::Home} is being included into a class or a module.
|
24
24
|
#
|
25
25
|
# @param [Class, Module] context
|
26
26
|
# The class or module which is including {Home}.
|