bwrap 1.0.0.pre.alpha5 → 1.0.0.pre.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,15 +1,29 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bwrap/output"
4
+ require_relative "exceptions"
4
5
 
5
6
  # Path checking methods.
6
7
  module Bwrap::Execution::Path
7
- # @api internal
8
+ # Utilities to handle environment path operations.
9
+ #
10
+ # @api private
8
11
  class Environment
9
- def self.each_env_path command
12
+ # Loop through each path in global PATH environment variable to
13
+ # perform an operation in each path, for example to resolve
14
+ # absolute path to a command.
15
+ #
16
+ # NOTE: This has nothing to do with {Bwrap::Config#env_paths}, as the
17
+ # env paths looped are what the system has defined, in ENV["PATH"].
18
+ #
19
+ # Should be cross-platform.
20
+ #
21
+ # @yield Command appended to each path in PATH environment variable
22
+ # @yieldparam path [String] Full path to executable
23
+ def self.each_env_path command, env_path_var: ENV["PATH"]
10
24
  exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [ "" ]
11
25
 
12
- ENV["PATH"].split(File::PATH_SEPARATOR).each do |env_path|
26
+ env_path_var.split(File::PATH_SEPARATOR).each do |env_path|
13
27
  exts.each do |ext|
14
28
  exe = File.join(env_path, "#{command}#{ext}")
15
29
  yield exe
@@ -20,8 +34,12 @@ module Bwrap::Execution::Path
20
34
 
21
35
  # Check if requested program can be found.
22
36
  #
23
- # Should work cross-platform and in restricted environents pretty well.
24
- private def command_available? command
37
+ # Should work cross-platform and in restricted environments pretty well.
38
+ #
39
+ # @param command [String] executable to be resolved
40
+ # @param env_path_var [String] PATH environment variable as string.
41
+ # Defaults to `ENV["PATH"]`
42
+ private def command_available? command, env_path_var: ENV["PATH"]
25
43
  # Special handling for absolute paths.
26
44
  path = Pathname.new command
27
45
  if path.absolute?
@@ -32,7 +50,7 @@ module Bwrap::Execution::Path
32
50
  return false
33
51
  end
34
52
 
35
- Bwrap::Execution::Path::Environment.each_env_path command do |exe|
53
+ Bwrap::Execution::Path::Environment.each_env_path command, env_path_var: env_path_var do |exe|
36
54
  return true if File.executable?(exe) && !File.directory?(exe)
37
55
  end
38
56
 
@@ -40,7 +58,9 @@ module Bwrap::Execution::Path
40
58
  end
41
59
 
42
60
  # Returns path to given executable.
43
- private def which command, fail: true
61
+ #
62
+ # @param (see #command_available?)
63
+ private def which command, fail: true, env_path_var: ENV["PATH"]
44
64
  # Special handling for absolute paths.
45
65
  path = Pathname.new command
46
66
  if path.absolute?
@@ -48,17 +68,17 @@ module Bwrap::Execution::Path
48
68
  return command
49
69
  end
50
70
 
51
- raise CommandNotFound.new command: command if fail
71
+ raise Bwrap::Execution::CommandNotFound.new command: command if fail
52
72
 
53
73
  return nil
54
74
  end
55
75
 
56
- Bwrap::Execution::Path::Environment.each_env_path command do |exe|
76
+ Bwrap::Execution::Path::Environment.each_env_path command, env_path_var: env_path_var do |exe|
57
77
  return exe if File.executable?(exe) && !File.directory?(exe)
58
78
  end
59
79
 
60
80
  return nil unless fail
61
81
 
62
- raise CommandNotFound.new command: command
82
+ raise Bwrap::Execution::CommandNotFound.new command: command
63
83
  end
64
84
  end
