ufo 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +10 -0
- data/Gemfile.lock +28 -438
- data/README.md +0 -8
- data/docs/_docs/conventions.md +1 -1
- data/docs/_docs/helpers.md +1 -0
- data/docs/_docs/settings.md +25 -24
- data/docs/_docs/tutorial-ufo-ship.md +1 -1
- data/docs/_docs/ufo-env.md +10 -10
- data/docs/_docs/variables.md +8 -8
- data/lib/starter_project/Dockerfile +1 -1
- data/lib/starter_project/ufo/settings.yml +7 -7
- data/lib/starter_project/ufo/task_definitions.rb +13 -9
- data/lib/starter_project/ufo/variables/{stag.rb → development.rb} +4 -4
- data/lib/starter_project/ufo/variables/{prod.rb → production.rb} +3 -3
- data/lib/ufo.rb +1 -0
- data/lib/ufo/aws_services.rb +4 -1
- data/lib/ufo/cli.rb +9 -10
- data/lib/ufo/command.rb +23 -0
- data/lib/ufo/docker.rb +4 -5
- data/lib/ufo/docker/builder.rb +1 -2
- data/lib/ufo/env.rb +1 -1
- data/lib/ufo/help.rb +9 -0
- data/lib/ufo/help/destroy.md +5 -0
- data/lib/ufo/help/docker.md +4 -0
- data/lib/ufo/help/docker/base.md +9 -0
- data/lib/ufo/help/docker/build.md +6 -0
- data/lib/ufo/help/docker/clean.md +14 -0
- data/lib/ufo/help/docker/name.md +5 -0
- data/lib/ufo/help/init.md +11 -0
- data/lib/ufo/help/scale.md +5 -0
- data/lib/ufo/help/ship.md +17 -0
- data/lib/ufo/help/ships.md +18 -0
- data/lib/ufo/help/task.md +10 -0
- data/lib/ufo/help/tasks.md +7 -0
- data/lib/ufo/help/tasks/build.md +7 -0
- data/lib/ufo/help/tasks/register.md +5 -0
- data/lib/ufo/init.rb +2 -3
- data/lib/ufo/ship.rb +1 -1
- data/lib/ufo/task.rb +5 -1
- data/lib/ufo/tasks.rb +2 -3
- data/lib/ufo/version.rb +1 -1
- data/ufo.gemspec +4 -1
- metadata +63 -9
- data/lib/ufo/cli/help.rb +0 -124
- data/lib/ufo/docker/help.rb +0 -65
- data/lib/ufo/tasks/help.rb +0 -26
data/README.md
CHANGED
@@ -22,14 +22,6 @@ See [ufoships.com](http://ufoships.com) for full documentation.
|
|
22
22
|
|
23
23
|
## Installation
|
24
24
|
|
25
|
-
If you want to quickly install ufo without having to worry about ufo’s dependencies you can simply install the Bolts Toolbelt which has ufo included.
|
26
|
-
|
27
|
-
```sh
|
28
|
-
brew cask install boltopslabs/software/bolts
|
29
|
-
```
|
30
|
-
|
31
|
-
Or if you prefer you can install ufo with RubyGems
|
32
|
-
|
33
25
|
```sh
|
34
26
|
gem install ufo
|
35
27
|
```
|
data/docs/_docs/conventions.md
CHANGED
@@ -6,7 +6,7 @@ Ufo uses a set of naming conventions. This helps enforce some best practices an
|
|
6
6
|
|
7
7
|
### UFO_ENV to ECS Cluster Convention
|
8
8
|
|
9
|
-
By default, the ECS cluster value is the same as UFO_ENV's value. So if `UFO_ENV=
|
9
|
+
By default, the ECS cluster value is the same as UFO_ENV's value. So if `UFO_ENV=production` then the ECS Cluster is production and if `UFO_ENV=staging` then the ECS Cluster is staging. You can easily override this convention by specifying the `--cluster` CLI option. You can also override this behavior with [settings.yml]({% link _docs/settings.md %}) to spare you from having to type `--cluster` over and over.
|
10
10
|
|
11
11
|
### Service and Task Names Convention
|
12
12
|
|
data/docs/_docs/helpers.md
CHANGED
@@ -12,6 +12,7 @@ full\_image\_name | The full docker image name that ufo builds. The "base" por
|
|
12
12
|
dockerfile\_port | Exposed port extracted from the Dockerfile of the project.
|
13
13
|
env_vars(text) | This method takes a block of text that contains the env values in key=value format and converts that block of text to the proper task definition json format.
|
14
14
|
env_file(path) | This method takes an `.env` file which contains a simple key value list of environment variables and converts the list to the proper task definition json format.
|
15
|
+
task_definition_name | The name of the task_definition. So if the code looks like this `task_definition "demo-web" do`, the task_definition_name is "demo-web".
|
15
16
|
|
16
17
|
To call the helper in task_definitions.rb you must add `helper.` in front. So full\_image\_name is called via `helper.full_image_name`.
|
17
18
|
|
data/docs/_docs/settings.md
CHANGED
@@ -15,17 +15,18 @@ image: tongueroo/hi
|
|
15
15
|
clean_keep: 30
|
16
16
|
ecr_keep: 30
|
17
17
|
aws_profile_ufo_env_map:
|
18
|
-
default:
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
default: staging
|
19
|
+
# # More examples:
|
20
|
+
# aws_profile1: production
|
21
|
+
# aws_profile2: staging
|
22
|
+
# aws_profile3: development
|
23
|
+
|
23
24
|
ufo_env_cluster_map:
|
24
|
-
default:
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
default: production
|
26
|
+
# # More examples:
|
27
|
+
# production: production
|
28
|
+
# staging: staging
|
29
|
+
# development: development
|
29
30
|
```
|
30
31
|
|
31
32
|
The table below covers what each setting does:
|
@@ -39,19 +40,19 @@ Setting | Description
|
|
39
40
|
|
40
41
|
### UFO_ENV to ECS Cluster Mapping
|
41
42
|
|
42
|
-
The `ufo_env_cluster_map` option allows you to override the [UFO_ENV to ECS Cluster Convention]({% link _docs/conventions.md %}). Normally, the ECS cluster defaults to whatever UFO_ENV is set to. For example, when `UFO_ENV=
|
43
|
+
The `ufo_env_cluster_map` option allows you to override the [UFO_ENV to ECS Cluster Convention]({% link _docs/conventions.md %}). Normally, the ECS cluster defaults to whatever UFO_ENV is set to. For example, when `UFO_ENV=production` the ECS Cluster is production and when `UFO_ENV=staging` the ECS Cluster is staging. This setting allows you to override this behavior so that you do not have to specify the `--cluster` CLI option repeatedly. Let's go through an example:
|
43
44
|
|
44
45
|
By default:
|
45
46
|
|
46
47
|
```sh
|
47
|
-
UFO_ENV=
|
48
|
-
UFO_ENV=
|
48
|
+
UFO_ENV=production ufo ship hi-web # cluster defaults to UFO_ENV which is prod
|
49
|
+
UFO_ENV=production ufo ship hi-web --cluster prod # same as above
|
49
50
|
```
|
50
51
|
|
51
52
|
Override the convention and explicitly specify the `--cluster` option in the CLI.
|
52
53
|
|
53
54
|
```sh
|
54
|
-
UFO_ENV=
|
55
|
+
UFO_ENV=production ufo ship hi-web --cluster custom-cluster # override the default UFO_ENV TO cluster mapping
|
55
56
|
```
|
56
57
|
|
57
58
|
We can also override the convention with `settings.yml`:
|
@@ -64,7 +65,7 @@ ufo_env_cluster_map:
|
|
64
65
|
Because of the `ufo_env_cluster_map` setting, the `--cluster` CLI option is not longer required:
|
65
66
|
|
66
67
|
```sh
|
67
|
-
UFO_ENV=
|
68
|
+
UFO_ENV=production ufo ship hi-web # same as --cluster custom-cluster because of settings.yml
|
68
69
|
```
|
69
70
|
|
70
71
|
### AWS_PROFILE TO UFO_ENV Mapping
|
@@ -73,23 +74,23 @@ An interesting way to set `UFO_ENV` is with the `aws_profile_ufo_env_map` in `uf
|
|
73
74
|
|
74
75
|
```yaml
|
75
76
|
aws_profile_ufo_env_map:
|
76
|
-
default:
|
77
|
-
my-prod-profile:
|
78
|
-
my-stag-profile:
|
77
|
+
default: development
|
78
|
+
my-prod-profile: production
|
79
|
+
my-stag-profile: staging
|
79
80
|
```
|
80
81
|
|
81
82
|
In this case, when you set `AWS_PROFILE` to switch AWS profiles, ufo picks this up and maps the `AWS_PROFILE` value to the specified `UFO_ENV` using the `aws_profile_ufo_env_map` lookup. Example:
|
82
83
|
|
83
84
|
```sh
|
84
|
-
AWS_PROFILE=my-prod-profile => UFO_ENV=
|
85
|
-
AWS_PROFILE=my-stag-profile => UFO_ENV=
|
86
|
-
AWS_PROFILE=default => UFO_ENV=
|
87
|
-
AWS_PROFILE=whatever => UFO_ENV=
|
85
|
+
AWS_PROFILE=my-prod-profile => UFO_ENV=production
|
86
|
+
AWS_PROFILE=my-stag-profile => UFO_ENV=staging
|
87
|
+
AWS_PROFILE=default => UFO_ENV=development
|
88
|
+
AWS_PROFILE=whatever => UFO_ENV=development
|
88
89
|
```
|
89
90
|
|
90
|
-
Notice how `AWS_PROFILE=whatever` results in `UFO_ENV=
|
91
|
+
Notice how `AWS_PROFILE=whatever` results in `UFO_ENV=development`. This is because the `default: development` map is specially treated. If you set the `default` map, this becomes the default value when the profile map is not specified in the rest of `ufo/settings.yml`.
|
91
92
|
|
92
|
-
This behavior prevents you from switching `AWS_PROFILE`s and then accidentally deploying a production based docker image to staging and vice versas because you forgot to also switch `
|
93
|
+
This behavior prevents you from switching `AWS_PROFILE`s and then accidentally deploying a production based docker image to staging and vice versas because you forgot to also switch `UFO_ENV` to its respective environment.
|
93
94
|
|
94
95
|
|
95
96
|
<a id="prev" class="btn btn-basic" href="{% link _docs/ufo-help.md %}">Back</a>
|
@@ -14,7 +14,7 @@ By convention, ufo will ship the docker container to an ECS cluster with the sam
|
|
14
14
|
|
15
15
|
```sh
|
16
16
|
ufo ship hi-web --cluster prod
|
17
|
-
UFO_ENV=
|
17
|
+
UFO_ENV=production ufo ship hi-web --cluster prod
|
18
18
|
```
|
19
19
|
|
20
20
|
When you run `ufo ship hi-web`:
|
data/docs/_docs/ufo-env.md
CHANGED
@@ -15,13 +15,13 @@ The `UFO_ENV` can be set easily in several ways:
|
|
15
15
|
### At the CLI Command
|
16
16
|
|
17
17
|
```sh
|
18
|
-
UFO_ENV=
|
18
|
+
UFO_ENV=production ufo ship hi-web --cluster prod
|
19
19
|
```
|
20
20
|
|
21
21
|
### As an environment variable
|
22
22
|
|
23
23
|
```sh
|
24
|
-
export UFO_ENV=
|
24
|
+
export UFO_ENV=production
|
25
25
|
ufo ship hi-web --cluster prod
|
26
26
|
```
|
27
27
|
|
@@ -33,21 +33,21 @@ The most interesting way to set `UFO_ENV` is with the `aws_profile_ufo_env_map`
|
|
33
33
|
|
34
34
|
```yaml
|
35
35
|
aws_profile_ufo_env_map:
|
36
|
-
default:
|
37
|
-
my-prod-profile:
|
38
|
-
my-stag-profile:
|
36
|
+
default: development
|
37
|
+
my-prod-profile: production
|
38
|
+
my-stag-profile: staging
|
39
39
|
```
|
40
40
|
|
41
41
|
In this case, when you set `AWS_PROFILE` to switch AWS profiles, ufo picks this up and maps the `AWS_PROFILE` value to the specified `UFO_ENV` using the `aws_profile_ufo_env_map` lookup. Example:
|
42
42
|
|
43
43
|
```sh
|
44
|
-
AWS_PROFILE=my-prod-profile => UFO_ENV=
|
45
|
-
AWS_PROFILE=my-stag-profile => UFO_ENV=
|
46
|
-
AWS_PROFILE=default => UFO_ENV=
|
47
|
-
AWS_PROFILE=whatever => UFO_ENV=
|
44
|
+
AWS_PROFILE=my-prod-profile => UFO_ENV=production
|
45
|
+
AWS_PROFILE=my-stag-profile => UFO_ENV=staging
|
46
|
+
AWS_PROFILE=default => UFO_ENV=development
|
47
|
+
AWS_PROFILE=whatever => UFO_ENV=development
|
48
48
|
```
|
49
49
|
|
50
|
-
Notice how `AWS_PROFILE=whatever` results in `UFO_ENV=
|
50
|
+
Notice how `AWS_PROFILE=whatever` results in `UFO_ENV=development`. This is because the `default: development` map is specially treated. If you set the `default` map, this becomes the default value when the profile map is not specified in the rest of `ufo/settings.yml`. More info on settings is available at [settings]({% link _docs/settings.md %}).
|
51
51
|
|
52
52
|
<a id="prev" class="btn btn-basic" href="{% link _docs/settings.md %}">Back</a>
|
53
53
|
<a id="next" class="btn btn-primary" href="{% link _docs/variables.md %}">Next Step</a>
|
data/docs/_docs/variables.md
CHANGED
@@ -28,27 +28,27 @@ Shared variables also support a concept called layering. The `config/variables/
|
|
28
28
|
@environment = helper.env_file(".env")
|
29
29
|
```
|
30
30
|
|
31
|
-
When `ufo ship` is ran with `UFO_ENV=
|
31
|
+
When `ufo ship` is ran with `UFO_ENV=production` he `config/variables/production.rb` will be evaluated and layered on top of the variables defined in `base.rb:
|
32
32
|
|
33
|
-
`ufo/variables/
|
33
|
+
`ufo/variables/production.rb`:
|
34
34
|
|
35
35
|
```ruby
|
36
|
-
@environment = helper.env_vars(%Q
|
36
|
+
@environment = helper.env_vars(%Q[
|
37
37
|
RAILS_ENV=production
|
38
38
|
SECRET_KEY_BASE=secret
|
39
|
-
|
39
|
+
])
|
40
40
|
```
|
41
41
|
|
42
|
-
When `ufo ship` is ran with `UFO_ENV=
|
42
|
+
When `ufo ship` is ran with `UFO_ENV=staging` he `config/variables/staging.rb` will be evaluated and layered on top of the variables defined in `base.rb:
|
43
43
|
|
44
44
|
|
45
|
-
`ufo/variables/
|
45
|
+
`ufo/variables/production.rb`:
|
46
46
|
|
47
47
|
```ruby
|
48
|
-
@environment = helper.env_vars(%Q
|
48
|
+
@environment = helper.env_vars(%Q[
|
49
49
|
RAILS_ENV=staging
|
50
50
|
SECRET_KEY_BASE=secret
|
51
|
-
|
51
|
+
])
|
52
52
|
```
|
53
53
|
|
54
54
|
|
@@ -4,15 +4,15 @@ image: <%= @image %>
|
|
4
4
|
# ecr_keep: 30
|
5
5
|
|
6
6
|
# aws_profile_ufo_env_map:
|
7
|
-
# default:
|
7
|
+
# default: staging
|
8
8
|
# # More examples:
|
9
|
-
# aws_profile1:
|
10
|
-
# aws_profile2:
|
11
|
-
# aws_profile3:
|
9
|
+
# aws_profile1: production
|
10
|
+
# aws_profile2: staging
|
11
|
+
# aws_profile3: development
|
12
12
|
|
13
13
|
# ufo_env_cluster_map:
|
14
14
|
# default: prod
|
15
15
|
# # More examples:
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
16
|
+
# production: prod
|
17
|
+
# staging: stag
|
18
|
+
# development: dev
|
@@ -1,11 +1,12 @@
|
|
1
|
-
# There
|
1
|
+
# There some built-in helpers that are automatically available in this file.
|
2
2
|
#
|
3
|
-
# Some of
|
3
|
+
# Some of helpers get data from the Dockerfile and some are from other places.
|
4
|
+
# Here's a summary of the some helpers:
|
4
5
|
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
6
|
+
# full_image_name
|
7
|
+
# dockerfile_port
|
8
|
+
# env_vars(text)
|
9
|
+
# env_file(path)
|
9
10
|
#
|
10
11
|
# More info: http://ufoships.com/docs/helpers/
|
11
12
|
#
|
@@ -18,7 +19,8 @@ task_definition "<%= @app %>-web" do
|
|
18
19
|
# uncomment out to set the log group
|
19
20
|
# awslogs_group: "<%= @app %>-web",
|
20
21
|
# awslogs_stream_prefix: "<%= @app %>",
|
21
|
-
|
22
|
+
# awslogs_region: "us-east-1",
|
23
|
+
# command: ["bin/web"] # IMPORTANT: change or create a bin/web file
|
22
24
|
)
|
23
25
|
end
|
24
26
|
|
@@ -30,7 +32,8 @@ task_definition "<%= @app %>-worker" do
|
|
30
32
|
# uncomment out to set the log group
|
31
33
|
# awslogs_group: "<%= @app %>-worker",
|
32
34
|
# awslogs_stream_prefix: "<%= @app %>",
|
33
|
-
|
35
|
+
# awslogs_region: "us-east-1",
|
36
|
+
# command: ["bin/worker"] # IMPORTANT: change or create a bin/worker file
|
34
37
|
)
|
35
38
|
end
|
36
39
|
|
@@ -42,6 +45,7 @@ task_definition "<%= @app %>-clock" do
|
|
42
45
|
# uncomment out to set the log group
|
43
46
|
# awslogs_group: "<%= @app %>-clock",
|
44
47
|
# awslogs_stream_prefix: "<%= @app %>",
|
45
|
-
|
48
|
+
# awslogs_region: "us-east-1",
|
49
|
+
# command: ["bin/clock"] # IMPORTANT: change or create a bin/clock file
|
46
50
|
)
|
47
51
|
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
# Example ufo/variables/
|
1
|
+
# Example ufo/variables/development.rb
|
2
2
|
# More info on how variables work: http://ufoships.com/docs/variables/
|
3
3
|
@cpu = 192
|
4
|
-
@environment = helper.env_vars(%Q
|
5
|
-
RAILS_ENV=
|
4
|
+
@environment = helper.env_vars(%Q[
|
5
|
+
RAILS_ENV=development
|
6
6
|
SECRET_KEY_BASE=secret
|
7
|
-
|
7
|
+
])
|
@@ -1,7 +1,7 @@
|
|
1
|
-
# Example ufo/variables/
|
1
|
+
# Example ufo/variables/production.rb
|
2
2
|
# More info on how variables work: http://ufoships.com/docs/variables/
|
3
3
|
@cpu = 256
|
4
|
-
@environment = helper.env_vars(%Q
|
4
|
+
@environment = helper.env_vars(%Q[
|
5
5
|
RAILS_ENV=production
|
6
6
|
SECRET_KEY_BASE=secret
|
7
|
-
|
7
|
+
])
|
data/lib/ufo.rb
CHANGED
data/lib/ufo/aws_services.rb
CHANGED
data/lib/ufo/cli.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'thor'
|
2
2
|
require 'ufo/command'
|
3
|
-
require 'ufo/cli/help'
|
4
3
|
|
5
4
|
module Ufo
|
6
5
|
class CLI < Command
|
@@ -11,17 +10,17 @@ module Ufo
|
|
11
10
|
class_option :cluster, desc: "Cluster. Overrides ufo/settings.yml."
|
12
11
|
|
13
12
|
desc "docker [ACTION]", "docker related tasks"
|
14
|
-
long_desc Help.docker
|
13
|
+
long_desc Help.text(:docker)
|
15
14
|
subcommand "docker", Docker
|
16
15
|
|
17
16
|
desc "tasks [ACTION]", "task definition related tasks"
|
18
|
-
long_desc Help.tasks
|
17
|
+
long_desc Help.text(:tasks)
|
19
18
|
subcommand "tasks", Tasks
|
20
19
|
|
21
20
|
desc "init", "setup initial ufo files"
|
22
21
|
option :image, type: :string, required: true, desc: "Docker image name without the tag. Example: tongueroo/hi. Configures ufo/settings.yml"
|
23
22
|
option :app, type: :string, required: true, desc: "App name. Preferably one word. Used in the generated ufo/task_definitions.rb."
|
24
|
-
long_desc Help.init
|
23
|
+
long_desc Help.text(:init)
|
25
24
|
def init
|
26
25
|
Init.new(options).setup
|
27
26
|
end
|
@@ -40,7 +39,7 @@ module Ufo
|
|
40
39
|
end
|
41
40
|
|
42
41
|
desc "ship [SERVICE]", "builds and ships container image to the ECS service"
|
43
|
-
long_desc Help.ship
|
42
|
+
long_desc Help.text(:ship)
|
44
43
|
ship_options.call
|
45
44
|
def ship(service)
|
46
45
|
builder = build_docker
|
@@ -55,7 +54,7 @@ module Ufo
|
|
55
54
|
end
|
56
55
|
|
57
56
|
desc "ships [LIST-OF-SERVICES]", "builds and ships same container image to multiple ECS services"
|
58
|
-
long_desc Help.ships
|
57
|
+
long_desc Help.text(:ships)
|
59
58
|
ship_options.call
|
60
59
|
def ships(*services)
|
61
60
|
builder = build_docker
|
@@ -73,7 +72,7 @@ module Ufo
|
|
73
72
|
end
|
74
73
|
|
75
74
|
desc "task [TASK_DEFINITION]", "runs a one time task"
|
76
|
-
long_desc Help.task
|
75
|
+
long_desc Help.text(:task)
|
77
76
|
option :docker, type: :boolean, desc: "Enable docker build and push", default: true
|
78
77
|
option :command, type: :array, desc: "Override the command used for the container"
|
79
78
|
def task(task_definition)
|
@@ -83,7 +82,7 @@ module Ufo
|
|
83
82
|
end
|
84
83
|
|
85
84
|
desc "destroy [SERVICE]", "destroys the ECS service"
|
86
|
-
long_desc Help.destroy
|
85
|
+
long_desc Help.text(:destroy)
|
87
86
|
option :sure, type: :boolean, desc: "By pass are you sure prompt."
|
88
87
|
def destroy(service)
|
89
88
|
task_definition = options[:task] || service # convention
|
@@ -91,14 +90,14 @@ module Ufo
|
|
91
90
|
end
|
92
91
|
|
93
92
|
desc "scale [SERVICE] [COUNT]", "scale the ECS service"
|
94
|
-
long_desc Help.scale
|
93
|
+
long_desc Help.text(:scale)
|
95
94
|
def scale(service, count)
|
96
95
|
Scale.new(service, count, options).update
|
97
96
|
end
|
98
97
|
|
99
98
|
desc "version", "Prints version number of installed ufo"
|
100
99
|
def version
|
101
|
-
puts
|
100
|
+
puts VERSION
|
102
101
|
end
|
103
102
|
|
104
103
|
no_tasks do
|
data/lib/ufo/command.rb
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
require "thor"
|
2
|
+
|
3
|
+
# Override thor's long_desc identation behavior
|
4
|
+
# https://github.com/erikhuda/thor/issues/398
|
5
|
+
class Thor
|
6
|
+
module Shell
|
7
|
+
class Basic
|
8
|
+
def print_wrapped(message, options = {})
|
9
|
+
message = "\n#{message}" unless message[0] == "\n"
|
10
|
+
stdout.puts message
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
1
16
|
module Ufo
|
2
17
|
class Command < Thor
|
3
18
|
class << self
|
@@ -16,6 +31,14 @@ module Ufo
|
|
16
31
|
args -= help_flags
|
17
32
|
args.insert(-2, "help")
|
18
33
|
end
|
34
|
+
|
35
|
+
# ufo --version
|
36
|
+
# ufo -v
|
37
|
+
version_flags = ["-v", "--version"]
|
38
|
+
if args.length == 1 && !(args & version_flags).empty?
|
39
|
+
args = ["version"]
|
40
|
+
end
|
41
|
+
|
19
42
|
super
|
20
43
|
end
|
21
44
|
end
|