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,62 @@
|
|
1
|
+
class HomePage < AppPage
|
2
|
+
def page_template
|
3
|
+
# The duplication and excessive class sizes here are to
|
4
|
+
# make it easier for you to remove this when you start working
|
5
|
+
# on your app. There are pros and cons to how this code
|
6
|
+
# is written, so don't take this is as a directive on how to
|
7
|
+
# build your app. You do you!
|
8
|
+
img(src: "/static/images/LogoPylon.png",
|
9
|
+
class: "dn db-ns pos-fixed top-0 left-0 h-100vh w-auto z-2")
|
10
|
+
|
11
|
+
header(class: "flex flex-column items-center justify-center h-100vh") do
|
12
|
+
div(class: "flex flex-column flex-row-ns items-center justify-center gap-3") do
|
13
|
+
img(src: "/static/images/LogoTransit.png", class: "h-5")
|
14
|
+
div do
|
15
|
+
h1(class: "ff-sans ma-0 lh-title f-5 tc tl-ns flex flex-column flex-row-ns items-center gap-2") do
|
16
|
+
plain("Welcome to Brut")
|
17
|
+
end
|
18
|
+
h2(class: "ff-sans ma-0 lh-title f-3 fw-normal tc tl-ns") do
|
19
|
+
plain("v")
|
20
|
+
plain(Gem.loaded_specs["brut"].version.to_s)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
nav(class: [ "ff-sans",
|
26
|
+
"flex",
|
27
|
+
"flex-column",
|
28
|
+
"flex-row-ns",
|
29
|
+
"items-center",
|
30
|
+
"justify-start",
|
31
|
+
"gap-3",
|
32
|
+
"mt-3",
|
33
|
+
]) do
|
34
|
+
a(href: "https://brutrb.com",
|
35
|
+
target: "_blank",
|
36
|
+
class: "f-3 red-300 tdu tdn-ns hover-tdu-ns"
|
37
|
+
) do
|
38
|
+
code { "brutrb.com" }
|
39
|
+
end
|
40
|
+
span(role: "separator", class: "dn di-ns f-3 red-300") do
|
41
|
+
raw(safe "⊙")
|
42
|
+
end
|
43
|
+
a(href: "https://brutrb.com/api/index.html",
|
44
|
+
target: "_blank",
|
45
|
+
class: "f-3 red-300 tdu tdn-ns hover-tdu-ns"
|
46
|
+
) do
|
47
|
+
"API Docs"
|
48
|
+
end
|
49
|
+
span(role: "separator", class: "dn di-ns f-3 red-300") do
|
50
|
+
raw(safe "⊙")
|
51
|
+
end
|
52
|
+
a(href: "http://localhost:6504",
|
53
|
+
target: "_blank",
|
54
|
+
class: "f-3 red-300 tdu tdn-ns hover-tdu-ns"
|
55
|
+
) do
|
56
|
+
"Local OpenTelemetry"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
+
<svg
|
3
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
4
|
+
xmlns:cc="http://creativecommons.org/ns#"
|
5
|
+
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
6
|
+
xmlns:svg="http://www.w3.org/2000/svg"
|
7
|
+
xmlns="http://www.w3.org/2000/svg"
|
8
|
+
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
9
|
+
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
10
|
+
aria-label="Comment"
|
11
|
+
class="_8-yf5 "
|
12
|
+
fill="#262626"
|
13
|
+
height="24"
|
14
|
+
viewBox="0 0 48 48"
|
15
|
+
width="24"
|
16
|
+
version="1.1"
|
17
|
+
id="svg22"
|
18
|
+
sodipodi:docname="comment button.svg"
|
19
|
+
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
|
20
|
+
<metadata
|
21
|
+
id="metadata28">
|
22
|
+
<rdf:RDF>
|
23
|
+
<cc:Work
|
24
|
+
rdf:about="">
|
25
|
+
<dc:format>image/svg+xml</dc:format>
|
26
|
+
<dc:type
|
27
|
+
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
28
|
+
<dc:title></dc:title>
|
29
|
+
</cc:Work>
|
30
|
+
</rdf:RDF>
|
31
|
+
</metadata>
|
32
|
+
<defs
|
33
|
+
id="defs26" />
|
34
|
+
<sodipodi:namedview
|
35
|
+
pagecolor="#ffffff"
|
36
|
+
bordercolor="#666666"
|
37
|
+
borderopacity="1"
|
38
|
+
objecttolerance="10"
|
39
|
+
gridtolerance="10"
|
40
|
+
guidetolerance="10"
|
41
|
+
inkscape:pageopacity="0"
|
42
|
+
inkscape:pageshadow="2"
|
43
|
+
inkscape:window-width="1920"
|
44
|
+
inkscape:window-height="1001"
|
45
|
+
id="namedview24"
|
46
|
+
showgrid="false"
|
47
|
+
inkscape:zoom="23.805928"
|
48
|
+
inkscape:cx="12.634482"
|
49
|
+
inkscape:cy="10.463496"
|
50
|
+
inkscape:window-x="-9"
|
51
|
+
inkscape:window-y="-9"
|
52
|
+
inkscape:window-maximized="1"
|
53
|
+
inkscape:current-layer="svg22" />
|
54
|
+
<path
|
55
|
+
d="M47.5 46.1l-2.8-11c1.8-3.3 2.8-7.1 2.8-11.1C47.5 11 37 .5 24 .5S.5 11 .5 24 11 47.5 24 47.5c4 0 7.8-1 11.1-2.8l11 2.8c.8.2 1.6-.6 1.4-1.4zm-3-22.1c0 4-1 7-2.6 10-.2.4-.3.9-.2 1.4l2.1 8.4-8.3-2.1c-.5-.1-1-.1-1.4.2-1.8 1-5.2 2.6-10 2.6-11.4 0-20.6-9.2-20.6-20.5S12.7 3.5 24 3.5 44.5 12.7 44.5 24z"
|
56
|
+
id="path20"
|
57
|
+
clip-rule="evenodd"
|
58
|
+
fill-rule="evenodd" />
|
59
|
+
</svg>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
usage() {
|
6
|
+
echo "Usage: $0"
|
7
|
+
echo
|
8
|
+
echo " Run all tests and quality checks, as if on a CI server"
|
9
|
+
echo
|
10
|
+
}
|
11
|
+
|
12
|
+
for arg in "$@"; do
|
13
|
+
if [ "${arg}" = "-h" ] || [ "${arg}" = "--help" ] || [ "${arg}" = "help" ]; then
|
14
|
+
usage
|
15
|
+
exit 0
|
16
|
+
fi
|
17
|
+
done
|
18
|
+
|
19
|
+
|
20
|
+
echo "[ bin/ci ] Building Assets"
|
21
|
+
bin/build-assets
|
22
|
+
|
23
|
+
echo "[ bin/ci ] Running non E2E tests"
|
24
|
+
bin/test run --rebuild
|
25
|
+
|
26
|
+
echo "[ bin/ci ] Running JS tests"
|
27
|
+
bin/test js
|
28
|
+
|
29
|
+
echo "[ bin/ci ] Running E2E tests"
|
30
|
+
bin/test e2e --rebuild --rebuild-after
|
31
|
+
|
32
|
+
echo "[ bin/ci ] Analyzing Ruby gems for"
|
33
|
+
echo "[ bin/ci ] security vulnerabilities"
|
34
|
+
bundle exec bundle audit check --update
|
35
|
+
|
36
|
+
echo "[ bin/ci ] Checking to see that all classes have tests"
|
37
|
+
bin/test audit --ignore app/src/front_end/components/custom_element_registration.rb
|
38
|
+
|
39
|
+
echo "[ bin/ci ] Done"
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "optparse"
|
4
|
+
|
5
|
+
option_parser = OptionParser.new do |opts|
|
6
|
+
opts.banner = "Usage: bin/console [options]\n\n Get an IRB session with your app loaded in the development RACK_ENV\n\nOPTIONS"
|
7
|
+
|
8
|
+
opts.on("-h", "--help", "Display this help message") do
|
9
|
+
puts opts
|
10
|
+
exit
|
11
|
+
end
|
12
|
+
end
|
13
|
+
option_parser.parse!
|
14
|
+
if ARGV[0] == "help"
|
15
|
+
puts option_parser
|
16
|
+
exit
|
17
|
+
end
|
18
|
+
|
19
|
+
ENV["RACK_ENV"] = "development"
|
20
|
+
if ENV["LOG_LEVEL"].to_s == ""
|
21
|
+
ENV["LOG_LEVEL"] = "warn"
|
22
|
+
end
|
23
|
+
require "pathname"
|
24
|
+
require "dotenv"
|
25
|
+
|
26
|
+
project_root = Pathname(__dir__) / ".."
|
27
|
+
Dotenv.load(project_root / ".env.development.local",
|
28
|
+
project_root / ".env.development")
|
29
|
+
require_relative project_root / "app" / "bootstrap"
|
30
|
+
Bootstrap.new.bootstrap!
|
31
|
+
binding.irb
|
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
SCRIPT_DIR=$( cd -- "$( dirname -- "${0}" )" > /dev/null 2>&1 && pwd )
|
5
|
+
|
6
|
+
usage() {
|
7
|
+
echo "Usage: $0 -e env"
|
8
|
+
echo
|
9
|
+
echo " Get a PostgreSQL console for the specified environment"
|
10
|
+
echo
|
11
|
+
echo "OPTIONS"
|
12
|
+
echo
|
13
|
+
echo " env - 'test' or 'development' (default is 'development')"
|
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=development
|
23
|
+
while getopts ":e:" opt "${@}"; do
|
24
|
+
case ${opt} in
|
25
|
+
e )
|
26
|
+
RACK_ENV="${OPTARG}"
|
27
|
+
;;
|
28
|
+
\? )
|
29
|
+
echo "[ $0 ] Unknown option: ${opt}"
|
30
|
+
usage
|
31
|
+
exit 1
|
32
|
+
;;
|
33
|
+
: )
|
34
|
+
echo "[ $0 ] Invalid option: ${opt}"
|
35
|
+
exit 0
|
36
|
+
usage
|
37
|
+
;;
|
38
|
+
esac
|
39
|
+
done
|
40
|
+
shift $((OPTIND -1))
|
41
|
+
ENV_FILE="${SCRIPT_DIR}"/../".env.${RACK_ENV}"
|
42
|
+
|
43
|
+
if [ -e "${ENV_FILE}" ]; then
|
44
|
+
database_url=$(grep DATABASE_URL "${ENV_FILE}" | sed 's/^[^=]*=//g')
|
45
|
+
psql "${database_url}"
|
46
|
+
else
|
47
|
+
echo "[ $0 ] error: '${RACK_ENV}' is not a valid environment"
|
48
|
+
echo
|
49
|
+
usage
|
50
|
+
exit 1
|
51
|
+
fi
|
@@ -0,0 +1,25 @@
|
|
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 for local development, with asset and code reloading"
|
11
|
+
echo
|
12
|
+
}
|
13
|
+
|
14
|
+
for arg in "$@"; do
|
15
|
+
if [ "${arg}" = "-h" ] || [ "${arg}" = "--help" ] || [ "${arg}" = "help" ]; then
|
16
|
+
usage
|
17
|
+
exit 0
|
18
|
+
fi
|
19
|
+
done
|
20
|
+
|
21
|
+
RACK_ENV="development"
|
22
|
+
export RACK_ENV
|
23
|
+
"${SCRIPT_DIR}"/build-assets
|
24
|
+
foreman start --procfile "${ROOT_DIR}/Procfile.${RACK_ENV}" --root "${ROOT_DIR}"
|
25
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
set -e
|
3
|
+
|
4
|
+
usage() {
|
5
|
+
echo "Usage: $0"
|
6
|
+
echo
|
7
|
+
echo " Run tasks on production after code is avaiable, but before deployment"
|
8
|
+
echo
|
9
|
+
}
|
10
|
+
|
11
|
+
for arg in "$@"; do
|
12
|
+
if [ "${arg}" = "-h" ] || [ "${arg}" = "--help" ] || [ "${arg}" = "help" ]; then
|
13
|
+
usage
|
14
|
+
exit 0
|
15
|
+
fi
|
16
|
+
done
|
17
|
+
|
18
|
+
echo "[ bin/release ] started"
|
19
|
+
echo "[ bin/release ] Creating DB if needed"
|
20
|
+
BRUT_CLI_RAISE_ON_ERROR=true bundle exec ./bin/db create --env=production
|
21
|
+
echo "[ bin/release ] Migrating DB if needed"
|
22
|
+
BRUT_CLI_RAISE_ON_ERROR=true bundle exec ./bin/db migrate --env=production
|
23
|
+
|
24
|
+
# Add additional commands here as needed
|
25
|
+
|
26
|
+
echo "[ bin/release ] DONE"
|
@@ -0,0 +1,86 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
set -e
|
4
|
+
SCRIPT_DIR=$( cd -- "$( dirname -- "${0}" )" > /dev/null 2>&1 && pwd )
|
5
|
+
|
6
|
+
usage() {
|
7
|
+
echo "Usage: $0"
|
8
|
+
echo
|
9
|
+
echo " Run the app in the given RACK_ENV."
|
10
|
+
echo " You likely want to use bin/dev instead of this command."
|
11
|
+
echo
|
12
|
+
echo "ENVIRONMENT VARIABLES"
|
13
|
+
echo
|
14
|
+
echo " PORT - The port to run the app on. Default is 6502"
|
15
|
+
echo " RACK_ENV - The Rack environment to use. Default is development"
|
16
|
+
echo
|
17
|
+
}
|
18
|
+
|
19
|
+
for arg in "$@"; do
|
20
|
+
if [ "${arg}" = "-h" ] || [ "${arg}" = "--help" ] || [ "${arg}" = "help" ]; then
|
21
|
+
usage
|
22
|
+
exit 0
|
23
|
+
fi
|
24
|
+
done
|
25
|
+
|
26
|
+
PORT="${PORT:-6502}"
|
27
|
+
RACK_ENV="${RACK_ENV:-development}"
|
28
|
+
|
29
|
+
export PORT
|
30
|
+
export RACK_ENV
|
31
|
+
|
32
|
+
set -e
|
33
|
+
|
34
|
+
# Everything here is trying its best to prevent more than
|
35
|
+
# one server from running, as this is extremely confusing.
|
36
|
+
# Note that the puma invocation at the bottom
|
37
|
+
# of this script uses the pidfile concept.
|
38
|
+
if [ -f tmp/pidfile ]; then
|
39
|
+
echo "[ $0 ] pidfile found"
|
40
|
+
pid=$(cat tmp/pidfile)
|
41
|
+
|
42
|
+
# First, try to gracefully stop the server with kill
|
43
|
+
if ps -p "${pid}" > /dev/null; then
|
44
|
+
echo "[ $0 ] Attempting to kill PID '${pid}'"
|
45
|
+
kill "${pid}"
|
46
|
+
else
|
47
|
+
echo "[ $0 ] PID '${pid}' no longer running"
|
48
|
+
fi
|
49
|
+
|
50
|
+
# Now, wait 5 seconds to see if it stopped
|
51
|
+
if timeout 5 tail --pid="${pid}" -f /dev/null; then
|
52
|
+
echo "[ $0 ] PID '${pid}' stopped. Restarting server"
|
53
|
+
else
|
54
|
+
# if it has not stopeed, use kill -9 which should work.
|
55
|
+
# But, like all things computer, it's not guaranteed.
|
56
|
+
echo "[ $0 ] PID '${pid}' has not stopped. Trying kill -9"
|
57
|
+
kill -9 "${pid}"
|
58
|
+
if timeout 1 tail --pid="${pid}" -f /dev/null; then
|
59
|
+
echo "[ $0 ] PID '${pid}' killed. Restarting server"
|
60
|
+
else
|
61
|
+
echo "[ $0 ] PID '${pid}' still running. Something seriously wrong"
|
62
|
+
echo "[ $0 ] You may need to stop all Docker containers and restart them"
|
63
|
+
exit 1
|
64
|
+
fi
|
65
|
+
fi
|
66
|
+
|
67
|
+
else
|
68
|
+
echo "[ $0 ] No pidfile-Starting up"
|
69
|
+
fi
|
70
|
+
|
71
|
+
# Run puma in a UNIX environment provided by dotenv.
|
72
|
+
#
|
73
|
+
# A few things to note:
|
74
|
+
#
|
75
|
+
# * dotenv is OK if -f is given non-existent files. That's why this works
|
76
|
+
# in production where there are no .env files.
|
77
|
+
# * the `--` marks the end of dotenv's options and the start of the command
|
78
|
+
# to run. That's why the flags given to puma are not interpreted by dotenv
|
79
|
+
# as flags for itself.
|
80
|
+
dotenv \
|
81
|
+
-f "${SCRIPT_DIR}/../.env.${RACK_ENV}.local,${SCRIPT_DIR}/../.env.${RACK_ENV}" \
|
82
|
+
--ignore \
|
83
|
+
-- \
|
84
|
+
bin/puma \
|
85
|
+
-C puma.config.rb \
|
86
|
+
--pid tmp/pidfile
|
@@ -0,0 +1,256 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
|
4
|
+
require "fileutils"
|
5
|
+
require "open3"
|
6
|
+
require "optparse"
|
7
|
+
require "pathname"
|
8
|
+
|
9
|
+
# This is intended to run inside the Workspace (i.e. Docker container) to
|
10
|
+
# set up the Foundation, thus enabling development. This script should:
|
11
|
+
#
|
12
|
+
# a) Rely only on Ruby and its standard library, since it runs
|
13
|
+
# before any gems are installed
|
14
|
+
# b) Be idempotent, with the ability to run in a CI server
|
15
|
+
# c) Be organized with the setup method first, as this is the main chunk
|
16
|
+
# of logic, with all other supporting methods following
|
17
|
+
#
|
18
|
+
# NOTE: It is not clear yet how Brut will manage this file for you, especially
|
19
|
+
# given that you will need to add to it based on your own setup needs.
|
20
|
+
#
|
21
|
+
# Take care to only add code and not change what is here.
|
22
|
+
|
23
|
+
def setup(update_gems:,update_node:)
|
24
|
+
if update_gems
|
25
|
+
log "Updating gems"
|
26
|
+
system! "bundle update"
|
27
|
+
else
|
28
|
+
log "Installing gems"
|
29
|
+
# Only do bundle install if the much-faster
|
30
|
+
# bundle check indicates we need to
|
31
|
+
system! "bundle check --no-color || bundle install --no-color --quiet"
|
32
|
+
end
|
33
|
+
|
34
|
+
log "Installing puma binstubs"
|
35
|
+
system! "bundle binstub puma"
|
36
|
+
|
37
|
+
log "Installing rspec binstubs"
|
38
|
+
system! "bundle binstub rspec-core"
|
39
|
+
|
40
|
+
# https://github.com/ddollar/foreman/wiki/Don't-Bundle-Foreman
|
41
|
+
log "Installing foreman"
|
42
|
+
system! "gem install foreman"
|
43
|
+
|
44
|
+
# Installs Shopify's LSP. You can remove this if you don't want that,
|
45
|
+
# but this is here to show where to do it vs requiring you to read
|
46
|
+
# documentation.
|
47
|
+
log "Installing Ruby LSP"
|
48
|
+
system! "gem install ruby-lsp"
|
49
|
+
|
50
|
+
if update_node
|
51
|
+
log "Updating Node Modules"
|
52
|
+
system! "npm --no-color --no-progress update"
|
53
|
+
else
|
54
|
+
log "Installing Node Modules"
|
55
|
+
system! "npm --no-color --no-progress install"
|
56
|
+
end
|
57
|
+
|
58
|
+
# In theory, this was installed when the Workspace was setup, but
|
59
|
+
# it doesn't alwaysd work propertly, so this ensures
|
60
|
+
# Chromium is set up. See comments in Dockerfile.dx as to why
|
61
|
+
# Chromium and not Chrome.
|
62
|
+
log "Re-installing playwright/chromium if needed"
|
63
|
+
system! "node_modules/.bin/playwright install chromium"
|
64
|
+
|
65
|
+
log "Ensuring tmp dir exists"
|
66
|
+
system! "mkdir -p tmp"
|
67
|
+
|
68
|
+
setup_dot_env_local
|
69
|
+
|
70
|
+
log "Setting up databases"
|
71
|
+
|
72
|
+
log "Re-creating development database"
|
73
|
+
system! "bin/db rebuild --env=development"
|
74
|
+
|
75
|
+
log "Re-creating test database"
|
76
|
+
system! "bin/db rebuild --env=test"
|
77
|
+
|
78
|
+
log "Loading seed data into the development database"
|
79
|
+
system! "bin/db seed --env=development"
|
80
|
+
|
81
|
+
log "All set up."
|
82
|
+
help
|
83
|
+
end
|
84
|
+
|
85
|
+
def setup_dot_env_local()
|
86
|
+
|
87
|
+
dot_env = ROOT_DIR / ".env.development"
|
88
|
+
if !File.exist?(dot_env)
|
89
|
+
raise "Problem: '#{dot_env}' does not exist"
|
90
|
+
end
|
91
|
+
|
92
|
+
log "Checking #{dot_env} for required local environment variables"
|
93
|
+
previous_comment = ""
|
94
|
+
dot_env_need_local = {}
|
95
|
+
File.read(dot_env).split(/\n/).each do |line|
|
96
|
+
if line =~ /^#(.*)$/
|
97
|
+
previous_comment << line
|
98
|
+
elsif line =~ /^LOCAL:([^=]+)$/
|
99
|
+
dot_env_need_local[$1] = previous_comment
|
100
|
+
previous_comment = ""
|
101
|
+
elsif line =~ /^([^=])+/
|
102
|
+
previous_comment = ""
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
dot_env_local = ROOT_DIR / ".env.development.local"
|
107
|
+
log "Ensuring '#{dot_env_local}' exists"
|
108
|
+
if !File.exist?(dot_env_local)
|
109
|
+
log "Creating '#{dot_env_local}'"
|
110
|
+
FileUtils.touch dot_env_local
|
111
|
+
end
|
112
|
+
|
113
|
+
log "Checking #{dot_env_local} for values for required local environment variables"
|
114
|
+
local_contents = File.read(dot_env_local).split(/\n/).map { |line|
|
115
|
+
if line =~ /^([^=]+)=(.*)$/
|
116
|
+
var = $1
|
117
|
+
val = $2
|
118
|
+
if dot_env_need_local[var] && val.to_s != ""
|
119
|
+
log "Value for '#{var}' is good"
|
120
|
+
dot_env_need_local.delete(var)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
line
|
124
|
+
}.compact
|
125
|
+
|
126
|
+
dot_env_need_local.each do |var,comment|
|
127
|
+
log "A value is needed locally for '#{var}'"
|
128
|
+
log ""
|
129
|
+
log comment
|
130
|
+
log ""
|
131
|
+
puts "Enter the value below and hit Return"
|
132
|
+
value = gets
|
133
|
+
local_contents << "#{var}=#{value}"
|
134
|
+
log "Got it, thanks"
|
135
|
+
end
|
136
|
+
|
137
|
+
log "Updating '#{dot_env_local}'"
|
138
|
+
File.open(dot_env_local,"w") do |file|
|
139
|
+
local_contents.each do |line|
|
140
|
+
file.puts line
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
log "Checking that #{dot_env_local} is being ignored"
|
145
|
+
gitignore = ROOT_DIR / ".gitignore"
|
146
|
+
if File.exist?(gitignore)
|
147
|
+
lines = File.read(gitignore).split(/\n/)
|
148
|
+
if lines.include?("/#{dot_env_local.basename}")
|
149
|
+
log "It's there!"
|
150
|
+
else
|
151
|
+
log "It's missing. Adding..."
|
152
|
+
lines << ""
|
153
|
+
lines << "# This contains actual secrets and should not be checked in"
|
154
|
+
lines << "/#{dot_env_local.basename}"
|
155
|
+
File.open(gitignore,"w") do |file|
|
156
|
+
lines.each do |line|
|
157
|
+
file.puts line
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
else
|
162
|
+
log "No #{gitignore}, so make sure you DO NOT CHECK #{dot_env_local} IN!!!"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# We don't want the setup method to have to do all this error
|
167
|
+
# checking, and we also want to explicitly log what we are
|
168
|
+
# executing. Thus, we use this method instead of Kernel#system
|
169
|
+
def system!(*args)
|
170
|
+
if ENV["BRUT_BIN_KIT_DEBUG"] == "true"
|
171
|
+
log "Executing #{args}"
|
172
|
+
out,err,status = Open3.capture3(*args)
|
173
|
+
if status.success?
|
174
|
+
log "#{args} succeeded"
|
175
|
+
else
|
176
|
+
log "#{args} failed"
|
177
|
+
log "STDOUT:"
|
178
|
+
$stdout.puts out
|
179
|
+
log "STDERR:"
|
180
|
+
$stderr.puts err
|
181
|
+
abort
|
182
|
+
end
|
183
|
+
else
|
184
|
+
log "Executing #{args}"
|
185
|
+
if system(*args)
|
186
|
+
log "#{args} succeeded"
|
187
|
+
else
|
188
|
+
log "#{args} failed"
|
189
|
+
abort
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
# It's helpful to know what messages came from this
|
195
|
+
# script, so we'll use log instead of `puts`
|
196
|
+
def log(message)
|
197
|
+
puts "[ #{$0} ] #{message}"
|
198
|
+
end
|
199
|
+
|
200
|
+
ROOT_DIR = ((Pathname(__dir__) / ".." ).expand_path)
|
201
|
+
|
202
|
+
def help(option_parser=nil)
|
203
|
+
if option_parser
|
204
|
+
puts option_parser
|
205
|
+
puts
|
206
|
+
puts "OTHER USEFUL COMMANDS"
|
207
|
+
else
|
208
|
+
puts
|
209
|
+
puts "USEFUL COMMANDS"
|
210
|
+
end
|
211
|
+
puts ""
|
212
|
+
puts " bin/dev"
|
213
|
+
puts " # run app locally, rebuilding and reloading as needed"
|
214
|
+
puts ""
|
215
|
+
puts " bin/ci"
|
216
|
+
puts " # runs all tests and checks as CI would"
|
217
|
+
puts ""
|
218
|
+
puts " bin/console"
|
219
|
+
puts " # get an IRB console with the app loaded"
|
220
|
+
puts ""
|
221
|
+
puts " bin/db"
|
222
|
+
puts " # interact with the DB for migrations, information, etc"
|
223
|
+
puts ""
|
224
|
+
puts " bin/dbconsole"
|
225
|
+
puts " # get a PSQL session to the database"
|
226
|
+
puts ""
|
227
|
+
puts " bin/scaffold"
|
228
|
+
puts " # Create various structures in your app, like pages or forms"
|
229
|
+
puts ""
|
230
|
+
puts " bin/setup help"
|
231
|
+
puts " # show this help"
|
232
|
+
puts ""
|
233
|
+
end
|
234
|
+
|
235
|
+
options = {
|
236
|
+
update_gems: false,
|
237
|
+
update_node: false,
|
238
|
+
}
|
239
|
+
option_parser = OptionParser.new do |opts|
|
240
|
+
opts.banner = "Usage: bin/setup [options]\n\n Set up the Foundation, allowing for development and testing of the app\n\nOPTIONS\n"
|
241
|
+
opts.on("--update[=TYPE]","Update gems or modules to get the latest versions consistent with Gemfile or package.json. TYPE can be 'all', 'gems', or 'node'. If TYPE is omitted, 'all' is assumed.") do |value|
|
242
|
+
options[:update_gems] = value.nil? || value == "gems"
|
243
|
+
options[:update_node] = value.nil? || value == "node"
|
244
|
+
end
|
245
|
+
opts.on("-h", "--help", "Display this help message") do
|
246
|
+
help(opts)
|
247
|
+
exit
|
248
|
+
end
|
249
|
+
end
|
250
|
+
option_parser.parse!
|
251
|
+
|
252
|
+
if ARGV[0] == "help"
|
253
|
+
help(option_parser)
|
254
|
+
else
|
255
|
+
setup(**options)
|
256
|
+
end
|