@@ -1,165 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "bwrap/version"
4
- require "bwrap/output"
5
- require_relative "execution/execute"
6
- require_relative "execution/path"
7
-
8
- # @abstract Module to be included in a class that needs to execute commands.
9
- #
10
- # Methods to execute processes.
3
+ # Declare Execution module here so Bwrap::Execution module is
4
+ # already declared for Execution module classes, to avoid
5
+ # a circular dependency.
11
6
  module Bwrap::Execution
12
- include Bwrap::Output
13
- include Bwrap::Execution::Path
14
-
15
- # Unspecified execution related error.
16
- class CommandError < StandardError
17
- end
18
-
19
- # Signifies that command execution has failed.
20
- class ExecutionFailed < CommandError
21
- end
22
-
23
- # Thrown if given command was not found.
24
- class CommandNotFound < CommandError
25
- # Command that was looked at.
26
- attr_reader :command
27
-
28
- def initialize command:
29
- @command = command
30
- msg = "Failed to find #{command} from PATH."
31
-
32
- super msg
33
- end
34
- end
35
-
36
- # Actual implementation of execution command. Can be used when static method is needed.
37
- #
38
- # @note When an array is given as a command, empty strings are passed as empty arguments.
39
- #
40
- # This means that `[ "foo", "bar" ]` passes one argument to "foo" command, when
41
- # `[ "foo", "", "bar" ]` passes two arguments.
42
- #
43
- # This may or may not be what is assumed, so it can’t be fixed here. It is up to the
44
- # command to decide how to handle empty arguments.
45
- #
46
- # Returns pid of executed command if wait is false.
47
- # Returns command output if wait is true.
48
- #
49
- # fail == If true, an error is raised in case the command returns failure code.
50
- #
51
- # @param error if :show, warn()s output of the command is shown if execution failed.
52
- #
53
- # @see #execute
54
- def self.do_execute command,
55
- fail: true,
56
- wait: true,
57
- log: true,
58
- direct_output: false,
59
- env: {},
60
- clear_env: false,
61
- error: nil,
62
- log_callback: 2,
63
- rootcmd: nil
64
- command = Execute.format_command command, rootcmd: rootcmd
65
- Execute.handle_logging command, log_callback: log_callback, log: log, dry_run: @dry_run
66
- return if @dry_run || Bwrap::Execution::Execute.dry_run
67
-
68
- Execute.open_pipes direct_output
69
-
70
- # If command is an array, there can’t be arrays inside the array.
71
- # For convenience, the array is flattened here, so callers can construct commands more easily.
72
- if command.respond_to? :flatten!
73
- command.flatten!
74
- end
75
-
76
- # If command is string, splat operator (the *) does not do anything. If array, it expand the arguments.
77
- # This causes spawning work correctly, as that’s how spawn() expects to have the argu
78
- pid = spawn(env, *command, err: [ :child, :out ], out: Execute.w, unsetenv_others: clear_env)
79
- output = Execute.finish_execution(log: log, wait: wait, direct_output: direct_output)
80
- return pid unless wait
81
-
82
- # This is instant return, but allows us to have $?/$CHILD_STATUS set.
83
- Process.wait pid
84
- @last_status = $CHILD_STATUS
85
-
86
- output = Execute.process_output output: output
87
- Execute.handle_execution_fail fail: fail, error: error, output: output
88
- output
89
- ensure
90
- Execute.clean_variables
91
- end
92
-
93
- # Returns Process::Status instance of last execution.
94
- #
95
- # @note This only is able to return the status if wait is true, as otherwise caller is assumed to
96
- # handle execution flow.
97
- def self.last_status
98
- @last_status
99
- end
100
-
101
- # Execute a command.
102
- #
103
- # This method can be used by including Execution module in a class that should be able to
104
- # execute commands.
105
- #
106
- # @see .do_execute .do_execute for documentation of argument syntax
107
- private def execute *args
108
- # Mangle proper location to error message.
109
- if args.last.is_a? Hash
110
- args.last[:log_callback] = 3
111
- else
112
- args << { log_callback: 3 }
113
- end
114
- Bwrap::Execution.do_execute(*args)
115
- end
116
-
117
- # Same as ::execute, but uses log: false to avoid unnecessary output when we’re just getting a
118
- # value for internal needs.
119
- #
120
- # Defaults to fail: false, since when one just wants to get the value, there is not that much
121
- # need to unconditionally die if getting bad exit code.
122
- private def execvalue *args, fail: false, rootcmd: nil, env: {}
123
- # This logging handling is a bit of duplication from execute(), but to be extra safe, it is duplicated.
124
- # The debug message contents will always be evaluated, so can just do it like this.
125
- log_command = args[0].respond_to?(:join) && args[0].join(" ") || args[0]
126
- log_command =
127
- if log_command.frozen?
128
- log_command.dup.force_encoding("UTF-8")
129
- else
130
- log_command.force_encoding("UTF-8")
131
- end
132
- if @dry_run
133
- puts "Would execvalue “#{log_command}” at #{caller_locations(1, 1)[0]}"
134
- return
135
- end
136
- trace "Execvaluing “#{log_command}” at #{caller_locations(1, 1)[0]}"
137
- execute(*args, fail: fail, log: false, rootcmd: rootcmd, env: env)
138
- end
139
-
140
- private def exec_success?
141
- $CHILD_STATUS.success?
142
- end
143
-
144
- private def exec_failure?
145
- !exec_success?
146
- end
147
-
148
- # When running through bundler, don’t use whatever it defines as we’re running inside chroot.
149
- private def clean_execute
150
- if (Bundler&.bundler_major_version) >= 2
151
- Bundler.with_unbundled_env do
152
- yield 2
153
- end
154
- elsif Bundler&.bundler_major_version == 1
155
- Bundler.with_clean_env do
156
- yield 1
157
- end
158
- else
159
- yield nil
160
- end
161
- rescue NameError
162
- # If NameError is thrown, no Bundler is available.
163
- yield nil
164
- end
165
7
  end
