brut 0.20.0 → 0.20.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/lib/brut/cli/apps/build_assets.rb +2 -2
- data/lib/brut/cli/apps/new/app.rb +1 -1
- data/lib/brut/cli/apps/new/ops/insert_code_in_method.rb +5 -0
- data/lib/brut/cli/apps/new/segments/heroku.rb +0 -3
- data/lib/brut/cli/apps/new/segments/sidekiq.rb +6 -3
- data/lib/brut/cli/apps/scaffold.rb +2 -1
- data/lib/brut/cli/apps/test.rb +12 -5
- data/lib/brut/cli/commands/help_in_markdown.rb +109 -0
- data/lib/brut/cli/commands.rb +1 -0
- data/lib/brut/cli/parsed_command_line.rb +8 -4
- data/lib/brut/framework/mcp.rb +1 -0
- data/lib/brut/front_end/asset_metadata.rb +0 -1
- data/lib/brut/front_end/forms/input_declarations.rb +30 -1
- data/lib/brut/spec_support/e2e_test_server.rb +5 -4
- data/lib/brut/tui/event_loop.rb +5 -1
- data/lib/brut/version.rb +1 -1
- data/templates/Base/bin/console +1 -1
- data/templates/Base/bin/release +1 -1
- data/templates/Base/dx/build +2 -2
- metadata +6 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: de61901270558680112b8b90f787067add7f777204219016020adcc90c15564d
|
|
4
|
+
data.tar.gz: 4437fee31bc132bd93fe419ac72df5bc1b1e7bb67f506a4e36ab126dc7395b85
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fcc0ef80b40ea5703298cdbaa71f86f3ec8d22b96f8bc4e9cea336f41b09bbca109b211eea365b202759f8bca4c07ace5c35d2a6f638a7d2231f5d0534090556
|
|
7
|
+
data.tar.gz: c4bb547d99089ca6d567e744c39539fda20ff85b21c45dd2419ab7d0bcfc0e265a9004006973e7bb4f96be35f41d21354efd71502f77e2276140dbd8badf29a3
|
|
@@ -91,9 +91,9 @@ This is to ensure that any images your code references will end up in the public
|
|
|
91
91
|
def description = "Builds a single CSS file suitable for sending to the browser"
|
|
92
92
|
|
|
93
93
|
def detailed_description = %{
|
|
94
|
-
This produces a hashed file in every environment, in order to keep environments consistent and reduce differences. If your CSS file references images, fonts, or other assets via url() or other CSS functions, those files will be hashed and copied into the output directory where CSS is served.
|
|
94
|
+
This produces a hashed file in every environment, in order to keep environments consistent and reduce differences. If your CSS file references images, fonts, or other assets via `url()` or other CSS functions, those files will be hashed and copied into the output directory where CSS is served.
|
|
95
95
|
|
|
96
|
-
To ensure this happens correctly, your url() or other function must reference the file as a relative file from where your actual source CSS file is located. For example, a font named some-font.ttf would be in app/src/front_end/fonts
|
|
96
|
+
To ensure this happens correctly, your `url()` or other function must reference the file as a relative file from where your actual source CSS file is located. For example, a font named `some-font.ttf` would be in `app/src/front_end/fonts`. To reference this from `app/src/front_end/css/index.css` you'd use `url("../fonts/some-font.ttf")`
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
def run
|
|
@@ -319,7 +319,7 @@ class Brut::CLI::Apps::New::App < Brut::CLI::Commands::BaseCommand
|
|
|
319
319
|
|
|
320
320
|
puts "Adding #{segment_name} to this app"
|
|
321
321
|
segment.add!
|
|
322
|
-
segment.output_post_add_messaging(stdout:)
|
|
322
|
+
segment.output_post_add_messaging(stdout: execution_context.stdout)
|
|
323
323
|
0
|
|
324
324
|
end
|
|
325
325
|
end
|
|
@@ -19,6 +19,11 @@ class Brut::CLI::Apps::New::Ops::InsertCodeInMethod < Brut::CLI::Apps::New::Ops:
|
|
|
19
19
|
if !@file.exist? && @ignore_if_file_not_found
|
|
20
20
|
return
|
|
21
21
|
end
|
|
22
|
+
if dry_run?
|
|
23
|
+
op = @class_method ? "::" : "#"
|
|
24
|
+
puts "Would add this code to #{@class_name}#{op}#{@method_name} in #{@file}:\n\n#{@code}\n\n"
|
|
25
|
+
return
|
|
26
|
+
end
|
|
22
27
|
method_node = find_method(class_name: @class_name, method_name: @method_name, class_method: @class_method)
|
|
23
28
|
|
|
24
29
|
insertion_point = if @where == :start
|
|
@@ -75,6 +75,10 @@ class Brut::CLI::Apps::New::Segments::Sidekiq < Brut::CLI::Apps::New::Base
|
|
|
75
75
|
file: @project_root / "Gemfile",
|
|
76
76
|
content: "# Sidekiq is used for background jobs\ngem \"sidekiq\"\n"
|
|
77
77
|
),
|
|
78
|
+
Brut::CLI::Apps::New::Ops::AppendToFile.new(
|
|
79
|
+
file: @project_root / "Gemfile",
|
|
80
|
+
content: "# Sets up OTel middelware for Sidekiq \ngem \"opentelemetry-instrumentation-sidekiq\"\n"
|
|
81
|
+
),
|
|
78
82
|
Brut::CLI::Apps::New::Ops::AppendToFile.new(
|
|
79
83
|
file: @project_root / ".env.development",
|
|
80
84
|
content: %{
|
|
@@ -110,7 +114,7 @@ SIDEKIQ_BASIC_AUTH_PASSWORD=password
|
|
|
110
114
|
Brut::CLI::Apps::New::Ops::InsertIntoFile.new(
|
|
111
115
|
file: @project_root / "specs" / "spec_helper.rb",
|
|
112
116
|
before_line: "require \"brut/spec_support\"",
|
|
113
|
-
content: "
|
|
117
|
+
content: "Sidekiq.testing!(:fake)"
|
|
114
118
|
),
|
|
115
119
|
Brut::CLI::Apps::New::Ops::InsertIntoFile.new(
|
|
116
120
|
file: @project_root / "config.ru",
|
|
@@ -142,10 +146,9 @@ SIDEKIQ_BASIC_AUTH_PASSWORD=password
|
|
|
142
146
|
code: "@sidekiq_segment.boot!"
|
|
143
147
|
),
|
|
144
148
|
Brut::CLI::Apps::New::Ops::InsertCodeInMethod.new(
|
|
145
|
-
file: project_root / "deploy" / "
|
|
149
|
+
file: project_root / "deploy" / "docker_config.rb",
|
|
146
150
|
class_name: "HerokuConfig",
|
|
147
151
|
method_name: "additional_images",
|
|
148
|
-
class_method: true,
|
|
149
152
|
ignore_if_file_not_found: true,
|
|
150
153
|
code: %{
|
|
151
154
|
{
|
|
@@ -637,7 +637,8 @@ describe("#{description}", () => {
|
|
|
637
637
|
|
|
638
638
|
def run
|
|
639
639
|
if argv.length == 0
|
|
640
|
-
|
|
640
|
+
puts "You must provide one or more model names"
|
|
641
|
+
return 1
|
|
641
642
|
end
|
|
642
643
|
db_module = ModuleName.from_string("DB")
|
|
643
644
|
actions = argv.map { |arg|
|
data/lib/brut/cli/apps/test.rb
CHANGED
|
@@ -90,6 +90,7 @@ Runs all non end-to-end tests for the app, or runs a subset of non-end-to-end te
|
|
|
90
90
|
[ "E2E_RECORD_VIDEOS","If set to 'true', videos of each test run are saved in `./tmp/e2e-videos`" ],
|
|
91
91
|
[ "E2E_SLOW_MO","If set to, will attempt to slow operations down by this many milliseconds" ],
|
|
92
92
|
[ "E2E_TIMEOUT_MS","ms to wait for any browser activity before failing the test. And here you didn't think you'd get away without using sleep in browse-based tests?" ],
|
|
93
|
+
[ "E2E_STARTUP_TIMEOUT_SEC","seconds to wait for the test server to start before assuming something went wrong" ],
|
|
93
94
|
]
|
|
94
95
|
|
|
95
96
|
def rspec_cli_args = "--tag e2e"
|
|
@@ -102,11 +103,17 @@ Runs all end-to-end tests for the app, or runs a subset of end-to-end tests usin
|
|
|
102
103
|
private
|
|
103
104
|
|
|
104
105
|
def run_tests
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
106
|
+
test_server = Brut::SpecSupport::E2ETestServer.new(
|
|
107
|
+
bin_dir: Brut.container.project_root / "bin",
|
|
108
|
+
start_timeout_seconds: ENV["E2E_STARTUP_TIMEOUT_SEC"]
|
|
109
|
+
)
|
|
110
|
+
begin
|
|
111
|
+
require "brut/spec_support/e2e_test_server"
|
|
112
|
+
test_server.start
|
|
113
|
+
super
|
|
114
|
+
ensure
|
|
115
|
+
test_server.stop
|
|
116
|
+
end
|
|
110
117
|
end
|
|
111
118
|
end
|
|
112
119
|
class Js < Brut::CLI::Commands::BaseCommand
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
class Brut::CLI::Commands::HelpInMarkdown < Brut::CLI::Commands::BaseCommand
|
|
2
|
+
def description = "Get help for the app or a command, in Markdown"
|
|
3
|
+
attr_accessor :option_parser
|
|
4
|
+
|
|
5
|
+
def initialize(command,option_parser)
|
|
6
|
+
@command = command
|
|
7
|
+
@option_parser = option_parser
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def commands = []
|
|
11
|
+
|
|
12
|
+
def run
|
|
13
|
+
if env["BRUT_HELP_IN_MARKDOWN_COMMANDS_ONLY"]
|
|
14
|
+
@command.commands.sort_by(&:name).each do |command|
|
|
15
|
+
puts command.name
|
|
16
|
+
end
|
|
17
|
+
return 0
|
|
18
|
+
end
|
|
19
|
+
cli = [@command.name ]
|
|
20
|
+
cmd = @command
|
|
21
|
+
while cmd.parent_command
|
|
22
|
+
cmd = cmd.parent_command
|
|
23
|
+
cli.unshift cmd.name
|
|
24
|
+
end
|
|
25
|
+
invocation = cli.join(" ")
|
|
26
|
+
puts "# `#{invocation}`"
|
|
27
|
+
puts
|
|
28
|
+
puts @command.description
|
|
29
|
+
puts
|
|
30
|
+
|
|
31
|
+
usage = invocation
|
|
32
|
+
|
|
33
|
+
options = @option_parser.top.list
|
|
34
|
+
if options.size > 0
|
|
35
|
+
usage << theme.weak.render(" [options]")
|
|
36
|
+
end
|
|
37
|
+
if @command.commands.any?
|
|
38
|
+
usage << theme.code.render(" command")
|
|
39
|
+
end
|
|
40
|
+
if @command.args_description
|
|
41
|
+
usage << " #{@command.args_description}"
|
|
42
|
+
end
|
|
43
|
+
puts
|
|
44
|
+
puts "## USAGE"
|
|
45
|
+
puts
|
|
46
|
+
puts " " + usage
|
|
47
|
+
puts
|
|
48
|
+
if @command.detailed_description
|
|
49
|
+
puts
|
|
50
|
+
puts "## DESCRIPTION"
|
|
51
|
+
puts
|
|
52
|
+
puts @command.detailed_description.gsub(/ +/," ").strip
|
|
53
|
+
puts
|
|
54
|
+
end
|
|
55
|
+
if options.size > 0
|
|
56
|
+
puts
|
|
57
|
+
puts "## OPTIONS"
|
|
58
|
+
puts
|
|
59
|
+
|
|
60
|
+
options.each do |option|
|
|
61
|
+
switches = option.long.map { |switch|
|
|
62
|
+
if option.arg
|
|
63
|
+
if option.arg[0] == "="
|
|
64
|
+
"#{switch.strip}#{theme.weak.render(option.arg.strip)}"
|
|
65
|
+
else
|
|
66
|
+
"#{switch.strip}=#{theme.weak.render(option.arg.strip)}"
|
|
67
|
+
end
|
|
68
|
+
else
|
|
69
|
+
switch
|
|
70
|
+
end
|
|
71
|
+
} + option.short.map { |switch|
|
|
72
|
+
if option.arg
|
|
73
|
+
"#{switch} #{theme.weak.render(option.arg)}"
|
|
74
|
+
else
|
|
75
|
+
switch
|
|
76
|
+
end
|
|
77
|
+
}
|
|
78
|
+
puts "* `#{switches.join(", ")}` - #{option.desc.join(" ")}"
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
if @command.env_vars.any?
|
|
82
|
+
puts
|
|
83
|
+
puts "## ENVIRONMENT VARIABLES"
|
|
84
|
+
puts
|
|
85
|
+
@command.env_vars.sort_by(&:first).each do |env_var|
|
|
86
|
+
puts "* `#{env_var[0]}` - #{env_var[1]}"
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
if @command.commands.any?
|
|
90
|
+
commands_subpath = env["BRUT_HELP_IN_MARKDOWN_COMMAND_PATH"] || "commands"
|
|
91
|
+
puts
|
|
92
|
+
puts "## COMMANDS"
|
|
93
|
+
puts
|
|
94
|
+
@command.commands.sort_by(&:name).each do |command|
|
|
95
|
+
puts "### [`#{command.name}`](./#{commands_subpath}/#{command.name})"
|
|
96
|
+
puts
|
|
97
|
+
puts "#{command.description}"
|
|
98
|
+
if command.detailed_description
|
|
99
|
+
puts
|
|
100
|
+
puts command.detailed_description.gsub(/ +/," ").strip
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
0
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def bootstrap? = false
|
|
108
|
+
def default_rack_env = nil
|
|
109
|
+
end
|
data/lib/brut/cli/commands.rb
CHANGED
|
@@ -2,6 +2,7 @@ module Brut::CLI::Commands
|
|
|
2
2
|
autoload(:BaseCommand, "brut/cli/commands/base_command")
|
|
3
3
|
autoload(:CompoundCommand, "brut/cli/commands/compound_command")
|
|
4
4
|
autoload(:Help, "brut/cli/commands/help")
|
|
5
|
+
autoload(:HelpInMarkdown, "brut/cli/commands/help_in_markdown")
|
|
5
6
|
autoload(:OutputError, "brut/cli/commands/output_error")
|
|
6
7
|
autoload(:RaiseError, "brut/cli/commands/raise_error")
|
|
7
8
|
autoload(:ExecutionContext, "brut/cli/commands/execution_context")
|
|
@@ -30,6 +30,11 @@ class Brut::CLI::ParsedCommandLine
|
|
|
30
30
|
# This should always succeed, however depending on the contents of the parameters, the value
|
|
31
31
|
# for `#command` may be a command that outputs an error.
|
|
32
32
|
def initialize(app_command:, argv:, env:)
|
|
33
|
+
help_command_class = if env["BRUT_HELP_IN_MARKDOWN"] == "true"
|
|
34
|
+
Brut::CLI::Commands::HelpInMarkdown
|
|
35
|
+
else
|
|
36
|
+
Brut::CLI::Commands::Help
|
|
37
|
+
end
|
|
33
38
|
brut_provided_help_requested = false
|
|
34
39
|
app_option_parser = new_option_parser(app_command.name) do |opts|
|
|
35
40
|
opts.banner = app_command.description
|
|
@@ -51,7 +56,7 @@ class Brut::CLI::ParsedCommandLine
|
|
|
51
56
|
end
|
|
52
57
|
|
|
53
58
|
help_command = if brut_provided_help_requested
|
|
54
|
-
|
|
59
|
+
help_command_class.new(app_command,app_option_parser)
|
|
55
60
|
end
|
|
56
61
|
|
|
57
62
|
command = app_command
|
|
@@ -83,7 +88,7 @@ class Brut::CLI::ParsedCommandLine
|
|
|
83
88
|
end
|
|
84
89
|
remaining_argv = command_option_parser.parse!(remaining_argv, into: options)
|
|
85
90
|
if brut_provided_help_requested
|
|
86
|
-
help_command =
|
|
91
|
+
help_command = help_command_class.new(command,command_option_parser)
|
|
87
92
|
elsif help_command
|
|
88
93
|
help_command.option_parser = command_option_parser
|
|
89
94
|
end
|
|
@@ -147,8 +152,7 @@ private
|
|
|
147
152
|
"Project environment, e.g. test, development, production. Default depends on the command")
|
|
148
153
|
opts.on("--log-level=LOG_LEVEL", [ "debug", "info", "warn", "error", "fatal" ],
|
|
149
154
|
"Log level, which should be debug, info, warn, error, or fatal. Defaults to error")
|
|
150
|
-
opts.on("--verbose", "Set log level to debug, and show log messages on stdout")
|
|
151
|
-
opts.on("--debug", "Set log level to debug, and show log messages on stdout")
|
|
155
|
+
opts.on("--debug", "--verbose", "Set log level to debug, and show log messages on stdout")
|
|
152
156
|
opts.on("--quiet", "Set log level to error")
|
|
153
157
|
opts.on("--log-file=FILE",
|
|
154
158
|
"Path to a file where log messages are written. Defaults to $XDG_CACHE_HOME/brut/logs/#{app_name}.log")
|
data/lib/brut/framework/mcp.rb
CHANGED
|
@@ -439,6 +439,7 @@ private
|
|
|
439
439
|
if defined?(OpenTelemetry::Instrumentation::Sidekiq)
|
|
440
440
|
c.use 'OpenTelemetry::Instrumentation::Sidekiq', {
|
|
441
441
|
span_naming: :job_class,
|
|
442
|
+
propagation_style: :child, # XXX: Configurable?
|
|
442
443
|
}
|
|
443
444
|
else
|
|
444
445
|
SemanticLogger[self.class].info "OpenTelemetry::Instrumentation::Sidekiq is not loaded, so Sidekiq traces will not be captured"
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
class Brut::FrontEnd::AssetMetadata
|
|
5
5
|
|
|
6
6
|
# @param [String] asset_metadata_file to the asset metadata file
|
|
7
|
-
# @param [IO] out IO on which to write messaging
|
|
8
7
|
def initialize(asset_metadata_file:,logger: :use_default)
|
|
9
8
|
@asset_metadata_file = asset_metadata_file
|
|
10
9
|
@logger = if logger == :use_default
|
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
# Extended by {Brut::FrontEnd::Form} to allow declaring inputs.
|
|
1
|
+
# Extended by {Brut::FrontEnd::Form} to allow declaring inputs. This module creates methods per input on the form passed to your handlers. For example, if you have an `input :book_title`, then `form.book_title` will be available to access the value of the "book_title" input.
|
|
2
|
+
#
|
|
3
|
+
# There are two methods that could be created, per input. Examples below use
|
|
4
|
+
# `book_title` as the attribute name
|
|
5
|
+
#
|
|
6
|
+
# * `#book_title` - returns {Brut::FrontEnd::Forms::Input#value}, which is always a string.
|
|
7
|
+
# * `#book_title_coerced` - returns {Brut::FrontEnd::Forms::Input#typed_value}, which is always the correct type for the input **or `nil` if type coercion failed**. Only call this once you have checked for constraint violations
|
|
8
|
+
#
|
|
9
|
+
# For indexed parameters, the above methods require the index to be passed,
|
|
10
|
+
# e.g. `form.book_title_coerced(4)`. For non-indexed parameters, the index may
|
|
11
|
+
# not be passed.
|
|
12
|
+
#
|
|
13
|
+
# Do not use this module directly. Instead, call {#input} or {#select}
|
|
2
14
|
# from within your form's class definition.
|
|
3
15
|
module Brut::FrontEnd::Forms::InputDeclarations
|
|
4
16
|
# Declares an input for this form, to be modeled via an HTML `<INPUT>` tag.
|
|
@@ -59,11 +71,22 @@ module Brut::FrontEnd::Forms::InputDeclarations
|
|
|
59
71
|
end
|
|
60
72
|
self.input(input_definition.name, index:).value
|
|
61
73
|
end
|
|
74
|
+
define_method "#{input_definition.name}_coerced" do |index=nil|
|
|
75
|
+
if index.nil?
|
|
76
|
+
raise ArgumentError,"#{input_definition.name} is an array - you must provide an index to access one of its values"
|
|
77
|
+
end
|
|
78
|
+
self.input(input_definition.name, index:).typed_value
|
|
79
|
+
end
|
|
62
80
|
define_method "#{input_definition.name}_each" do |&block|
|
|
63
81
|
self.inputs(input_definition.name).each_with_index do |input,i|
|
|
64
82
|
block.(input.value,i)
|
|
65
83
|
end
|
|
66
84
|
end
|
|
85
|
+
define_method "#{input_definition.name}_each_coerced" do |&block|
|
|
86
|
+
self.inputs(input_definition.name).each_with_index do |input,i|
|
|
87
|
+
block.(input.typed_value,i)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
67
90
|
else
|
|
68
91
|
define_method input_definition.name do |index_that_should_be_omitted=nil|
|
|
69
92
|
if !index_that_should_be_omitted.nil?
|
|
@@ -71,6 +94,12 @@ module Brut::FrontEnd::Forms::InputDeclarations
|
|
|
71
94
|
end
|
|
72
95
|
self.input(input_definition.name, index: 0).value
|
|
73
96
|
end
|
|
97
|
+
define_method "#{input_definition.name}_coerced" do |index_that_should_be_omitted=nil|
|
|
98
|
+
if !index_that_should_be_omitted.nil?
|
|
99
|
+
raise ArgumentError,"#{input_definition.name} is not an array - do not provide an index when accessing its value"
|
|
100
|
+
end
|
|
101
|
+
self.input(input_definition.name, index: 0).typed_value
|
|
102
|
+
end
|
|
74
103
|
end
|
|
75
104
|
end
|
|
76
105
|
|
|
@@ -15,9 +15,10 @@ class Brut::SpecSupport::E2ETestServer
|
|
|
15
15
|
# from the given bin dir
|
|
16
16
|
#
|
|
17
17
|
# @param [Pathname] bin_dir path to where the app's Brut-provide CLI apps are installed
|
|
18
|
-
def initialize(bin_dir:)
|
|
19
|
-
@bin_dir
|
|
20
|
-
@pid
|
|
18
|
+
def initialize(bin_dir:, start_timeout_seconds: nil)
|
|
19
|
+
@bin_dir = bin_dir
|
|
20
|
+
@pid = nil
|
|
21
|
+
@start_timeout_seconds = start_timeout_seconds || 5
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
# Starts the server. Returns when the server has started
|
|
@@ -66,7 +67,7 @@ private
|
|
|
66
67
|
|
|
67
68
|
def is_port_open?(ip, port)
|
|
68
69
|
begin
|
|
69
|
-
Timeout::timeout(
|
|
70
|
+
Timeout::timeout(@start_timeout_seconds) do
|
|
70
71
|
loop do
|
|
71
72
|
begin
|
|
72
73
|
logger.debug "Attemping to conenct to '#{ip}' on port '#{port}'"
|
data/lib/brut/tui/event_loop.rb
CHANGED
|
@@ -112,7 +112,11 @@ private
|
|
|
112
112
|
errors.each do
|
|
113
113
|
$stderr.puts("FATAL Exception: #{it.exception.class}: #{it.exception.message}\n #{it.exception.backtrace.join("\n ")}")
|
|
114
114
|
end
|
|
115
|
-
|
|
115
|
+
if errors.any?
|
|
116
|
+
exit 1
|
|
117
|
+
else
|
|
118
|
+
exit 0
|
|
119
|
+
end
|
|
116
120
|
else
|
|
117
121
|
errors.each { @queue.unshift(Brut::TUI::Events::Exception.new(it)) }
|
|
118
122
|
end
|
data/lib/brut/version.rb
CHANGED
data/templates/Base/bin/console
CHANGED
data/templates/Base/bin/release
CHANGED
|
@@ -19,7 +19,7 @@ echo "[ bin/release ] started"
|
|
|
19
19
|
echo "[ bin/release ] Creating DB if needed"
|
|
20
20
|
BRUT_CLI_RAISE_ON_ERROR=true bundle exec brut db create --env=production
|
|
21
21
|
echo "[ bin/release ] Migrating DB if needed"
|
|
22
|
-
BRUT_CLI_RAISE_ON_ERROR=true bundle exec
|
|
22
|
+
BRUT_CLI_RAISE_ON_ERROR=true bundle exec brut db migrate --env=production
|
|
23
23
|
|
|
24
24
|
# Add additional commands here as needed
|
|
25
25
|
|
data/templates/Base/dx/build
CHANGED
|
@@ -48,7 +48,7 @@ setup_playright_build_args() {
|
|
|
48
48
|
require_command "grep"
|
|
49
49
|
require_command "sed"
|
|
50
50
|
|
|
51
|
-
if [ ! -e "${SCRIPT_DIR}"
|
|
51
|
+
if [ ! -e "${SCRIPT_DIR}"/../Gemfile.lock ]; then
|
|
52
52
|
log "Could not find Gemfile.lock, which is needed to determine the playwright-ruby-client version"
|
|
53
53
|
log "Assuming your app is brand-new, this should be OK"
|
|
54
54
|
echo "# When this file was created, there was no Gemfile.lock, so" >> "${SCRIPT_DIR}"/build.args
|
|
@@ -57,7 +57,7 @@ setup_playright_build_args() {
|
|
|
57
57
|
echo "# encouraged to re-run \`dx/build\` to address this issue." >> "${SCRIPT_DIR}"/build.args
|
|
58
58
|
echo PLAYWRIGHT_VERSION=latest >> "${SCRIPT_DIR}"/build.args
|
|
59
59
|
else
|
|
60
|
-
PLAYWRIGHT_VERSION=$(grep playwright-ruby-client Gemfile.lock | grep '(' | sed 's/^.*(//' | sed 's/).*$//' | grep -v ^=)
|
|
60
|
+
PLAYWRIGHT_VERSION=$(grep playwright-ruby-client $SCRIPT_DIR/../Gemfile.lock | grep '(' | sed 's/^.*(//' | sed 's/).*$//' | grep -v ^=)
|
|
61
61
|
if [ -z "${PLAYWRIGHT_VERSION}" ]; then
|
|
62
62
|
log "Could not find precise version of playwright-ruby-client from Gemfile.lock"
|
|
63
63
|
log "This means that your playwright-ruby-client version and playwright NPM modules may be out of sync and may not work"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: brut
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.20.
|
|
4
|
+
version: 0.20.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Bryant Copeland
|
|
@@ -475,16 +475,16 @@ dependencies:
|
|
|
475
475
|
name: yard
|
|
476
476
|
requirement: !ruby/object:Gem::Requirement
|
|
477
477
|
requirements:
|
|
478
|
-
- -
|
|
478
|
+
- - '='
|
|
479
479
|
- !ruby/object:Gem::Version
|
|
480
|
-
version:
|
|
480
|
+
version: 0.9.37
|
|
481
481
|
type: :development
|
|
482
482
|
prerelease: false
|
|
483
483
|
version_requirements: !ruby/object:Gem::Requirement
|
|
484
484
|
requirements:
|
|
485
|
-
- -
|
|
485
|
+
- - '='
|
|
486
486
|
- !ruby/object:Gem::Version
|
|
487
|
-
version:
|
|
487
|
+
version: 0.9.37
|
|
488
488
|
description: An opinionated web framework build on web standards
|
|
489
489
|
email:
|
|
490
490
|
- davec@thirdtank.com
|
|
@@ -548,6 +548,7 @@ files:
|
|
|
548
548
|
- lib/brut/cli/commands/compound_command.rb
|
|
549
549
|
- lib/brut/cli/commands/execution_context.rb
|
|
550
550
|
- lib/brut/cli/commands/help.rb
|
|
551
|
+
- lib/brut/cli/commands/help_in_markdown.rb
|
|
551
552
|
- lib/brut/cli/commands/output_error.rb
|
|
552
553
|
- lib/brut/cli/commands/raise_error.rb
|
|
553
554
|
- lib/brut/cli/error.rb
|