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

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.
@@ -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"]