8
+
9
+ require_relative "execution/execution"
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "output"
4
-
5
3
  # Methods to color CLI output.
6
4
  module Bwrap::Output::Colors
7
5
  # Outputs ANSI true color sequence.
@@ -2,8 +2,6 @@
2
2
 
3
3
  # force_encoding modifies string, so can’t freeze strings.
4
4
 
5
- require_relative "output"
6
-
7
5
  # Logging methods.
8
6
  class Bwrap::Output::Log
9
7
  @@log_file = nil
@@ -40,7 +38,7 @@ class Bwrap::Output::Log
40
38
  @@log_file = log_file
41
39
 
42
40
  at_exit do
43
- ::Bwrap::Output::Log.close_log_file
41
+ Bwrap::Output::Log.close_log_file
44
42
  end
45
43
  end
46
44
  end
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Have variables like $CHILD_STATUS which is alias of $?.
4
+ require "English"
5
+
6
+ require "bwrap/execution/labels"
7
+
8
+ require_relative "levels"
9
+ require_relative "log"
10
+
11
+ # Methods useful for output handling.
12
+ #
13
+ # There is four different log levels:
14
+ #
15
+ # @!description_list
16
+ # @term error
17
+ # @description
18
+ # Causes execution to halt either to exit with requested code or,
19
+ # if requested, raises an exception.
20
+ # @term warning
21
+ # @description Outputs given text to STDERR.
22
+ # @term verbose
23
+ # @description Outputs given text if verbose, debug or trace flag is set.
24
+ # @term debug
25
+ # @description Outputs given text if debug or trace flag is set.
26
+ # @term trace
27
+ # @description Outputs given text if trace flag is set.
28
+ #
29
+ # Output levels can be enabled with {.handle_output_options}.
30
+ #
31
+ # When using {Bwrap::Bwrap}, {Bwrap::Bwrap#parse_command_line_arguments}
32
+ # causes output levels to be set if relevant CLI arguments have been
33
+ # given. TODO: Add documentation about CLI args somewhere. Maybe README?
34
+ module Bwrap::Output
35
+ # @see #verbose?
36
+ def self.verbose?
37
+ Bwrap::Output::Levels.verbose?
38
+ end
39
+
40
+ # @see #debug?
41
+ def self.debug?
42
+ Bwrap::Output::Levels.debug?
43
+ end
44
+
45
+ # @see #trace?
46
+ def self.trace?
47
+ Bwrap::Output::Levels.trace?
48
+ end
49
+
50
+ # Takes hash of options received from Optimist and checks output related flags.
51
+ def self.handle_output_options options
52
+ Bwrap::Output::Levels.handle_output_options options
53
+ end
54
+
55
+ # Handler used by #trace to output given string.
56
+ def self.trace_output str, raw: false, log_callback: 1
57
+ return unless trace?
58
+
59
+ if raw
60
+ print str
61
+ else
62
+ out = Bwrap::Output::Levels.trace_print_formatted str, log_callback: (log_callback + 1)
63
+ end
64
+ Bwrap::Output::Log.puts_to_log out || str
65
+ end
66
+
67
+ # Handler used by #debug to output given string.
68
+ def self.debug_output str, raw: false, log_callback: 1
69
+ return unless debug?
70
+
71
+ if raw
72
+ print str
73
+ else
74
+ out = Bwrap::Output::Levels.debug_print_formatted str, log_callback: (log_callback + 1)
75
+ end
76
+ Bwrap::Output::Log.puts_to_log out || str
77
+ end
78
+
79
+ # Handler used by #verb to output given string.
80
+ def self.verb_output str, raw: false, log_callback: 1
81
+ return unless verbose?
82
+
83
+ if raw
84
+ print str
85
+ else
86
+ out = Bwrap::Output::Levels.verbose_print_formatted str, log_callback: (log_callback + 1)
87
+ end
88
+ Bwrap::Output::Log.puts_to_log out || str
89
+ end
90
+
91
+ # Handler used by #warn to output given string.
92
+ def self.warn_output str, raw: false, log_callback: 1
93
+ if raw
94
+ print str
95
+ else
96
+ out = Bwrap::Output::Levels.warning_print_formatted str, log_callback: (log_callback + 1)
97
+ end
98
+ Bwrap::Output::Log.puts_to_log out || str
99
+ end
100
+
101
+ # Aborts current process.
102
+ #
103
+ # Use this instead of Ruby’s #exit in order to filter out dummy #exit calls from the code.
104
+ def self.error_output str = nil, label: :unspecified, log_callback: 1, raise_exception: false
105
+ unless str.nil?
106
+ out = Bwrap::Output::Levels.error_print_formatted str, log_callback: (log_callback + 1)
107
+ Bwrap::Output::Log.puts_to_log out
108
+ end
109
+
110
+ exit_code = Bwrap::Execution::Labels.resolve_exit_code(label)
111
+ raise str if raise_exception
112
+
113
+ exit exit_code
114
+ end
115
+
116
+ # @return true if --verbose, --debug or --trace has been passed, false if not.
117
+ private def verbose?
118
+ Bwrap::Output::Levels.verbose?
119
+ end
120
+
121
+ # @return true if --debug or --trace has been passed, false if not.
122
+ private def debug?
123
+ Bwrap::Output::Levels.debug?
124
+ end
125
+
126
+ # @return true if --trace has been passed, false if not.
127
+ private def trace?
128
+ Bwrap::Output::Levels.trace?
129
+ end
130
+
131
+ # @!group Outputters
132
+
133
+ # Outputs given string if trace flag has been set.
134
+ #
135
+ # Output flags can be set with {.handle_output_options}.
136
+ #
137
+ # @param str String to be outputted
138
+ # @param raw [Boolean] If true, disables output formatting
139
+ private def trace str, raw: false
140
+ Bwrap::Output.trace_output(str, raw: raw, log_callback: 2)
141
+ end
142
+
143
+ # Outputs given string if debug flag has been set.
144
+ #
145
+ # Output flags can be set with {.handle_output_options}.
146
+ #
147
+ # @param str String to be outputted
148
+ # @param raw [Boolean] If true, disables output formatting
149
+ private def debug str, raw: false
150
+ Bwrap::Output.debug_output(str, raw: raw, log_callback: 2)
151
+ end
152
+
153
+ # Outputs given string if verbose flag has been set.
154
+ #
155
+ # Output flags can be set with {.handle_output_options}.
156
+ #
157
+ # @param str String to be outputted
158
+ # @param raw [Boolean] If true, disables output formatting
159
+ private def verb str, raw: false
160
+ Bwrap::Output.verb_output(str, raw: raw, log_callback: 2)
161
+ end
162
+
163
+ # Outputs given string to `$stderr`.
164
+ #
165
+ # @param str String to be outputted
166
+ # @param raw [Boolean] If true, disables output formatting
167
+ private def warn str, raw: false
168
+ Bwrap::Output.warn_output(str, raw: raw, log_callback: 2)
169
+ end
170
+
171
+ # Outputs given string to `$stderr` and halts execution.
172
+ #
173
+ # @param str String to be outputted
174
+ # @param label [Symbol] Exit label accepted by {Bwrap::Execution.resolve_exit_code}
175
+ # @param raise_exception [Boolean] if true, an exception is raised instead of just existing with exit code.
176
+ private def error str = nil, label: :unspecified, raise_exception: false
177
+ Bwrap::Output.error_output(str, label: label, log_callback: 2, raise_exception: raise_exception)
178
+ end
179
+
180
+ # @!endgroup
181
+ end
data/lib/bwrap/output.rb CHANGED
@@ -1,157 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Have variables like $CHILD_STATUS which is alias of $?.
4
- require "English"
5
-
6
- require "bwrap/execution/labels"
7
- require_relative "output/colors"
8
- require_relative "output/levels"
9
- require_relative "output/log"
10
-
11
- # Extends the module with outputting methods.
3
+ # Declare Output module here so Bwrap::Output module is
4
+ # already declared for Output module classes, to avoid
5
+ # a circular dependency.
6
+ #
7
+ # See output/output.rb for documentation.
12
8
  module Bwrap::Output
