brut 0.5.0 → 0.8.0
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/.gitignore +4 -0
- data/CHANGELOG.md +7 -0
- data/Dockerfile.dx +19 -0
- data/Gemfile.lock +1 -1
- data/README.md +19 -0
- data/assets/YouTubeThumb.pxd +0 -0
- data/bin/build +86 -0
- data/bin/ci +36 -0
- data/bin/docs +39 -9
- data/bin/publish +61 -0
- data/bin/setup +6 -0
- data/brut-css/bin/build +19 -0
- data/brut-css/bin/ci +19 -0
- data/brut-css/bin/docs +19 -0
- data/brut-css/bin/publish +21 -0
- data/brut-css/bin/setup +1 -0
- data/brut-css/package-lock.json +2 -2
- data/brut-css/package.json +1 -1
- data/brut-js/bin/build +15 -6
- data/brut-js/bin/docs +25 -0
- data/brut-js/bin/publish +21 -0
- data/brut-js/bin/setup +1 -0
- data/brut-js/dx +1 -0
- data/brut-js/package-lock.json +2 -2
- data/brut-js/package.json +1 -1
- data/brut.gemspec +2 -2
- data/brutrb.com/bin/setup +1 -0
- data/brutrb.com/getting-started.md +3 -0
- data/brutrb.com/overview.md +6 -0
- data/brutrb.com/tutorial.md +7 -3
- data/docs/404.html +2 -2
- data/docs/adrs.html +3 -3
- data/docs/ai.html +3 -3
- data/docs/assets/{app.D6BuVHo9.js → app.DyQLb4Ot.js} +1 -1
- data/docs/assets/chunks/@localSearchIndexroot.CmtZyrFA.js +1 -0
- data/docs/assets/chunks/{VPLocalSearchBox.BpvHMbx6.js → VPLocalSearchBox.T1iA-eJx.js} +1 -1
- data/docs/assets/chunks/{theme.wlAOvi2f.js → theme.ChwsbWjK.js} +2 -2
- data/docs/assets/{components.md.iLiv2E9X.js → components.md.DHh-NwKs.js} +3 -3
- data/docs/assets/{configuration.md.DmuAdsli.js → configuration.md.D8Wz3oJU.js} +1 -1
- data/docs/assets/{forms.md.D8aa_qI-.js → forms.md.BRE85eju.js} +1 -1
- data/docs/assets/{getting-started.md.DLplsDUd.js → getting-started.md.2ioiTe-B.js} +6 -3
- data/docs/assets/{getting-started.md.DLplsDUd.lean.js → getting-started.md.2ioiTe-B.lean.js} +1 -1
- data/docs/assets/overview.md.DlKiRRG_.js +1 -0
- data/docs/assets/overview.md.DlKiRRG_.lean.js +1 -0
- data/docs/assets/tutorial.md.BIb7XT6j.js +1 -0
- data/docs/assets/tutorial.md.BIb7XT6j.lean.js +1 -0
- data/docs/assets.html +3 -3
- data/docs/brut-js.html +3 -3
- data/docs/business-logic.html +3 -3
- data/docs/cli.html +3 -3
- data/docs/components.html +7 -7
- data/docs/configuration.html +5 -5
- data/docs/css.html +3 -3
- data/docs/custom-element-tests.html +3 -3
- data/docs/database-access.html +3 -3
- data/docs/database-schema.html +3 -3
- data/docs/deployment.html +3 -3
- data/docs/dev-environment.html +3 -3
- data/docs/dir-structure.html +3 -3
- data/docs/doc-conventions.html +3 -3
- data/docs/end-to-end-tests.html +3 -3
- data/docs/features.html +3 -3
- data/docs/flash-and-session.html +3 -3
- data/docs/form-constraints.html +3 -3
- data/docs/forms.html +5 -5
- data/docs/getting-started.html +9 -6
- data/docs/handlers.html +3 -3
- data/docs/hashmap.json +1 -1
- data/docs/hooks.html +3 -3
- data/docs/i18n.html +3 -3
- data/docs/index.html +3 -3
- data/docs/instrumentation.html +3 -3
- data/docs/javascript.html +3 -3
- data/docs/jobs.html +3 -3
- data/docs/keyword-injection.html +3 -3
- data/docs/layouts.html +3 -3
- data/docs/lsp.html +3 -3
- data/docs/markdown-examples.html +3 -3
- data/docs/middleware.html +3 -3
- data/docs/overview.html +5 -5
- data/docs/pages.html +3 -3
- data/docs/recipes/alternate-layouts.html +3 -3
- data/docs/recipes/authentication.html +3 -3
- data/docs/recipes/blank-layouts.html +3 -3
- data/docs/recipes/custom-flash.html +3 -3
- data/docs/recipes/indexed-forms.html +3 -3
- data/docs/recipes/migrations.html +3 -3
- data/docs/recipes/text-field-component.html +3 -3
- data/docs/roadmap.html +3 -3
- data/docs/routes.html +3 -3
- data/docs/security.html +3 -3
- data/docs/seed-data.html +3 -3
- data/docs/space-time-continuum.html +3 -3
- data/docs/tutorial.html +5 -5
- data/docs/unit-tests.html +3 -3
- data/docs/why.html +3 -3
- data/lib/brut/framework/mcp.rb +1 -1
- data/lib/brut/front_end/components/form_tag.rb +2 -2
- data/lib/brut/version.rb +1 -1
- data/mkbrut/.gitignore +16 -0
- data/mkbrut/CODE_OF_CONDUCT.txt +100 -0
- data/mkbrut/Gemfile +3 -0
- data/mkbrut/Gemfile.lock +19 -0
- data/mkbrut/LICENSE.txt +370 -0
- data/mkbrut/README.md +145 -0
- data/mkbrut/Rakefile +2 -0
- data/mkbrut/bin/build +36 -0
- data/mkbrut/bin/ci +19 -0
- data/mkbrut/bin/docs +19 -0
- data/mkbrut/bin/publish +129 -0
- data/mkbrut/bin/rake +16 -0
- data/mkbrut/bin/setup +30 -0
- data/mkbrut/brut-welcome.png +0 -0
- data/mkbrut/deploy/.dockerignore +2 -0
- data/mkbrut/deploy/Dockerfile +25 -0
- data/mkbrut/exe/mkbrut +5 -0
- data/mkbrut/lib/mkbrut/app.rb +79 -0
- data/mkbrut/lib/mkbrut/app_id.rb +8 -0
- data/mkbrut/lib/mkbrut/app_name.rb +29 -0
- data/mkbrut/lib/mkbrut/app_options.rb +36 -0
- data/mkbrut/lib/mkbrut/base.rb +57 -0
- data/mkbrut/lib/mkbrut/cli.rb +107 -0
- data/mkbrut/lib/mkbrut/erb_binding_delegate.rb +20 -0
- data/mkbrut/lib/mkbrut/internet_identifier.rb +32 -0
- data/mkbrut/lib/mkbrut/invalid_identifier.rb +4 -0
- data/mkbrut/lib/mkbrut/ops/add_css_import.rb +42 -0
- data/mkbrut/lib/mkbrut/ops/add_i18n_message.rb +74 -0
- data/mkbrut/lib/mkbrut/ops/add_method.rb +48 -0
- data/mkbrut/lib/mkbrut/ops/append_to_file.rb +20 -0
- data/mkbrut/lib/mkbrut/ops/base_op.rb +21 -0
- data/mkbrut/lib/mkbrut/ops/copy_file.rb +12 -0
- data/mkbrut/lib/mkbrut/ops/insert_code_in_method.rb +58 -0
- data/mkbrut/lib/mkbrut/ops/insert_route.rb +52 -0
- data/mkbrut/lib/mkbrut/ops/mkdir.rb +13 -0
- data/mkbrut/lib/mkbrut/ops/prism_parsing_op.rb +70 -0
- data/mkbrut/lib/mkbrut/ops/render_template.rb +26 -0
- data/mkbrut/lib/mkbrut/ops/skip_file.rb +10 -0
- data/mkbrut/lib/mkbrut/ops.rb +16 -0
- data/mkbrut/lib/mkbrut/organization.rb +5 -0
- data/mkbrut/lib/mkbrut/prefix.rb +26 -0
- data/mkbrut/lib/mkbrut/prefixed_io.rb +16 -0
- data/mkbrut/lib/mkbrut/segments/bare_bones.rb +185 -0
- data/mkbrut/lib/mkbrut/segments/demo.rb +121 -0
- data/mkbrut/lib/mkbrut/segments/heroku.rb +30 -0
- data/mkbrut/lib/mkbrut/segments/sidekiq.rb +3 -0
- data/mkbrut/lib/mkbrut/segments.rb +8 -0
- data/mkbrut/lib/mkbrut/version.rb +3 -0
- data/mkbrut/lib/mkbrut/versions.rb +13 -0
- data/mkbrut/lib/mkbrut.rb +18 -0
- data/mkbrut/mkbrut.gemspec +32 -0
- data/mkbrut/templates/Base/.dockerignore +25 -0
- data/mkbrut/templates/Base/.env.development.erb +60 -0
- data/mkbrut/templates/Base/.env.test.erb +8 -0
- data/mkbrut/templates/Base/.gitignore +31 -0
- data/mkbrut/templates/Base/.projections.json +59 -0
- data/mkbrut/templates/Base/Dockerfile.dx +205 -0
- data/mkbrut/templates/Base/Gemfile.erb +53 -0
- data/mkbrut/templates/Base/Procfile.development +5 -0
- data/mkbrut/templates/Base/Procfile.test +1 -0
- data/mkbrut/templates/Base/README.md +4 -0
- data/mkbrut/templates/Base/README.md.erb +40 -0
- data/mkbrut/templates/Base/app/bootstrap.rb +61 -0
- data/mkbrut/templates/Base/app/config/i18n/en/1_defaults.rb +128 -0
- data/mkbrut/templates/Base/app/config/i18n/en/2_app.rb +24 -0
- data/mkbrut/templates/Base/app/public/static/manifest.json.erb +33 -0
- data/mkbrut/templates/Base/app/src/app.rb.erb +37 -0
- data/mkbrut/templates/Base/app/src/back_end/data_models/app_data_model.rb +5 -0
- data/mkbrut/templates/Base/app/src/back_end/data_models/db.rb +19 -0
- data/mkbrut/templates/Base/app/src/back_end/data_models/migrations/20240101130000_citext.rb +6 -0
- data/mkbrut/templates/Base/app/src/back_end/data_models/seed/seed_data.rb +9 -0
- data/mkbrut/templates/Base/app/src/front_end/components/app_component.rb +8 -0
- data/mkbrut/templates/Base/app/src/front_end/components/custom_element_registration.rb.erb +7 -0
- data/mkbrut/templates/Base/app/src/front_end/css/index.css +2 -0
- data/mkbrut/templates/Base/app/src/front_end/css/svgs.css +12 -0
- data/mkbrut/templates/Base/app/src/front_end/forms/app_form.rb +4 -0
- data/mkbrut/templates/Base/app/src/front_end/handlers/app_handler.rb +4 -0
- data/mkbrut/templates/Base/app/src/front_end/images/LogoPylon.png +0 -0
- data/mkbrut/templates/Base/app/src/front_end/images/LogoTransit.png +0 -0
- data/mkbrut/templates/Base/app/src/front_end/images/apple-touch-icon-120x120.png +0 -0
- data/mkbrut/templates/Base/app/src/front_end/images/apple-touch-icon-152x152.png +0 -0
- data/mkbrut/templates/Base/app/src/front_end/images/apple-touch-icon-167x167.png +0 -0
- data/mkbrut/templates/Base/app/src/front_end/images/apple-touch-icon-180x180.png +0 -0
- data/mkbrut/templates/Base/app/src/front_end/images/favicon.ico +0 -0
- data/mkbrut/templates/Base/app/src/front_end/images/icon.png +0 -0
- data/mkbrut/templates/Base/app/src/front_end/images/mkicons.sh +6 -0
- data/mkbrut/templates/Base/app/src/front_end/js/index.js +6 -0
- data/mkbrut/templates/Base/app/src/front_end/layouts/default_layout.rb.erb +73 -0
- data/mkbrut/templates/Base/app/src/front_end/pages/app_page.rb +11 -0
- data/mkbrut/templates/Base/app/src/front_end/pages/home_page.rb +62 -0
- data/mkbrut/templates/Base/app/src/front_end/support/app_session.rb +6 -0
- data/mkbrut/templates/Base/app/src/front_end/svgs/README.md +5 -0
- data/mkbrut/templates/Base/app/src/front_end/svgs/comment-button.svg +59 -0
- data/mkbrut/templates/Base/bin/README.md.erb +5 -0
- data/mkbrut/templates/Base/bin/build-assets +7 -0
- data/mkbrut/templates/Base/bin/ci +39 -0
- data/mkbrut/templates/Base/bin/console +31 -0
- data/mkbrut/templates/Base/bin/db +9 -0
- data/mkbrut/templates/Base/bin/dbconsole +51 -0
- data/mkbrut/templates/Base/bin/dev +25 -0
- data/mkbrut/templates/Base/bin/release +26 -0
- data/mkbrut/templates/Base/bin/run +86 -0
- data/mkbrut/templates/Base/bin/scaffold +9 -0
- data/mkbrut/templates/Base/bin/setup +256 -0
- data/mkbrut/templates/Base/bin/startup-message +65 -0
- data/mkbrut/templates/Base/bin/test +9 -0
- data/mkbrut/templates/Base/bin/test-server +29 -0
- data/mkbrut/templates/Base/bin/watch-and-build-assets +37 -0
- data/mkbrut/templates/Base/config.ru +16 -0
- data/mkbrut/templates/Base/docker-compose.dx.yml +92 -0
- data/mkbrut/templates/Base/dx/README.md +28 -0
- data/mkbrut/templates/Base/dx/bash_customizations +12 -0
- data/mkbrut/templates/Base/dx/bash_customizations.local +8 -0
- data/mkbrut/templates/Base/dx/build +107 -0
- data/mkbrut/templates/Base/dx/docker-compose.env.erb +25 -0
- data/mkbrut/templates/Base/dx/dx.sh.lib +137 -0
- data/mkbrut/templates/Base/dx/exec +68 -0
- data/mkbrut/templates/Base/dx/prune +19 -0
- data/mkbrut/templates/Base/dx/show-help-in-app-container-then-wait.sh +38 -0
- data/mkbrut/templates/Base/dx/start +30 -0
- data/mkbrut/templates/Base/dx/stop +23 -0
- data/mkbrut/templates/Base/package.json.erb +37 -0
- data/mkbrut/templates/Base/puma.config.rb +53 -0
- data/mkbrut/templates/Base/specs/e2e/home_page.spec.rb.erb +23 -0
- data/mkbrut/templates/Base/specs/front_end/js/SpecHelper.js +24 -0
- data/mkbrut/templates/Base/specs/front_end/pages/home_page.spec.rb +22 -0
- data/mkbrut/templates/Base/specs/lint_factories.spec.rb +7 -0
- data/mkbrut/templates/Base/specs/spec_helper.rb +78 -0
- data/mkbrut/templates/Base/specs/support.rb +2 -0
- data/mkbrut/templates/segments/BareBones/app/src/front_end/handlers/trigger_exception_handler.rb +24 -0
- data/mkbrut/templates/segments/BareBones/app/src/front_end/js/Example.js.erb +49 -0
- data/mkbrut/templates/segments/BareBones/specs/front_end/handlers/trigger_exception_handler.spec.rb +41 -0
- data/mkbrut/templates/segments/BareBones/specs/front_end/js/Example.spec.js.erb +38 -0
- data/mkbrut/templates/segments/Demo/app/src/back_end/data_models/db/guestbook_message.rb +3 -0
- data/mkbrut/templates/segments/Demo/app/src/back_end/data_models/migrations/20250628194124_guestbook.rb +14 -0
- data/mkbrut/templates/segments/Demo/app/src/front_end/components/flash_component.rb +36 -0
- data/mkbrut/templates/segments/Demo/app/src/front_end/css/constraint-violations.css +18 -0
- data/mkbrut/templates/segments/Demo/app/src/front_end/css/fonts.css +19 -0
- data/mkbrut/templates/segments/Demo/app/src/front_end/fonts/monaspace-xenon.ttf +0 -0
- data/mkbrut/templates/segments/Demo/app/src/front_end/forms/guestbook_message_form.rb +4 -0
- data/mkbrut/templates/segments/Demo/app/src/front_end/handlers/guestbook_message_handler.rb +64 -0
- data/mkbrut/templates/segments/Demo/app/src/front_end/pages/guestbook_page/message_component.rb +41 -0
- data/mkbrut/templates/segments/Demo/app/src/front_end/pages/guestbook_page.rb +43 -0
- data/mkbrut/templates/segments/Demo/app/src/front_end/pages/new_guestbook_message_page.rb +64 -0
- data/mkbrut/templates/segments/Demo/specs/back_end/data_models/db/guestbook_message.spec.rb +5 -0
- data/mkbrut/templates/segments/Demo/specs/e2e/guest_message.spec.rb +54 -0
- data/mkbrut/templates/segments/Demo/specs/factories/db/guestbook_message.factory.rb +7 -0
- data/mkbrut/templates/segments/Demo/specs/front_end/components/flash_component.spec.rb +5 -0
- data/mkbrut/templates/segments/Demo/specs/front_end/handlers/guestbook_message_handler.spec.rb +122 -0
- data/mkbrut/templates/segments/Demo/specs/front_end/pages/guestbook_page/message_component.spec.rb +5 -0
- data/mkbrut/templates/segments/Demo/specs/front_end/pages/guestbook_page.spec.rb +52 -0
- data/mkbrut/templates/segments/Demo/specs/front_end/pages/new_guestbook_message_page.spec.rb +5 -0
- data/mkbrut/templates/segments/Heroku/bin/deploy +11 -0
- data/mkbrut/templates/segments/Heroku/deploy/Dockerfile +125 -0
- data/mkbrut/templates/segments/Heroku/deploy/docker-entrypoint +15 -0
- data/mkbrut/templates/segments/Heroku/deploy/heroku_config.rb +26 -0
- metadata +185 -21
- data/docs/assets/chunks/@localSearchIndexroot.COP2Bcmp.js +0 -1
- data/docs/assets/overview.md.iMnwLO4x.js +0 -1
- data/docs/assets/overview.md.iMnwLO4x.lean.js +0 -1
- data/docs/assets/tutorial.md.BYXj4cOu.js +0 -1
- data/docs/assets/tutorial.md.BYXj4cOu.lean.js +0 -1
- /data/docs/assets/{components.md.iLiv2E9X.lean.js → components.md.DHh-NwKs.lean.js} +0 -0
- /data/docs/assets/{configuration.md.DmuAdsli.lean.js → configuration.md.D8Wz3oJU.lean.js} +0 -0
- /data/docs/assets/{forms.md.D8aa_qI-.lean.js → forms.md.BRE85eju.lean.js} +0 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
require "yaml"
|
5
|
+
require "optparse"
|
6
|
+
|
7
|
+
option_parser = OptionParser.new do |opts|
|
8
|
+
opts.banner = "Usage: bin/startup-message\n\n Outputs a message about where the dev server is running\n\nENVIRONMENT VARIABLES\n\n PORT - the port configured for bin/run"
|
9
|
+
end
|
10
|
+
option_parser.parse!
|
11
|
+
|
12
|
+
docker_compose_file = Pathname.new(__FILE__).dirname / ".." / "docker-compose.dx.yml"
|
13
|
+
|
14
|
+
port_config = nil
|
15
|
+
error = nil
|
16
|
+
|
17
|
+
if docker_compose_file.exist?
|
18
|
+
docker_compose = YAML.load_file(docker_compose_file)
|
19
|
+
|
20
|
+
docker_port = begin
|
21
|
+
ENV.fetch("PORT")
|
22
|
+
rescue KeyError
|
23
|
+
$stderr.puts "ERROR: The PORT environment variable is not set."
|
24
|
+
$stderr.puts " Please set it to the port your app is running on."
|
25
|
+
exit 1
|
26
|
+
end
|
27
|
+
|
28
|
+
ports_config = docker_compose.dig("services", "app", "ports")
|
29
|
+
error = nil
|
30
|
+
if ports_config
|
31
|
+
port_config = ports_config.detect { |port_mapping|
|
32
|
+
host_port, container_port = port_mapping.split(":")
|
33
|
+
container_port.to_s == docker_port
|
34
|
+
}
|
35
|
+
if !port_config
|
36
|
+
error = "#{docker_compose_file} does not expose the port #{docker_port} for the 'app' service."
|
37
|
+
end
|
38
|
+
else
|
39
|
+
error = "#{docker_compose_file} does not contain a 'ports' section for the 'app' service."
|
40
|
+
end
|
41
|
+
else
|
42
|
+
error = "#{docker_compose_file} does not exist. This is assumed to be in placefor your dev environment"
|
43
|
+
end
|
44
|
+
if !error
|
45
|
+
sleep 2 # allow all other initial output from bin/dev to happen first
|
46
|
+
|
47
|
+
host_port = port_config.split(":")[0]
|
48
|
+
|
49
|
+
url = "http://localhost:#{host_port}"
|
50
|
+
|
51
|
+
$stdout.puts "Your app is now running at"
|
52
|
+
$stdout.puts
|
53
|
+
$stdout.puts " #{url}"
|
54
|
+
$stdout.puts
|
55
|
+
$stdout.flush # ensure this output happens immediately
|
56
|
+
else
|
57
|
+
$stderr.puts "WARN: #{$0} could not figure out what port the app is exposed on"
|
58
|
+
$stderr.puts
|
59
|
+
$stderr.puts " #{error}"
|
60
|
+
$stderr.puts
|
61
|
+
$stderr.puts " This won't stop your app from running, but it does mean"
|
62
|
+
$stderr.puts " there is some issue with your dev environment"
|
63
|
+
$stderr.flush # ensure this error output happens immediately
|
64
|
+
end
|
65
|
+
sleep
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
SCRIPT_DIR=$( cd -- "$( dirname -- "${0}" )" > /dev/null 2>&1 && pwd )
|
5
|
+
ROOT_DIR="${SCRIPT_DIR}/.."
|
6
|
+
|
7
|
+
usage() {
|
8
|
+
echo "Usage: $0"
|
9
|
+
echo
|
10
|
+
echo " Run the app in the test environment, suitable for end-to-end tests"
|
11
|
+
echo " This will build all assets first, but not rebuild or reload after that"
|
12
|
+
echo
|
13
|
+
}
|
14
|
+
|
15
|
+
for arg in "$@"; do
|
16
|
+
if [ "${arg}" = "-h" ] || [ "${arg}" = "--help" ] || [ "${arg}" = "help" ]; then
|
17
|
+
usage
|
18
|
+
exit 0
|
19
|
+
fi
|
20
|
+
done
|
21
|
+
|
22
|
+
RACK_ENV="test"
|
23
|
+
export RACK_ENV
|
24
|
+
echo "[ bin/test-server ] Building assets"
|
25
|
+
"${SCRIPT_DIR}"/build-assets
|
26
|
+
|
27
|
+
echo "[ bin/test-server ] Starting server"
|
28
|
+
PORT=6503 bin/run &
|
29
|
+
wait
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# This script exists to ensure that chokidar actually terminates when foreman stops all the processes.
|
4
|
+
# For whatever reason, if Procfile has the npx chokidar… invocation below, these processes are not
|
5
|
+
# stopped. Putting them into this script addresses that. Cool.
|
6
|
+
|
7
|
+
set -e
|
8
|
+
|
9
|
+
if [ -z "${1}" ] ; then
|
10
|
+
echo "[ $0 ] error: asset type required. Must be css, js, or images"
|
11
|
+
exit 65
|
12
|
+
fi
|
13
|
+
usage() {
|
14
|
+
echo "usage: $0 asset_type"
|
15
|
+
echo
|
16
|
+
echo " Sets up a watching/rebuild command for the given asset. Useful in dev only"
|
17
|
+
echo
|
18
|
+
echo " asset_types:"
|
19
|
+
echo
|
20
|
+
echo " - css"
|
21
|
+
echo " - js"
|
22
|
+
echo " - images"
|
23
|
+
echo
|
24
|
+
}
|
25
|
+
for arg in "${@}"; do
|
26
|
+
if [ "${arg}" = "-h" ] || [ "${arg}" = "--help" ] || [ "${arg}" = "help" ]; then
|
27
|
+
usage
|
28
|
+
exit 0
|
29
|
+
fi
|
30
|
+
done
|
31
|
+
|
32
|
+
asset_type=$1
|
33
|
+
watch_dir="app/src/front_end/${asset_type}/**/*"
|
34
|
+
build_command="bin/build-assets ${asset_type}"
|
35
|
+
|
36
|
+
export SHELL # chokidar needs this for reasons unknown to me
|
37
|
+
exec npx chokidar --initial --polling --command "${build_command}" "${watch_dir}"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative "app/bootstrap"
|
2
|
+
bootstrap = Bootstrap.new.bootstrap!
|
3
|
+
|
4
|
+
app = Rack::Builder.app do
|
5
|
+
use Rack::Session::Cookie,
|
6
|
+
key: "rack.session",
|
7
|
+
path: "/",
|
8
|
+
expire_after: 31_536_000,
|
9
|
+
same_site: :lax, # this allows links from other domains to send our cookies to us,
|
10
|
+
# but only if such links are direct/obvious to the user.
|
11
|
+
secret: ENV.fetch("SESSION_SECRET")
|
12
|
+
|
13
|
+
run bootstrap.rack_app
|
14
|
+
end
|
15
|
+
run app
|
16
|
+
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# This file is heavily documented to explain what is going on and why.
|
2
|
+
# If you are reading this, however, you now own this file and can
|
3
|
+
# change it how you like. Just be sure you understand how it works in the
|
4
|
+
# context of Dockerfile.dx and the files in dx/,
|
5
|
+
# which are referred to as the Workspace
|
6
|
+
#
|
7
|
+
# This file is used to run several Docker containers, based on images, together
|
8
|
+
# in a shared private network. All containers run by this file will be able to see
|
9
|
+
# each other over a network, but the only access your host (computer) will have to
|
10
|
+
# these services is via explicitly exposed ports.
|
11
|
+
|
12
|
+
services:
|
13
|
+
# 'app' is the service where all your dev tools will run. The tests will
|
14
|
+
# run in here as will the dev server.
|
15
|
+
#
|
16
|
+
# You interact with this container via `dx/exec`
|
17
|
+
app:
|
18
|
+
# IMAGE is defined in dx/docker-compose.env and is the name of an image
|
19
|
+
# built LOCALLY (never pushed to DockerHub) that has all the tools needed
|
20
|
+
# for developing your app installed into it.
|
21
|
+
image: ${IMAGE}
|
22
|
+
# This is magic that makes the Docker container stop much more quickly when
|
23
|
+
# you hit Ctrl-C.
|
24
|
+
init: true
|
25
|
+
# There are two types of volumes (drives) mounted.
|
26
|
+
volumes:
|
27
|
+
# This volume is your source code. Its source and target are the same
|
28
|
+
# so that stuff like language servers can work.
|
29
|
+
- type: bind
|
30
|
+
source: ${PWD}
|
31
|
+
target: ${PWD}
|
32
|
+
consistency: "consistent"
|
33
|
+
# This allows docker build commands run inside Docker, referred to
|
34
|
+
# as "docker out of docker". Essentially, Docker binaries installed into
|
35
|
+
# this container will access your host (you computer)'s Docker install.
|
36
|
+
# This is to allow it to build the production images.
|
37
|
+
- type: bind
|
38
|
+
source: "/var/run/docker.sock"
|
39
|
+
target: "/var/run/docker.sock"
|
40
|
+
# This is what is started up when you run `dx/start`. It just
|
41
|
+
# waits forever keeping the container running.
|
42
|
+
command: /home/appuser/show-help-in-app-container-then-wait.sh
|
43
|
+
# The working directory for any command, this is the same as your
|
44
|
+
# project root.
|
45
|
+
working_dir: ${PWD}
|
46
|
+
# This sets environment variables
|
47
|
+
environment:
|
48
|
+
# Because we'll install RubyGems inside our project (mostly to allow
|
49
|
+
# language servers to work), configuration in bash_customizations relies
|
50
|
+
# on this value being set
|
51
|
+
PROJECT_ROOT: ${PWD}
|
52
|
+
# This exposes ports from this running container to your localhost.
|
53
|
+
# In this case, we expose 6502, where the app runs, and 6503, where
|
54
|
+
# the test server runs.
|
55
|
+
#
|
56
|
+
# To change this, the port before the colon is where the app
|
57
|
+
# will be available on your localhost. The port AFTER the colon is where
|
58
|
+
# the app runs in the container. So: change the port before the colon, and
|
59
|
+
# don't change the one after.
|
60
|
+
#
|
61
|
+
# * 6502 - dev
|
62
|
+
# * 6503 - test server (run by E2E tests)
|
63
|
+
ports:
|
64
|
+
- "6502:6502"
|
65
|
+
- "6503:6503"
|
66
|
+
# This "service" runs Postgres. The service name ("postgres") is the host
|
67
|
+
# on which the service is available to other containers, namely from the
|
68
|
+
# app container. You cannot connect to thise service from your host (computer)
|
69
|
+
# directly without additional configuration.
|
70
|
+
postgres:
|
71
|
+
# This image is the name of the image from DockerHub that will be pulled
|
72
|
+
# down to run Postgres.
|
73
|
+
image: postgres:16.4
|
74
|
+
pull_policy: "missing"
|
75
|
+
environment:
|
76
|
+
# Postgres will not work without being told the password. The most
|
77
|
+
# direct way to do that is via this environment variable.
|
78
|
+
POSTGRES_PASSWORD: postgres
|
79
|
+
# This runes otel-deskop-viewer, which will receive OpenTelemetry traces
|
80
|
+
# from your app. You can connect to this to observe those traces.
|
81
|
+
otel-desktop-viewer:
|
82
|
+
# The otel-desktop-viewer maintainers do not maintain a Docker
|
83
|
+
# image of the app. I have made one available on my DockerHub account.
|
84
|
+
# If you want to build your own, see
|
85
|
+
# https://github.com/CtrlSpice/otel-desktop-viewer?tab=readme-ov-file#via-docker
|
86
|
+
# When you build that image, change the value for image: below to the image
|
87
|
+
# name you chose.
|
88
|
+
image: davetron5000/otel-desktop-viewer:alpine-3
|
89
|
+
# This runs internally on port 8000 but will be available
|
90
|
+
# on port 6504 of your machine.
|
91
|
+
ports:
|
92
|
+
- "6504:8000"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Workspace Commands
|
2
|
+
|
3
|
+
These commands manage the Workspace, AKA the part of the development environment that
|
4
|
+
runs on your computer (sometimes called the *host*).
|
5
|
+
|
6
|
+
These are all written in Bash as that is the only environment that can be relied upon to exist on any operating system.
|
7
|
+
|
8
|
+
These are designed to be somewhat agnostic of your app and Brut may update some of
|
9
|
+
these files if changes are needed. All app-specific configuration is consolidated
|
10
|
+
into just a few files.
|
11
|
+
|
12
|
+
These files are owned by Brut and you should avoid editing them:
|
13
|
+
|
14
|
+
* `bash_customizations` - Bash configuration
|
15
|
+
* `build` - Builds the development docker image
|
16
|
+
* `dx.sh.lib` - Shared bash functions
|
17
|
+
* `exec` - Run commands inside a container
|
18
|
+
* `prune` - Remove unused containers
|
19
|
+
* `README.md` - This file
|
20
|
+
* `show-help-in-app-container-then-wait.sh` - Runs inside the app container to keep
|
21
|
+
the container up
|
22
|
+
* `start` - starts the Workspace/dev environment
|
23
|
+
* `stop` - stops the Workspace/dev environment
|
24
|
+
|
25
|
+
These files contain project-specific information and Brut will not change them:
|
26
|
+
|
27
|
+
* `docker-compose.env` - Configuration values.
|
28
|
+
* `bash_customizations.local` - Per-developer bash configuration, **project specific**, **developer specific**, **do not check into version control**.
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# This sets up RubyGems and Bundler so they install
|
2
|
+
# all gems inside this project's root and not into the system
|
3
|
+
# location. This allows LSP servers to work more easily.
|
4
|
+
if [ ! -n "$PROJECT_ROOT" ]; then
|
5
|
+
echo "[ bash_customizations ] WARNING: PROJECT_ROOT is not set - this will break RubyGems"
|
6
|
+
fi
|
7
|
+
export GEM_HOME=${PROJECT_ROOT}/local-gems/gem-home
|
8
|
+
export PATH=${PATH}:${GEM_HOME}/bin
|
9
|
+
# This sets up the Node version so we don't have to do it before every. single.
|
10
|
+
# shell. invocation.
|
11
|
+
. ~/.nvm/nvm.sh
|
12
|
+
nvm use default
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# Insert developer-specifilc Bash customizations here.
|
2
|
+
# This file is not checked into version control, so you
|
3
|
+
# are safe to export EDITOR=vim and avoid any guff from
|
4
|
+
# co-workers.
|
5
|
+
|
6
|
+
# Sets up a multi-line prompt since the working directory
|
7
|
+
# may be very deep. Customize or change at your leisure.
|
8
|
+
PS1='\[\e[35m\]docker-container\[\e[0m\] - \[\e[37m\]\w\n\[\e[0m\]> '
|
@@ -0,0 +1,107 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
SCRIPT_DIR=$( cd -- "$( dirname -- "${0}" )" > /dev/null 2>&1 && pwd )
|
6
|
+
|
7
|
+
. "${SCRIPT_DIR}/dx.sh.lib"
|
8
|
+
|
9
|
+
read_custom_build_args() {
|
10
|
+
build_args_file="${SCRIPT_DIR}/build.args"
|
11
|
+
if [ -e "${build_args_file}" ]; then
|
12
|
+
for arg in `grep -v '^#' "${build_args_file}"`; do
|
13
|
+
BUILD_ARGS+=(--build-arg ${arg})
|
14
|
+
done
|
15
|
+
fi
|
16
|
+
}
|
17
|
+
|
18
|
+
setup_local_user_build_args() {
|
19
|
+
require_command "id"
|
20
|
+
require_command "uname"
|
21
|
+
user_uid=$(id -u)
|
22
|
+
user_gid=$(id -g)
|
23
|
+
docker_gid=
|
24
|
+
sadly_user_must_be_added_to_root=
|
25
|
+
OS=$(uname)
|
26
|
+
if [ "${OS}" == "Darwin" ] ; then
|
27
|
+
docker_gid=$(stat -f %g /var/run/docker.sock)
|
28
|
+
sadly_user_must_be_added_to_root="0,"
|
29
|
+
else
|
30
|
+
if [ "${OS}" == "Linux" ] ; then
|
31
|
+
docker_gid=$(stat -c %g /var/run/docker.sock)
|
32
|
+
else
|
33
|
+
log "Could not determine OS, which is needed to know how to invoke stat to figure out the group id of /var/run/docker.sock"
|
34
|
+
log "Docker commands will not work"
|
35
|
+
fi
|
36
|
+
fi
|
37
|
+
echo user_uid=${user_uid} >> "${SCRIPT_DIR}"/build.args
|
38
|
+
echo user_gid=${user_gid} >> "${SCRIPT_DIR}"/build.args
|
39
|
+
echo docker_gid=${docker_gid} >> "${SCRIPT_DIR}"/build.args
|
40
|
+
echo sadly_user_must_be_added_to_root=${sadly_user_must_be_added_to_root} >> "${SCRIPT_DIR}"/build.args
|
41
|
+
}
|
42
|
+
|
43
|
+
initialize_build_args() {
|
44
|
+
echo "# This is generated - see build.pre" > "${SCRIPT_DIR}"/build.args
|
45
|
+
}
|
46
|
+
|
47
|
+
setup_playright_build_args() {
|
48
|
+
require_command "grep"
|
49
|
+
require_command "sed"
|
50
|
+
|
51
|
+
if [ ! -e "${SCRIPT_DIR}"/Gemfile.lock ]; then
|
52
|
+
log "Could not find Gemfile.lock, which is needed to determine the playwright-ruby-client version"
|
53
|
+
log "Assuming your app is brand-new, this should be OK"
|
54
|
+
echo "# When this file was created, there was no Gemfile.lock, so" >> "${SCRIPT_DIR}"/build.args
|
55
|
+
echo "# it was not possible to determine which version of Playright was set up." >> "${SCRIPT_DIR}"/build.args
|
56
|
+
echo "# Once you've build your app and installed gems, you are " >> "${SCRIPT_DIR}"/build.args
|
57
|
+
echo "# encouraged to re-run \`dx/build\` to address this issue." >> "${SCRIPT_DIR}"/build.args
|
58
|
+
echo PLAYWRIGHT_VERSION=latest >> "${SCRIPT_DIR}"/build.args
|
59
|
+
else
|
60
|
+
PLAYWRIGHT_VERSION=$(grep playwright-ruby-client Gemfile.lock | grep '(' | sed 's/^.*(//' | sed 's/).*$//' | grep -v ^=)
|
61
|
+
if [ -z "${PLAYWRIGHT_VERSION}" ]; then
|
62
|
+
log "Could not find precise version of playwright-ruby-client from Gemfile.lock"
|
63
|
+
log "This means that your playwright-ruby-client version and playwright NPM modules may be out of sync and may not work"
|
64
|
+
echo "# When this file was created, Gemfile.lock did not" >> "${SCRIPT_DIR}"/build.args
|
65
|
+
echo "# contain playwrith-ruby-client. This means it" >> "${SCRIPT_DIR}"/build.args
|
66
|
+
echo "# it was not possible to determine which version of" >> "${SCRIPT_DIR}"/build.args
|
67
|
+
echo "# Playright was set up. If you aren't using Playwright," >> "${SCRIPT_DIR}"/build.args
|
68
|
+
echo "# that's fine, this won't cause issues" >> "${SCRIPT_DIR}"/build.args
|
69
|
+
echo "# If you ARE using Playwright, something may be wrong with your setup" >> "${SCRIPT_DIR}"/build.args
|
70
|
+
echo PLAYWRIGHT_VERSION=latest >> "${SCRIPT_DIR}"/build.args
|
71
|
+
else
|
72
|
+
echo PLAYWRIGHT_VERSION=${PLAYWRIGHT_VERSION} >> "${SCRIPT_DIR}"/build.args
|
73
|
+
fi
|
74
|
+
fi
|
75
|
+
}
|
76
|
+
|
77
|
+
require_command "docker"
|
78
|
+
load_docker_compose_env
|
79
|
+
|
80
|
+
usage_on_help "Builds the Docker image based on the Dockerfile" "" "build.pre" "build.post" "${@}"
|
81
|
+
|
82
|
+
if ! exec_hook_if_exists "build.pre" Dockerfile.dx "${IMAGE}"; then
|
83
|
+
log "build.pre failed"
|
84
|
+
exit 1
|
85
|
+
fi
|
86
|
+
BUILD_ARGS=()
|
87
|
+
|
88
|
+
initialize_build_args
|
89
|
+
setup_local_user_build_args
|
90
|
+
setup_playright_build_args
|
91
|
+
read_custom_build_args
|
92
|
+
|
93
|
+
docker build \
|
94
|
+
--file Dockerfile.dx \
|
95
|
+
--tag "${IMAGE}" \
|
96
|
+
${BUILD_ARGS[@]} \
|
97
|
+
./
|
98
|
+
|
99
|
+
if ! exec_hook_if_exists "build.post" Dockerfile.dx "${IMAGE}"; then
|
100
|
+
log "build.pre failed"
|
101
|
+
exit 1
|
102
|
+
fi
|
103
|
+
|
104
|
+
log "🌈" "Your Docker image has been built tagged '${IMAGE}'"
|
105
|
+
log "🔄" "You can now run dx/start to start it up, though you may need to stop it first with Ctrl-C"
|
106
|
+
|
107
|
+
# vim: ft=bash
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# This file is an input to Docker Compose, and serves
|
2
|
+
# as an additional set of environment variables.
|
3
|
+
|
4
|
+
# IMAGE is the name of the image to be built for running
|
5
|
+
# your app. The recommended format is ORG/REPO:TAG
|
6
|
+
#
|
7
|
+
# The ORG and REPO are based on the values used
|
8
|
+
# with mkbrut. TAG is set to mimic the value
|
9
|
+
# in the FROM directive of the Dockerfile.
|
10
|
+
# This will allow you to upgrade Ruby and run both
|
11
|
+
# versions more easily.
|
12
|
+
IMAGE=<%= organization %>/<%= app_name %>:ruby-3.4
|
13
|
+
|
14
|
+
# PROJECT_NAME is used when running Docker compose
|
15
|
+
# to help ensure the output includes your project's name.
|
16
|
+
PROJECT_NAME=<%= app_name %>
|
17
|
+
|
18
|
+
# DEFAULT_SERVICE is the name of the service (keys under
|
19
|
+
# service: in docker-compose.dx.yml) to use when
|
20
|
+
# running dx/exec and no service is specified.
|
21
|
+
# The value "app" should match that in docker-compose.dx.yml
|
22
|
+
# having the effect of dx/exec running commands inside your app's
|
23
|
+
# container.
|
24
|
+
DEFAULT_SERVICE=app
|
25
|
+
# vim: ft=bash
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# shellcheck shell=bash
|
2
|
+
|
3
|
+
# These are various functions needed by all the other scripts in dx/
|
4
|
+
|
5
|
+
# Log a fatal error and exit nonzero
|
6
|
+
fatal() {
|
7
|
+
remainder=${*:2}
|
8
|
+
if [ -z "$remainder" ]; then
|
9
|
+
log "🛑" "${@}"
|
10
|
+
else
|
11
|
+
log "${@}"
|
12
|
+
fi
|
13
|
+
exit 1
|
14
|
+
}
|
15
|
+
|
16
|
+
# Log an informational message. This is preferable to simply
|
17
|
+
# using `echo` because it prepends the message with the name
|
18
|
+
# of the script so you can tell where the message came from.
|
19
|
+
log() {
|
20
|
+
emoji=$1
|
21
|
+
remainder=${*:2}
|
22
|
+
if [ -z "${NO_EMOJI}" ]; then
|
23
|
+
echo "[ ${0} ] ${*}"
|
24
|
+
else
|
25
|
+
# if remainder is empty that means no emoji was passed
|
26
|
+
if [ -z "$remainder" ]; then
|
27
|
+
echo "[ ${0} ] ${*}"
|
28
|
+
else # emoji was passed, but we ignore it
|
29
|
+
echo "[ ${0} ] ${remainder}"
|
30
|
+
fi
|
31
|
+
fi
|
32
|
+
}
|
33
|
+
|
34
|
+
# Output a debug message if BRUT_WORKSPACE_DEBUG is set
|
35
|
+
debug() {
|
36
|
+
message=$1
|
37
|
+
if [ -z "${BRUT_WORKSPACE_DEBUG}" ]; then
|
38
|
+
return
|
39
|
+
fi
|
40
|
+
log "🐛" "${message}"
|
41
|
+
}
|
42
|
+
|
43
|
+
# Output general usage information for the command and exit zero.
|
44
|
+
#
|
45
|
+
# Args:
|
46
|
+
#
|
47
|
+
# [1] the description of the command
|
48
|
+
# [2] The names of the arguments
|
49
|
+
# [3] If given, the name of the pre hook that the command responds to
|
50
|
+
# [4] If given, the name of the post hook that the command responds to
|
51
|
+
usage() {
|
52
|
+
description=$1
|
53
|
+
arg_names=$2
|
54
|
+
pre_hook=$3
|
55
|
+
post_hook=$4
|
56
|
+
echo "usage: ${0} [-h] ${arg_names}"
|
57
|
+
if [ -n "${description}" ]; then
|
58
|
+
echo
|
59
|
+
echo "DESCRIPTION"
|
60
|
+
echo " ${description}"
|
61
|
+
fi
|
62
|
+
if [ -n "${pre_hook}" ] || [ -n "${post_hook}" ]; then
|
63
|
+
echo
|
64
|
+
echo "HOOKS"
|
65
|
+
if [ -n "${pre_hook}" ]; then
|
66
|
+
echo " ${pre_hook} - if present, called before the main action"
|
67
|
+
fi
|
68
|
+
if [ -n "${post_hook}" ]; then
|
69
|
+
echo " ${post_hook} - if present, called after the main action"
|
70
|
+
fi
|
71
|
+
fi
|
72
|
+
exit 0
|
73
|
+
}
|
74
|
+
|
75
|
+
# Show usage if the command line invocation indicated that help was requested.
|
76
|
+
# This calls usage, so this will exit 0
|
77
|
+
#
|
78
|
+
# Args:
|
79
|
+
#
|
80
|
+
# [1] the description of the command
|
81
|
+
# [2] The names of the arguments
|
82
|
+
# [3] If given, the name of the pre hook that the command responds to
|
83
|
+
# [4] If given, the name of the post hook that the command responds to
|
84
|
+
usage_on_help() {
|
85
|
+
description=$1
|
86
|
+
arg_names=$2
|
87
|
+
pre_hook=$3
|
88
|
+
post_hook=$4
|
89
|
+
# These are the args passed to the invocation so this
|
90
|
+
# function can determine if the user requested help
|
91
|
+
cli_args=( "${@:5}" )
|
92
|
+
|
93
|
+
for arg in "${cli_args[@]}"; do
|
94
|
+
if [ "${arg}" = "-h" ] || [ "${arg}" = "--help" ]; then
|
95
|
+
usage "${description}" "${arg_names}" "${pre_hook}" "${post_hook}"
|
96
|
+
fi
|
97
|
+
done
|
98
|
+
}
|
99
|
+
|
100
|
+
# Ensure that a command line utility exists, exiting nonzero if not.
|
101
|
+
# This is needed to avoid assumptions about what commands a user may have
|
102
|
+
# on their computer. It attempts to provide a more useful error message
|
103
|
+
# than "command not found".
|
104
|
+
require_command() {
|
105
|
+
command_name=$1
|
106
|
+
if ! command -v "${command_name}" >/dev/null 2>&1; then
|
107
|
+
fatal "Command '${command_name}' not found - it is required for this script to run"
|
108
|
+
fi
|
109
|
+
}
|
110
|
+
|
111
|
+
# This loads dx/docker-compose.env as variables to the bash script, thus
|
112
|
+
# allowing Docker Compose and these scripts to share configuration.
|
113
|
+
load_docker_compose_env() {
|
114
|
+
. "${ENV_FILE}"
|
115
|
+
}
|
116
|
+
|
117
|
+
# Execute a hook if the file exists. Note that if the hook exits
|
118
|
+
# nonzero, the caller will need to check the return value of this function and decide
|
119
|
+
# what to do.
|
120
|
+
exec_hook_if_exists() {
|
121
|
+
script_name=$1
|
122
|
+
shift
|
123
|
+
if [ -x "${SCRIPT_DIR}"/"${script_name}" ]; then
|
124
|
+
log "🪝" "${script_name} exists - executing"
|
125
|
+
"${SCRIPT_DIR}"/"${script_name}" "${@}"
|
126
|
+
else
|
127
|
+
debug "${script_name} does not exist"
|
128
|
+
fi
|
129
|
+
}
|
130
|
+
|
131
|
+
require_command "realpath"
|
132
|
+
require_command "cat"
|
133
|
+
|
134
|
+
# Set up the location to the docker-compose.env file.
|
135
|
+
ENV_FILE=$(realpath "${SCRIPT_DIR}")/docker-compose.env
|
136
|
+
|
137
|
+
# vim: ft=bash
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
SCRIPT_DIR=$( cd -- "$( dirname -- "${0}" )" > /dev/null 2>&1 && pwd )
|
6
|
+
|
7
|
+
. "${SCRIPT_DIR}/dx.sh.lib"
|
8
|
+
|
9
|
+
require_command "docker"
|
10
|
+
load_docker_compose_env
|
11
|
+
|
12
|
+
usage_description="Execute a command inside the app's container. Any command other than 'bash' will be run with bash -lc. Use -B to just run the command directly."
|
13
|
+
usage_args="[-s service] [-B] command"
|
14
|
+
usage_pre="exec.pre"
|
15
|
+
usage_on_help "${usage_description}" "${usage_args}" "${usage_pre}" "" "${@}"
|
16
|
+
|
17
|
+
SERVICE="${SERVICE_NAME:-${DEFAULT_SERVICE}}"
|
18
|
+
INCLUDE_PREFIX_FOR_NON_BASH=true
|
19
|
+
while getopts "s:B" opt "${@}"; do
|
20
|
+
case ${opt} in
|
21
|
+
s )
|
22
|
+
SERVICE="${OPTARG}"
|
23
|
+
;;
|
24
|
+
B )
|
25
|
+
INCLUDE_PREFIX_FOR_NON_BASH=false
|
26
|
+
;;
|
27
|
+
\? )
|
28
|
+
log "🛑" "Unknown option: ${opt}"
|
29
|
+
usage "${description}" "${usage_args}" "${usage_pre}"
|
30
|
+
;;
|
31
|
+
: )
|
32
|
+
log "🛑" "Invalid option: ${opt} requires an argument"
|
33
|
+
usage "${description}" "${usage_args}" "${usage_pre}"
|
34
|
+
;;
|
35
|
+
esac
|
36
|
+
done
|
37
|
+
shift $((OPTIND -1))
|
38
|
+
|
39
|
+
if [ $# -eq 0 ]; then
|
40
|
+
log "🛑" "You must provide a command e.g. bash or ls -l"
|
41
|
+
usage "${description}" "${usage_args}" "${usage_pre}"
|
42
|
+
fi
|
43
|
+
|
44
|
+
if ! exec_hook_if_exists "exec.pre"; then
|
45
|
+
log "build.pre failed"
|
46
|
+
exit 1
|
47
|
+
fi
|
48
|
+
|
49
|
+
if [ "$#" -eq 1 ] && [ "$1" = "bash" ]; then
|
50
|
+
COMMAND=(bash)
|
51
|
+
elif [ "$INCLUDE_PREFIX_FOR_NON_BASH" = "true" ]; then
|
52
|
+
COMMAND=(bash -lc "$*")
|
53
|
+
else
|
54
|
+
COMMAND=("$@")
|
55
|
+
fi
|
56
|
+
|
57
|
+
log "🚂" "Running '${COMMAND[@]}' inside container with service name '${SERVICE}'"
|
58
|
+
|
59
|
+
docker \
|
60
|
+
compose \
|
61
|
+
--file docker-compose.dx.yaml \
|
62
|
+
--project-name "${PROJECT_NAME}" \
|
63
|
+
--env-file "${ENV_FILE}" \
|
64
|
+
exec \
|
65
|
+
"${SERVICE}" \
|
66
|
+
"${COMMAND[@]}"
|
67
|
+
|
68
|
+
# vim: ft=bash
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
SCRIPT_DIR=$( cd -- "$( dirname -- "${0}" )" > /dev/null 2>&1 && pwd )
|
6
|
+
|
7
|
+
. "${SCRIPT_DIR}/dx.sh.lib"
|
8
|
+
require_command "docker"
|
9
|
+
load_docker_compose_env
|
10
|
+
|
11
|
+
usage_on_help "Prune containers for this repo" "" "" "" "${@}"
|
12
|
+
|
13
|
+
for container_id in $(docker container ls -a -f "name=^${PROJECT_NAME}-.*-1$" --format="{{.ID}}"); do
|
14
|
+
log "🗑" "Removing container with id '${container_id}'"
|
15
|
+
docker container rm "${container_id}"
|
16
|
+
done
|
17
|
+
echo "🧼" "Containers removed"
|
18
|
+
|
19
|
+
# vim: ft=bash
|