command_kit 0.1.0.pre2 → 0.2.1
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 +15 -0
- data/.rubocop.yml +141 -0
- data/ChangeLog.md +98 -2
- data/Gemfile +3 -0
- data/README.md +189 -117
- data/Rakefile +3 -2
- data/command_kit.gemspec +4 -4
- data/examples/command.rb +1 -1
- data/gemspec.yml +10 -2
- data/lib/command_kit/arguments/argument.rb +2 -0
- data/lib/command_kit/arguments/argument_value.rb +2 -0
- data/lib/command_kit/arguments.rb +23 -4
- data/lib/command_kit/colors.rb +253 -45
- data/lib/command_kit/command.rb +6 -1
- data/lib/command_kit/command_name.rb +9 -0
- data/lib/command_kit/commands/auto_load.rb +24 -1
- data/lib/command_kit/commands/auto_require.rb +16 -0
- data/lib/command_kit/commands/command.rb +3 -0
- data/lib/command_kit/commands/help.rb +5 -2
- data/lib/command_kit/commands/parent_command.rb +7 -0
- data/lib/command_kit/commands/subcommand.rb +13 -1
- data/lib/command_kit/commands.rb +54 -9
- data/lib/command_kit/description.rb +12 -1
- data/lib/command_kit/env/home.rb +9 -0
- data/lib/command_kit/env/path.rb +16 -1
- data/lib/command_kit/env.rb +4 -0
- data/lib/command_kit/examples.rb +12 -1
- data/lib/command_kit/exception_handler.rb +4 -0
- data/lib/command_kit/help/man.rb +26 -30
- data/lib/command_kit/help.rb +7 -1
- data/lib/command_kit/inflector.rb +49 -17
- data/lib/command_kit/interactive.rb +248 -0
- data/lib/command_kit/main.rb +18 -9
- data/lib/command_kit/man.rb +44 -0
- data/lib/command_kit/open_app.rb +69 -0
- data/lib/command_kit/options/option.rb +3 -6
- data/lib/command_kit/options/option_value.rb +5 -2
- data/lib/command_kit/options/parser.rb +46 -19
- data/lib/command_kit/options/quiet.rb +3 -0
- data/lib/command_kit/options/verbose.rb +5 -0
- data/lib/command_kit/options/version.rb +6 -0
- data/lib/command_kit/options.rb +32 -7
- data/lib/command_kit/os/linux.rb +157 -0
- data/lib/command_kit/os.rb +165 -11
- data/lib/command_kit/package_manager.rb +200 -0
- data/lib/command_kit/pager.rb +80 -11
- data/lib/command_kit/printing/indent.rb +27 -4
- data/lib/command_kit/printing.rb +35 -1
- data/lib/command_kit/program_name.rb +7 -0
- data/lib/command_kit/stdio.rb +24 -0
- data/lib/command_kit/sudo.rb +40 -0
- data/lib/command_kit/terminal.rb +159 -0
- data/lib/command_kit/usage.rb +14 -0
- data/lib/command_kit/version.rb +1 -1
- data/lib/command_kit/xdg.rb +13 -0
- data/lib/command_kit.rb +1 -0
- data/spec/arguments/argument_spec.rb +2 -2
- data/spec/arguments_spec.rb +53 -27
- data/spec/colors_spec.rb +277 -13
- data/spec/command_name_spec.rb +1 -1
- data/spec/command_spec.rb +79 -5
- data/spec/commands/auto_load/subcommand_spec.rb +1 -1
- data/spec/commands/auto_load_spec.rb +34 -3
- data/spec/commands/auto_require_spec.rb +2 -2
- data/spec/commands/help_spec.rb +1 -1
- data/spec/commands/parent_command_spec.rb +1 -1
- data/spec/commands/subcommand_spec.rb +1 -1
- data/spec/commands_spec.rb +103 -29
- data/spec/description_spec.rb +1 -25
- data/spec/env/home_spec.rb +1 -1
- data/spec/env/path_spec.rb +7 -1
- data/spec/examples_spec.rb +1 -25
- data/spec/exception_handler_spec.rb +1 -1
- data/spec/help/man_spec.rb +45 -58
- data/spec/help_spec.rb +0 -25
- data/spec/inflector_spec.rb +71 -9
- data/spec/interactive_spec.rb +415 -0
- data/spec/main_spec.rb +7 -7
- data/spec/man_spec.rb +46 -0
- data/spec/open_app_spec.rb +85 -0
- data/spec/options/option_spec.rb +5 -5
- data/spec/options/option_value_spec.rb +56 -1
- data/spec/options_spec.rb +283 -1
- data/spec/os/linux_spec.rb +164 -0
- data/spec/os_spec.rb +201 -14
- data/spec/package_manager_spec.rb +806 -0
- data/spec/pager_spec.rb +76 -11
- data/spec/printing/indent_spec.rb +8 -6
- data/spec/printing_spec.rb +33 -3
- data/spec/program_name_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -3
- data/spec/sudo_spec.rb +51 -0
- data/spec/{console_spec.rb → terminal_spec.rb} +65 -35
- data/spec/usage_spec.rb +2 -2
- data/spec/xdg_spec.rb +1 -1
- metadata +26 -8
- data/lib/command_kit/console.rb +0 -141
@@ -0,0 +1,200 @@
|
|
1
|
+
require 'command_kit/os'
|
2
|
+
require 'command_kit/os/linux'
|
3
|
+
require 'command_kit/env/path'
|
4
|
+
require 'command_kit/sudo'
|
5
|
+
|
6
|
+
module CommandKit
|
7
|
+
#
|
8
|
+
# Allows installing packages using the system's package manager.
|
9
|
+
#
|
10
|
+
# Supports the following package managers:
|
11
|
+
#
|
12
|
+
# * Linux
|
13
|
+
# * Debian / Ubuntu
|
14
|
+
# * `apt`
|
15
|
+
# * RedHat / Fedora
|
16
|
+
# * `dnf`
|
17
|
+
# * `yum`
|
18
|
+
# * Arch
|
19
|
+
# * `pacman`
|
20
|
+
# * SUSE / OpenSUSE
|
21
|
+
# * `zypper`
|
22
|
+
# * macOS
|
23
|
+
# * `brew`
|
24
|
+
# * `port`
|
25
|
+
# * FreeBSD
|
26
|
+
# * `pkg`
|
27
|
+
# * OpenBSD
|
28
|
+
# * `pkg_add`
|
29
|
+
#
|
30
|
+
# ## Examples
|
31
|
+
#
|
32
|
+
# unless install_packages("nmap")
|
33
|
+
# print_error "failed to install nmap"
|
34
|
+
# exit -1
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# ### Installing multiple packages
|
38
|
+
#
|
39
|
+
# install_packages apt: ["libxml2-dev", ...],
|
40
|
+
# dnf: ["libxml2-devel", ...],
|
41
|
+
# brew: ["libxml2", ...],
|
42
|
+
# ...
|
43
|
+
#
|
44
|
+
# @since 0.2.0
|
45
|
+
#
|
46
|
+
module PackageManager
|
47
|
+
include OS
|
48
|
+
include OS::Linux
|
49
|
+
include Env::Path
|
50
|
+
include Sudo
|
51
|
+
|
52
|
+
# The detected package manager.
|
53
|
+
#
|
54
|
+
# @return [:apt, :dnf, :yum, :zypper, :pacman, :brew, :pkg, :pkg_add, nil]
|
55
|
+
attr_reader :package_manager
|
56
|
+
|
57
|
+
#
|
58
|
+
# Initializes the command and determines which open command to use.
|
59
|
+
#
|
60
|
+
# @param [:apt, :dnf, :yum, :zypper, :pacman, :brew, :pkg, :pkg_add, nil] package_manager
|
61
|
+
# The explicit package manager to use. If `nil`, the package manager will
|
62
|
+
# be detected.
|
63
|
+
#
|
64
|
+
def initialize(package_manager: nil, **kwargs)
|
65
|
+
super(**kwargs)
|
66
|
+
|
67
|
+
@package_manager = package_manager || begin
|
68
|
+
if macos?
|
69
|
+
if command_installed?('brew') then :brew
|
70
|
+
elsif command_installed?('port') then :port
|
71
|
+
end
|
72
|
+
elsif linux?
|
73
|
+
if redhat_linux?
|
74
|
+
if command_installed?('dnf') then :dnf
|
75
|
+
elsif command_installed?('yum') then :yum
|
76
|
+
end
|
77
|
+
elsif debian_linux?
|
78
|
+
:apt if command_installed?('apt')
|
79
|
+
elsif suse_linux?
|
80
|
+
:zypper if command_installed?('zypper')
|
81
|
+
elsif arch_linux?
|
82
|
+
:pacman if command_installed?('pacman')
|
83
|
+
end
|
84
|
+
elsif freebsd?
|
85
|
+
:pkg if command_installed?('pkg')
|
86
|
+
elsif openbsd?
|
87
|
+
:pkg_add if command_installed?('pkg_add')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# Installs the packages using the system's package manager.
|
94
|
+
#
|
95
|
+
# @param [Array<String>, String] packages
|
96
|
+
# A list of package name(s) to install.
|
97
|
+
#
|
98
|
+
# @param [Boolean] yes
|
99
|
+
# Assume yes for all user prompts.
|
100
|
+
#
|
101
|
+
# @param [Array<String>, String] apt
|
102
|
+
# List of `apt` specific package names.
|
103
|
+
#
|
104
|
+
# @param [Array<String>, String] brew
|
105
|
+
# List of `brew` specific package names.
|
106
|
+
#
|
107
|
+
# @param [Array<String>, String] dnf
|
108
|
+
# List of `dnf` specific package names.
|
109
|
+
#
|
110
|
+
# @param [Array<String>, String] pacman
|
111
|
+
# List of `pacman` specific package names.
|
112
|
+
#
|
113
|
+
# @param [Array<String>, String] pkg
|
114
|
+
# List of `pkg` specific package names.
|
115
|
+
#
|
116
|
+
# @param [Array<String>, String] pkg_add
|
117
|
+
# List of `pkg_add` specific package names.
|
118
|
+
#
|
119
|
+
# @param [Array<String>, String] port
|
120
|
+
# List of `port` specific package names.
|
121
|
+
#
|
122
|
+
# @param [Array<String>, String] yum
|
123
|
+
# List of `yum` specific package names.
|
124
|
+
#
|
125
|
+
# @param [Array<String>, String] zypper
|
126
|
+
# List of `zypper` specific package names.
|
127
|
+
#
|
128
|
+
# @return [Boolean, nil]
|
129
|
+
# Specifies whether the packages were successfully installed or not.
|
130
|
+
# If the package manager command could not be determined, `nil` is
|
131
|
+
# returned.
|
132
|
+
#
|
133
|
+
# @example Install a package
|
134
|
+
# install_packages "nmap", ...
|
135
|
+
#
|
136
|
+
# @example Install a list of packages per package-manager
|
137
|
+
# install_packages apt: ["libxml2-dev", ...],
|
138
|
+
# dnf: ["libxml2-devel", ...],
|
139
|
+
# brew: ["libxml2", ...],
|
140
|
+
# ...
|
141
|
+
#
|
142
|
+
def install_packages(*packages, yes: false,
|
143
|
+
apt: nil,
|
144
|
+
brew: nil,
|
145
|
+
dnf: nil,
|
146
|
+
pacman: nil,
|
147
|
+
pkg: nil,
|
148
|
+
pkg_add: nil,
|
149
|
+
port: nil,
|
150
|
+
yum: nil,
|
151
|
+
zypper: nil)
|
152
|
+
specific_package_names = case @package_manager
|
153
|
+
when :apt then apt
|
154
|
+
when :brew then brew
|
155
|
+
when :dnf then dnf
|
156
|
+
when :pacman then pacman
|
157
|
+
when :pkg then pkg
|
158
|
+
when :pkg_add then pkg_add
|
159
|
+
when :port then port
|
160
|
+
when :yum then yum
|
161
|
+
when :zypper then zypper
|
162
|
+
end
|
163
|
+
packages += Array(specific_package_names)
|
164
|
+
|
165
|
+
case @package_manager
|
166
|
+
when :apt
|
167
|
+
args = []
|
168
|
+
args << '-y' if yes
|
169
|
+
|
170
|
+
sudo('apt','install',*args,*packages)
|
171
|
+
when :brew
|
172
|
+
system('brew','install',*packages)
|
173
|
+
when :dnf, :yum
|
174
|
+
args = []
|
175
|
+
args << '-y' if yes
|
176
|
+
|
177
|
+
sudo(@package_manager.to_s,'install',*args,*packages)
|
178
|
+
when :pacman
|
179
|
+
missing_packages = `pacman -T #{Shellwords.shelljoin(packages)}`.split
|
180
|
+
|
181
|
+
if missing_packages.empty?
|
182
|
+
return true
|
183
|
+
end
|
184
|
+
|
185
|
+
sudo('pacman','-S',*missing_packages)
|
186
|
+
when :pkg
|
187
|
+
args = []
|
188
|
+
args << '-y' if yes
|
189
|
+
|
190
|
+
sudo('pkg','install',*args,*packages)
|
191
|
+
when :pkg_add
|
192
|
+
sudo('pkg_add',*packages)
|
193
|
+
when :port
|
194
|
+
sudo('port','install',*packages)
|
195
|
+
when :zypper
|
196
|
+
sudo('zypper','-n','in','-l',*packages)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
data/lib/command_kit/pager.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'command_kit/stdio'
|
4
|
-
require 'command_kit/console'
|
5
3
|
require 'command_kit/env'
|
6
4
|
require 'command_kit/env/path'
|
5
|
+
require 'command_kit/stdio'
|
6
|
+
require 'command_kit/terminal'
|
7
|
+
|
8
|
+
require 'shellwords'
|
7
9
|
|
8
10
|
module CommandKit
|
9
11
|
#
|
@@ -35,10 +37,10 @@ module CommandKit
|
|
35
37
|
# * [tty-pager](https://github.com/piotrmurach/tty-pager#readme)
|
36
38
|
#
|
37
39
|
module Pager
|
38
|
-
include Stdio
|
39
|
-
include Console
|
40
40
|
include Env
|
41
41
|
include Env::Path
|
42
|
+
include Stdio
|
43
|
+
include Terminal
|
42
44
|
|
43
45
|
# Common pager commands.
|
44
46
|
PAGERS = ['less -r', 'more -r']
|
@@ -50,13 +52,15 @@ module CommandKit
|
|
50
52
|
# Keyword arguments.
|
51
53
|
#
|
52
54
|
# @note
|
53
|
-
# Respects the `PAGER` env variable, or
|
55
|
+
# Respects the `PAGER` env variable, or attempts to find `less` or
|
54
56
|
# `more` by searching the `PATH` env variable.
|
55
57
|
#
|
58
|
+
# @api public
|
59
|
+
#
|
56
60
|
def initialize(**kwargs)
|
57
61
|
super(**kwargs)
|
58
62
|
|
59
|
-
@
|
63
|
+
@pager_command = env.fetch('PAGER') do
|
60
64
|
PAGERS.find do |command|
|
61
65
|
bin = command.split(' ',2).first
|
62
66
|
|
@@ -74,15 +78,32 @@ module CommandKit
|
|
74
78
|
# @yieldparam [IO]
|
75
79
|
# The IO pipe to the pager.
|
76
80
|
#
|
81
|
+
# @example
|
82
|
+
# pager do |io|
|
83
|
+
# io.puts "Hello world"
|
84
|
+
# # ...
|
85
|
+
# end
|
86
|
+
#
|
87
|
+
# @example Piping a command into the pager:
|
88
|
+
# IO.peopn(["ping", ip]) do |ping|
|
89
|
+
# pager do |io|
|
90
|
+
# ping.each_line do |line|
|
91
|
+
# io.write line
|
92
|
+
# end
|
93
|
+
# end
|
94
|
+
# end
|
95
|
+
#
|
96
|
+
# @api public
|
97
|
+
#
|
77
98
|
def pager
|
78
|
-
if !stdout.tty? || @
|
79
|
-
# fallback to stdout if the process does not have a
|
99
|
+
if !stdout.tty? || @pager_command.nil?
|
100
|
+
# fallback to stdout if the process does not have a terminal or we could
|
80
101
|
# not find a suitable pager command.
|
81
102
|
yield stdout
|
82
103
|
return
|
83
104
|
end
|
84
105
|
|
85
|
-
io = IO.popen(@
|
106
|
+
io = IO.popen(@pager_command,'w')
|
86
107
|
pid = io.pid
|
87
108
|
|
88
109
|
begin
|
@@ -99,23 +120,71 @@ module CommandKit
|
|
99
120
|
end
|
100
121
|
|
101
122
|
#
|
102
|
-
# Pages the data if it's longer the
|
123
|
+
# Pages the data if it's longer the terminal's height, otherwise prints the
|
103
124
|
# data to {Stdio#stdout stdout}.
|
104
125
|
#
|
105
126
|
# @param [Array<String>, #to_s] data
|
106
127
|
# The data to print.
|
107
128
|
#
|
129
|
+
# @example
|
130
|
+
# print_or_page(data)
|
131
|
+
#
|
132
|
+
# @example Print or pages the contents of a file:
|
133
|
+
# print_or_page(File.read(file))
|
134
|
+
#
|
135
|
+
# @api public
|
136
|
+
#
|
108
137
|
def print_or_page(data)
|
109
138
|
line_count = case data
|
110
139
|
when Array then data.length
|
111
140
|
else data.to_s.each_line.count
|
112
141
|
end
|
113
142
|
|
114
|
-
if line_count >
|
143
|
+
if line_count > terminal_height
|
115
144
|
pager { |io| io.puts(data) }
|
116
145
|
else
|
117
146
|
stdout.puts(data)
|
118
147
|
end
|
119
148
|
end
|
149
|
+
|
150
|
+
#
|
151
|
+
# Pipes a command into the pager.
|
152
|
+
#
|
153
|
+
# @param [#to_s] command
|
154
|
+
# The program or command to run.
|
155
|
+
#
|
156
|
+
# @param [Array<#to_s>] arguments
|
157
|
+
# Additional arguments for the program.
|
158
|
+
#
|
159
|
+
# @return [Boolean]
|
160
|
+
# Indicates whether the command exited successfully or not.
|
161
|
+
#
|
162
|
+
# @note
|
163
|
+
# If multiple arguments are given, they will be shell-escaped and executed
|
164
|
+
# as a single command.
|
165
|
+
# If a single command is given, it will not be shell-escaped to allow
|
166
|
+
# executing compound shell commands.
|
167
|
+
#
|
168
|
+
# @example Pipe a single command into the pager:
|
169
|
+
# run_in_pager 'find', '.', '-name', '*.md'
|
170
|
+
#
|
171
|
+
# @example Pipe a compound command into the pager:
|
172
|
+
# run_in_pager "wc -l /path/to/wordlists/*.txt | sort -n"
|
173
|
+
#
|
174
|
+
# @api public
|
175
|
+
#
|
176
|
+
# @since 0.2.0
|
177
|
+
#
|
178
|
+
def pipe_to_pager(command,*arguments)
|
179
|
+
if @pager_command
|
180
|
+
unless arguments.empty?
|
181
|
+
command = Shellwords.shelljoin([command, *arguments])
|
182
|
+
end
|
183
|
+
|
184
|
+
system("#{command} | #{@pager_command}")
|
185
|
+
else
|
186
|
+
system(command.to_s,*arguments.map(&:to_s))
|
187
|
+
end
|
188
|
+
end
|
120
189
|
end
|
121
190
|
end
|
@@ -20,7 +20,7 @@ module CommandKit
|
|
20
20
|
#
|
21
21
|
module Indent
|
22
22
|
#
|
23
|
-
# Initializes the
|
23
|
+
# Initializes the indentation level to zero.
|
24
24
|
#
|
25
25
|
def initialize(**kwargs)
|
26
26
|
@indent = 0
|
@@ -40,14 +40,35 @@ module CommandKit
|
|
40
40
|
# increased.
|
41
41
|
#
|
42
42
|
# @return [Integer]
|
43
|
-
# If no block is given, the
|
43
|
+
# If no block is given, the indentation level will be returned.
|
44
|
+
#
|
45
|
+
# @example
|
46
|
+
# puts "values:"
|
47
|
+
# indent do
|
48
|
+
# values.each do |key,value|
|
49
|
+
# puts "#{key}: #{value}"
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# @example
|
54
|
+
# puts "Code:"
|
55
|
+
# puts
|
56
|
+
# puts "```"
|
57
|
+
# indent(4) do
|
58
|
+
# code.each_line do |line|
|
59
|
+
# puts line
|
60
|
+
# end
|
61
|
+
# end
|
62
|
+
# puts "```"
|
63
|
+
#
|
64
|
+
# @api public
|
44
65
|
#
|
45
66
|
def indent(n=2)
|
46
67
|
if block_given?
|
68
|
+
original_indent = @indent
|
69
|
+
|
47
70
|
begin
|
48
|
-
original_indent = @indent
|
49
71
|
@indent += n
|
50
|
-
|
51
72
|
yield
|
52
73
|
ensure
|
53
74
|
@indent = original_indent
|
@@ -63,6 +84,8 @@ module CommandKit
|
|
63
84
|
# @param [Array<String>] lines
|
64
85
|
# The lines to indent and print.
|
65
86
|
#
|
87
|
+
# @api public
|
88
|
+
#
|
66
89
|
def puts(*lines)
|
67
90
|
if (@indent > 0 && !lines.empty?)
|
68
91
|
padding = " " * @indent
|
data/lib/command_kit/printing.rb
CHANGED
@@ -9,14 +9,37 @@ module CommandKit
|
|
9
9
|
module Printing
|
10
10
|
include Stdio
|
11
11
|
|
12
|
+
# Platform independent new-line constant
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
#
|
16
|
+
# @api public
|
17
|
+
EOL = $/
|
18
|
+
|
12
19
|
#
|
13
20
|
# Prints the error message to {Stdio#stderr stderr}.
|
14
21
|
#
|
15
22
|
# @param [String] message
|
16
23
|
# The error message.
|
17
24
|
#
|
25
|
+
# @example
|
26
|
+
# print_error "error: invalid input"
|
27
|
+
# # error: invalid input
|
28
|
+
#
|
29
|
+
# @example When CommandKit::CommandName is included:
|
30
|
+
# print_error "invalid input"
|
31
|
+
# # foo: invalid input
|
32
|
+
#
|
33
|
+
# @api public
|
34
|
+
#
|
18
35
|
def print_error(message)
|
19
|
-
|
36
|
+
if respond_to?(:command_name)
|
37
|
+
# if #command_name is available, prefix all error messages with it
|
38
|
+
stderr.puts "#{command_name}: #{message}"
|
39
|
+
else
|
40
|
+
# if #command_name is not available, just print the error message as-is
|
41
|
+
stderr.puts message
|
42
|
+
end
|
20
43
|
end
|
21
44
|
|
22
45
|
#
|
@@ -25,6 +48,17 @@ module CommandKit
|
|
25
48
|
# @param [Exception] error
|
26
49
|
# The error to print.
|
27
50
|
#
|
51
|
+
# @example
|
52
|
+
# begin
|
53
|
+
# # ...
|
54
|
+
# rescue => error
|
55
|
+
# print_error "Error encountered"
|
56
|
+
# print_exception(error)
|
57
|
+
# exit(1)
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# @api public
|
61
|
+
#
|
28
62
|
def print_exception(error)
|
29
63
|
print_error error.full_message(highlight: stderr.tty?)
|
30
64
|
end
|
@@ -3,6 +3,9 @@ module CommandKit
|
|
3
3
|
# Retrieves the current program name (`$PROGRAM_NAME`).
|
4
4
|
#
|
5
5
|
module ProgramName
|
6
|
+
#
|
7
|
+
# @api private
|
8
|
+
#
|
6
9
|
module ModuleMethods
|
7
10
|
#
|
8
11
|
# Extends {ClassMethods} or {ModuleMethods}, depending on whether
|
@@ -42,6 +45,8 @@ module CommandKit
|
|
42
45
|
# The `$PROGRAM_NAME` or `nil` if the `$PROGRAM_NAME` is `-e`, `irb`,
|
43
46
|
# or `rspec`.
|
44
47
|
#
|
48
|
+
# @api semipublic
|
49
|
+
#
|
45
50
|
def program_name
|
46
51
|
$PROGRAM_NAME unless IGNORED_PROGRAM_NAMES.include?($PROGRAM_NAME)
|
47
52
|
end
|
@@ -50,6 +55,8 @@ module CommandKit
|
|
50
55
|
#
|
51
56
|
# @see ClassMethods#program_name
|
52
57
|
#
|
58
|
+
# @api public
|
59
|
+
#
|
53
60
|
def program_name
|
54
61
|
self.class.program_name
|
55
62
|
end
|
data/lib/command_kit/stdio.rb
CHANGED
@@ -34,6 +34,8 @@ module CommandKit
|
|
34
34
|
# @param [IO] stderr
|
35
35
|
# The stderr error output stream. Defaults to `$stderr`.
|
36
36
|
#
|
37
|
+
# @api public
|
38
|
+
#
|
37
39
|
def initialize(stdin: nil, stdout: nil, stderr: nil, **kwargs)
|
38
40
|
@stdin = stdin
|
39
41
|
@stdout = stdout
|
@@ -48,6 +50,8 @@ module CommandKit
|
|
48
50
|
# @return [$stdin, IO]
|
49
51
|
# The initialized `@stdin` value or `$stdin`.
|
50
52
|
#
|
53
|
+
# @api public
|
54
|
+
#
|
51
55
|
def stdin
|
52
56
|
@stdin || $stdin
|
53
57
|
end
|
@@ -58,6 +62,8 @@ module CommandKit
|
|
58
62
|
# @return [$stdout, IO]
|
59
63
|
# The initialized `@stdout` value or `$stdout`.
|
60
64
|
#
|
65
|
+
# @api public
|
66
|
+
#
|
61
67
|
def stdout
|
62
68
|
@stdout || $stdout
|
63
69
|
end
|
@@ -68,6 +74,8 @@ module CommandKit
|
|
68
74
|
# @return [$stderr, IO]
|
69
75
|
# The initialized `@stderr` value or `$stderr`.
|
70
76
|
#
|
77
|
+
# @api public
|
78
|
+
#
|
71
79
|
def stderr
|
72
80
|
@stderr || $stderr
|
73
81
|
end
|
@@ -75,6 +83,8 @@ module CommandKit
|
|
75
83
|
#
|
76
84
|
# Calls `stdin.gets`.
|
77
85
|
#
|
86
|
+
# @api public
|
87
|
+
#
|
78
88
|
def gets(*arguments)
|
79
89
|
stdin.gets(*arguments)
|
80
90
|
end
|
@@ -82,6 +92,8 @@ module CommandKit
|
|
82
92
|
#
|
83
93
|
# Calls `stdin.readline`.
|
84
94
|
#
|
95
|
+
# @api public
|
96
|
+
#
|
85
97
|
def readline(*arguments)
|
86
98
|
stdin.readline(*arguments)
|
87
99
|
end
|
@@ -89,6 +101,8 @@ module CommandKit
|
|
89
101
|
#
|
90
102
|
# Calls `stdin.readlines`.
|
91
103
|
#
|
104
|
+
# @api public
|
105
|
+
#
|
92
106
|
def readlines(*arguments)
|
93
107
|
stdin.readlines(*arguments)
|
94
108
|
end
|
@@ -99,6 +113,8 @@ module CommandKit
|
|
99
113
|
#
|
100
114
|
# Calls `stdout.putc`.
|
101
115
|
#
|
116
|
+
# @api public
|
117
|
+
#
|
102
118
|
def putc(*arguments)
|
103
119
|
stdout.putc(*arguments)
|
104
120
|
end
|
@@ -106,6 +122,8 @@ module CommandKit
|
|
106
122
|
#
|
107
123
|
# Calls `stdout.puts`.
|
108
124
|
#
|
125
|
+
# @api public
|
126
|
+
#
|
109
127
|
def puts(*arguments)
|
110
128
|
stdout.puts(*arguments)
|
111
129
|
end
|
@@ -113,6 +131,8 @@ module CommandKit
|
|
113
131
|
#
|
114
132
|
# Calls `stdout.print`.
|
115
133
|
#
|
134
|
+
# @api public
|
135
|
+
#
|
116
136
|
def print(*arguments)
|
117
137
|
stdout.print(*arguments)
|
118
138
|
end
|
@@ -120,6 +140,8 @@ module CommandKit
|
|
120
140
|
#
|
121
141
|
# Calls `stdout.printf`.
|
122
142
|
#
|
143
|
+
# @api public
|
144
|
+
#
|
123
145
|
def printf(*arguments)
|
124
146
|
stdout.printf(*arguments)
|
125
147
|
end
|
@@ -130,6 +152,8 @@ module CommandKit
|
|
130
152
|
# @param [String, nil] message
|
131
153
|
# The optional abort message.
|
132
154
|
#
|
155
|
+
# @api public
|
156
|
+
#
|
133
157
|
def abort(message=nil)
|
134
158
|
stderr.puts(message) if message
|
135
159
|
exit(1)
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'command_kit/os'
|
4
|
+
|
5
|
+
module CommandKit
|
6
|
+
#
|
7
|
+
# Allows running commands with `sudo`.
|
8
|
+
#
|
9
|
+
# @since 0.2.0
|
10
|
+
#
|
11
|
+
module Sudo
|
12
|
+
include OS
|
13
|
+
|
14
|
+
#
|
15
|
+
# Runs the command under sudo, if the user isn't already root.
|
16
|
+
#
|
17
|
+
# @param [String] command
|
18
|
+
# The command to execute.
|
19
|
+
#
|
20
|
+
# @param [Array<String>] arguments
|
21
|
+
# Additional arguments for the command.
|
22
|
+
#
|
23
|
+
# @return [Boolean, nil]
|
24
|
+
# Specifies whether the command was successfully ran or not.
|
25
|
+
#
|
26
|
+
# @api public
|
27
|
+
#
|
28
|
+
def sudo(command,*arguments)
|
29
|
+
if windows?
|
30
|
+
system('runas','/user:administrator',command,*arguments)
|
31
|
+
else
|
32
|
+
if Process.uid == 0
|
33
|
+
system(command,*arguments)
|
34
|
+
else
|
35
|
+
system('sudo',command,*arguments)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|