13
- include Bwrap::Output::Colors
14
-
15
- # @see #verbose?
16
- def self.verbose?
17
- Bwrap::Output::Levels.verbose?
18
- end
19
-
20
- # @see #debug?
21
- def self.debug?
22
- Bwrap::Output::Levels.debug?
23
- end
24
-
25
- # @see #trace?
26
- def self.trace?
27
- Bwrap::Output::Levels.trace?
28
- end
29
-
30
- # Takes hash of options received from Optimist and checks output related flags.
31
- def self.handle_output_options options
32
- Bwrap::Output::Levels.handle_output_options options
33
- end
34
-
35
- # Handler used by #trace to output given string.
36
- def self.trace_output str, raw: false, log_callback: 1
37
- return unless trace?
38
-
39
- if raw
40
- print str
41
- else
42
- out = Bwrap::Output::Levels.trace_print_formatted str, log_callback: (log_callback + 1)
43
- end
44
- Bwrap::Output::Log.puts_to_log out || str
45
- end
46
-
47
- # Handler used by #debug to output given string.
48
- def self.debug_output str, raw: false, log_callback: 1
49
- return unless debug?
50
-
51
- if raw
52
- print str
53
- else
54
- out = Bwrap::Output::Levels.debug_print_formatted str, log_callback: (log_callback + 1)
55
- end
56
- Bwrap::Output::Log.puts_to_log out || str
57
- end
58
-
59
- # Handler used by #verb to output given string.
60
- def self.verb_output str, raw: false, log_callback: 1
61
- return unless verbose?
62
-
63
- if raw
64
- print str
65
- else
66
- out = Bwrap::Output::Levels.verbose_print_formatted str, log_callback: (log_callback + 1)
67
- end
68
- Bwrap::Output::Log.puts_to_log out || str
69
- end
70
-
71
- # Handler used by #warn to output given string.
72
- def self.warn_output str, raw: false, log_callback: 1
73
- if raw
74
- print str
75
- else
76
- out = Bwrap::Output::Levels.warning_print_formatted str, log_callback: (log_callback + 1)
77
- end
78
- Bwrap::Output::Log.puts_to_log out || str
79
- end
80
-
81
- # Aborts current process.
82
- #
83
- # Use this instead of Ruby’s #exit in order to filter out dummy #exit calls from the code.
84
- def self.error_output str = nil, label: :unspecified, log_callback: 1, raise_exception: false
85
- unless str.nil?
86
- out = Bwrap::Output::Levels.error_print_formatted str, log_callback: (log_callback + 1)
87
- Bwrap::Output::Log.puts_to_log out
88
- end
89
-
90
- exit_code = Bwrap::Execution::Labels.resolve_exit_code(label)
91
- raise str if raise_exception
92
-
93
- exit exit_code
94
- end
95
-
96
- # @return true if --verbose, --debug or --trace has been passed, false if not.
97
- private def verbose?
98
- Bwrap::Output::Levels.verbose?
99
- end
100
-
101
- # @return true if --debug or --trace has been passed, false if not.
102
- private def debug?
103
- Bwrap::Output::Levels.debug?
104
- end
105
-
106
- # @return true if --trace has been passed, false if not.
107
- private def trace?
108
- Bwrap::Output::Levels.trace?
109
- end
110
-
111
- # Outputs given string if trace flag has been set.
112
- #
113
- # Output flags can be set with {.handle_output_options}.
114
- #
115
- # @param str String to be outputted
116
- # @param raw [Boolean] If true, disables output formatting
117
- private def trace str, raw: false
118
- Bwrap::Output.trace_output(str, raw: raw, log_callback: 2)
119
- end
120
-
121
- # Outputs given string if debug flag has been set.
122
- #
123
- # Output flags can be set with {.handle_output_options}.
124
- #
125
- # @param str String to be outputted
126
- # @param raw [Boolean] If true, disables output formatting
127
- private def debug str, raw: false
128
- Bwrap::Output.debug_output(str, raw: raw, log_callback: 2)
129
- end
130
-
131
- # Outputs given string if verbose flag has been set.
132
- #
133
- # Output flags can be set with {.handle_output_options}.
134
- #
135
- # @param str String to be outputted
136
- # @param raw [Boolean] If true, disables output formatting
137
- private def verb str, raw: false
138
- Bwrap::Output.verb_output(str, raw: raw, log_callback: 2)
139
- end
140
-
141
- # Outputs given string to `$stderr`.
142
- #
143
- # @param str String to be outputted
144
- # @param raw [Boolean] If true, disables output formatting
145
- private def warn str, raw: false
146
- Bwrap::Output.warn_output(str, raw: raw, log_callback: 2)
147
- end
148
-
149
- # Outputs given string to `$stderr` and halts execution.
150
- #
151
- # @param str String to be outputted
152
- # @param label [Symbol] Exit label accepted by {Bwrap::Execution.resolve_exit_code}
153
- # @param raise [Boolean] if true, an exception is raised instead of just existing with exit code.
154
- private def error str = nil, label: :unspecified, raise_exception: false
155
- Bwrap::Output.error_output(str, label: label, log_callback: 2, raise_exception: raise_exception)
156
- end
157
9
  end
10
+
11
+ require_relative "output/output_impl"
data/lib/bwrap/version.rb CHANGED
@@ -1,9 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # bwrap command runner tools.
4
3
  module Bwrap
5
4
  # Current version of bwrap.
6
- VERSION = "1.0.0-alpha5"
5
+ VERSION = "1.0.0-beta1"
7
6
  end
8
7
 
9
8
  require "deep-cover" if ENV["DEEP_COVER"]