bwrap 1.0.0.pre.alpha3 → 1.0.0.pre.beta2

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