ufo 2.3.0 → 3.0.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.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +57 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +1 -0
  5. data/CHANGELOG.md +16 -1
  6. data/Gemfile.lock +16 -3
  7. data/README.md +5 -1
  8. data/docs/_docs/auto-completion.md +27 -0
  9. data/docs/_docs/automated-cleanup.md +1 -1
  10. data/docs/_docs/conventions.md +2 -2
  11. data/docs/_docs/helpers.md +6 -6
  12. data/docs/_docs/run-in-pieces.md +15 -8
  13. data/docs/_docs/settings.md +61 -49
  14. data/docs/_docs/structure.md +2 -2
  15. data/docs/_docs/tutorial-ufo-docker-build.md +10 -3
  16. data/docs/_docs/tutorial-ufo-init.md +48 -16
  17. data/docs/_docs/tutorial-ufo-ship.md +14 -7
  18. data/docs/_docs/tutorial-ufo-ships.md +1 -1
  19. data/docs/_docs/tutorial-ufo-tasks-build.md +23 -14
  20. data/docs/_docs/ufo-deploy.md +30 -0
  21. data/docs/_docs/ufo-docker-base.md +3 -3
  22. data/docs/_docs/ufo-docker-build.md +3 -3
  23. data/docs/_docs/ufo-docker-push.md +43 -0
  24. data/docs/_docs/ufo-env.md +17 -15
  25. data/docs/_docs/ufo-init.md +14 -1
  26. data/docs/_docs/ufo-scale.md +2 -4
  27. data/docs/_docs/ufo-ships.md +2 -2
  28. data/docs/_docs/variables.md +6 -6
  29. data/docs/_includes/commands.html +4 -4
  30. data/docs/_includes/subnav.html +3 -0
  31. data/docs/_includes/summary.html +2 -2
  32. data/docs/_includes/ufo-ship-options.md +0 -2
  33. data/docs/docs.md +5 -1
  34. data/docs/quick-start.md +19 -10
  35. data/lib/{starter_project → template}/.env +0 -0
  36. data/lib/template/.ufo/settings.yml.tt +27 -0
  37. data/lib/{starter_project/ufo/task_definitions.rb → template/.ufo/task_definitions.rb.tt} +0 -0
  38. data/lib/{starter_project/ufo → template/.ufo}/templates/main.json.erb +0 -0
  39. data/lib/{starter_project/ufo → template/.ufo}/variables/base.rb +0 -0
  40. data/lib/{starter_project/ufo → template/.ufo}/variables/development.rb +0 -0
  41. data/lib/{starter_project/ufo → template/.ufo}/variables/production.rb +0 -0
  42. data/lib/{starter_project → template}/Dockerfile +0 -0
  43. data/lib/{starter_project/bin/deploy → template/bin/deploy.tt} +0 -0
  44. data/lib/ufo.rb +9 -2
  45. data/lib/ufo/cli.rb +34 -29
  46. data/lib/ufo/completer.rb +86 -64
  47. data/lib/ufo/core.rb +42 -0
  48. data/lib/ufo/default.rb +4 -6
  49. data/lib/ufo/default/settings.yml +24 -22
  50. data/lib/ufo/deploy.rb +0 -0
  51. data/lib/ufo/docker.rb +12 -2
  52. data/lib/ufo/docker/builder.rb +19 -49
  53. data/lib/ufo/docker/cleaner.rb +4 -2
  54. data/lib/ufo/docker/dockerfile.rb +1 -2
  55. data/lib/ufo/docker/pusher.rb +53 -0
  56. data/lib/ufo/dsl.rb +1 -2
  57. data/lib/ufo/dsl/helper.rb +3 -4
  58. data/lib/ufo/dsl/outputter.rb +1 -1
  59. data/lib/ufo/dsl/task_definition.rb +17 -37
  60. data/lib/ufo/ecr/auth.rb +22 -2
  61. data/lib/ufo/ecs.rb +5 -0
  62. data/lib/ufo/ecs/service.rb +21 -0
  63. data/lib/ufo/help/completion.md +1 -1
  64. data/lib/ufo/help/completion_script.md +1 -1
  65. data/lib/ufo/help/deploy.md +14 -0
  66. data/lib/ufo/help/docker/name.md +13 -2
  67. data/lib/ufo/help/docker/push.md +11 -0
  68. data/lib/ufo/init.rb +48 -65
  69. data/lib/ufo/log_group.rb +5 -2
  70. data/lib/ufo/sequence.rb +27 -0
  71. data/lib/ufo/setting.rb +18 -8
  72. data/lib/ufo/ship.rb +23 -46
  73. data/lib/ufo/tasks/builder.rb +8 -11
  74. data/lib/ufo/tasks/register.rb +2 -3
  75. data/lib/ufo/upgrade3.rb +64 -0
  76. data/lib/ufo/util.rb +0 -2
  77. data/lib/ufo/version.rb +1 -1
  78. data/spec/fixtures/home_existing/.docker/config.json +1 -1
  79. data/spec/fixtures/settings.yml +23 -0
  80. data/spec/lib/cli_spec.rb +1 -9
  81. data/spec/lib/completion_spec.rb +18 -0
  82. data/spec/lib/core_spec.rb +16 -0
  83. data/spec/lib/ecr_auth_spec.rb +1 -3
  84. data/spec/lib/ecr_cleaner_spec.rb +1 -3
  85. data/spec/lib/setting_spec.rb +12 -0
  86. data/spec/lib/ship_spec.rb +2 -4
  87. data/spec/lib/task_spec.rb +0 -2
  88. data/spec/spec_helper.rb +12 -2
  89. data/ufo.gemspec +2 -0
  90. metadata +47 -13
  91. data/lib/starter_project/ufo/settings.yml +0 -18
  92. data/lib/ufo/env.rb +0 -18
  93. data/lib/ufo/help/sub/goodbye.md +0 -5
@@ -16,15 +16,17 @@ module Ufo
16
16
  return if delete_list.empty?
17
17
  command = "docker rmi #{delete_list}"
18
18
  say "Cleaning up docker images...".green
19
- say "Running: #{"docker rmi #{delete_list}"}"
19
+ say "=> #{"docker rmi #{delete_list}"}".green
20
20
  return if @options[:noop]
21
21
  execute(command, use_system: false) # to use_system: false silence output
22
22
  end
23
23
 
24
24
  def delete_list
25
+ return [] if ENV['TEST']
25
26
  return @delete_list if @delete_list
26
27
 
27
- out = execute("docker images", live: true) # live to override the noop cli options
28
+ out = execute("docker images") # live to override the noop cli options
29
+
28
30
  name_regexp = Regexp.new(@docker_image_name)
29
31
  # Example tag: ufo-2016-10-19T00-36-47-211b63a
30
32
  tag_string = "#{@tag_prefix}-\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}-.{7}"
@@ -3,7 +3,6 @@ module Ufo
3
3
  def initialize(full_image_name, options={})
4
4
  @full_image_name = full_image_name
5
5
  @options = options
6
- @project_root = options[:project_root] || '.'
7
6
  end
8
7
 
9
8
  def update
@@ -15,7 +14,7 @@ module Ufo
15
14
  end
16
15
 
17
16
  def dockerfile_path
18
- "#{@project_root}/Dockerfile"
17
+ "#{Ufo.root}/Dockerfile"
19
18
  end
20
19
 
21
20
  def new_dockerfile
@@ -0,0 +1,53 @@
1
+ require 'active_support/core_ext/module/delegation'
2
+
3
+ class Ufo::Docker
4
+ class Pusher
5
+ include Ufo::Util
6
+
7
+ delegate :full_image_name, to: :builder
8
+ attr_reader :last_image_name
9
+ def initialize(image, options)
10
+ @options = options
11
+ @last_image_name = image || full_image_name
12
+ end
13
+
14
+ def push
15
+ update_auth_token
16
+ start_time = Time.now
17
+ message = "Pushed #{last_image_name} docker image."
18
+ if @options[:noop]
19
+ message = "NOOP #{message}"
20
+ else
21
+ command = "docker push #{last_image_name}"
22
+ puts "=> #{command}".colorize(:green)
23
+ success = execute(command, use_system: true)
24
+ unless success
25
+ puts "ERROR: The docker image fail to push.".colorize(:red)
26
+ exit 1
27
+ end
28
+ end
29
+ took = Time.now - start_time
30
+ message << " Took #{pretty_time(took)}.".green
31
+ puts message unless @options[:mute]
32
+ end
33
+
34
+ def builder
35
+ @builder ||= Builder.new(@options.merge(image: last_image_name))
36
+ end
37
+
38
+ def update_auth_token
39
+ auth = Ufo::Ecr::Auth.new(last_image_name)
40
+ # wont update auth token unless the image being pushed in the ECR image format
41
+ auth.update if auth.ecr_image?
42
+ end
43
+
44
+ # full_image - does not include the tag
45
+ def image_name
46
+ setting.data["image"]
47
+ end
48
+
49
+ def setting
50
+ @setting ||= Ufo::Setting.new(Ufo.root)
51
+ end
52
+ end
53
+ end
@@ -9,7 +9,6 @@ module Ufo
9
9
  def initialize(template_definitions_path, options={})
10
10
  @template_definitions_path = template_definitions_path
11
11
  @options = options
12
- @project_root = options[:project_root] || '.'
13
12
  @task_definitions = []
14
13
  @outputters = []
15
14
  end
@@ -69,7 +68,7 @@ module Ufo
69
68
 
70
69
  def clean_existing_task_definitions
71
70
  # removing 1 file a a time instead of recursing removing the directory to be safe
72
- Dir.glob("#{@options[:project_root]}/ufo/output/*").each do |path|
71
+ Dir.glob("#{Ufo.root}/.ufo/output/*").each do |path|
73
72
  FileUtils.rm_f(path)
74
73
  end
75
74
  end
@@ -10,13 +10,12 @@ module Ufo
10
10
  class Helper
11
11
  def initialize(options={})
12
12
  @options = options
13
- @project_root = options[:project_root] || '.'
14
13
  end
15
14
 
16
15
  ##############
17
16
  # helper variables
18
17
  def dockerfile_port
19
- dockerfile_path = "#{@project_root}/Dockerfile"
18
+ dockerfile_path = "#{Ufo.root}/Dockerfile"
20
19
  if File.exist?(dockerfile_path)
21
20
  parse_for_dockerfile_port(dockerfile_path)
22
21
  end
@@ -50,7 +49,7 @@ module Ufo
50
49
  end
51
50
 
52
51
  def env_file(path)
53
- full_path = "#{@project_root}/#{path}"
52
+ full_path = "#{Ufo.root}/#{path}"
54
53
  unless File.exist?(full_path)
55
54
  puts "The #{full_path} env file could not be found. Are you sure it exists?"
56
55
  exit 1
@@ -65,7 +64,7 @@ module Ufo
65
64
  end
66
65
 
67
66
  def setting
68
- @setting ||= Setting.new(@project_root)
67
+ @setting ||= Setting.new(Ufo.root)
69
68
  end
70
69
 
71
70
  def parse_for_dockerfile_port(dockerfile_path)
@@ -9,7 +9,7 @@ module Ufo
9
9
  end
10
10
 
11
11
  def write
12
- output_path = "#{@options[:project_root]}/ufo/output"
12
+ output_path = "#{Ufo.root}/.ufo/output"
13
13
  FileUtils.rm_rf(output_path) if @options[:clean]
14
14
  FileUtils.mkdir(output_path) unless File.exist?(output_path)
15
15
 
@@ -10,7 +10,6 @@ module Ufo
10
10
  @task_definition_name = task_definition_name
11
11
  @block = block
12
12
  @options = options
13
- @project_root = @options[:project_root] || '.'
14
13
  end
15
14
 
16
15
  # delegate helper method back up to dsl
@@ -21,12 +20,24 @@ module Ufo
21
20
  def build
22
21
  load_variables
23
22
  instance_eval(&@block)
24
- erb_result(source_path)
23
+
24
+ hash = assign_instance_variables
25
+ RenderMePretty.result(source_path, hash)
26
+ end
27
+
28
+ def assign_instance_variables
29
+ # copy over the instance variables from TaskDefinition scope to RenderMePretty's scope
30
+ hash = {}
31
+ instance_variables.each do |var|
32
+ key = var.to_s.sub('@','') # rid of the leading @
33
+ hash[key.to_sym] = instance_variable_get(var)
34
+ end
35
+ hash
25
36
  end
26
37
 
27
38
  def load_variables
28
39
  load_variables_file("base")
29
- load_variables_file(UFO_ENV)
40
+ load_variables_file(Ufo.env)
30
41
  end
31
42
 
32
43
  # Load the variables defined in ufo/variables/* to make available in the
@@ -50,41 +61,10 @@ module Ufo
50
61
  # NOTE: Only able to make instance variables avaialble with instance_eval
51
62
  # Wasnt able to make local variables available.
52
63
  def load_variables_file(filename)
53
- path = "#{@project_root}/ufo/variables/#{filename}.rb"
64
+ path = "#{Ufo.root}/.ufo/variables/#{filename}.rb"
54
65
  instance_eval(IO.read(path)) if File.exist?(path)
55
66
  end
56
67
 
57
- def erb_result(path)
58
- template = IO.read(path)
59
- begin
60
- ERB.new(template, nil, "-").result(binding)
61
- rescue Exception => e
62
- puts e
63
-
64
- # how to know where ERB stopped? - https://www.ruby-forum.com/topic/182051
65
- # syntax errors have the (erb):xxx info in e.message
66
- # undefined variables have (erb):xxx info in e.backtrac
67
- error_info = e.message.split("\n").grep(/\(erb\)/)[0]
68
- error_info ||= e.backtrace.grep(/\(erb\)/)[0]
69
- raise unless error_info # unable to find the (erb):xxx: error line
70
- line = error_info.split(':')[1].to_i
71
- puts "Error evaluating ERB template on line #{line.to_s.colorize(:red)} of: #{path.sub(/^\.\//, '')}"
72
-
73
- template_lines = template.split("\n")
74
- context = 5 # lines of context
75
- top, bottom = [line-context-1, 0].max, line+context-1
76
- spacing = template_lines.size.to_s.size
77
- template_lines[top..bottom].each_with_index do |line_content, index|
78
- line_number = top+index+1
79
- if line_number == line
80
- printf("%#{spacing}d %s\n".colorize(:red), line_number, line_content)
81
- else
82
- printf("%#{spacing}d %s\n", line_number, line_content)
83
- end
84
- end
85
- exit 1 unless ENV['TEST']
86
- end
87
- end
88
68
  # at this point instance_eval has been called and source has possibly been called
89
69
  def source(name)
90
70
  @source = name
@@ -101,7 +81,7 @@ module Ufo
101
81
 
102
82
  def source_path
103
83
  if @source # this means that source has been called
104
- path = "#{@project_root}/ufo/templates/#{@source}.json.erb"
84
+ path = "#{Ufo.root}/.ufo/templates/#{@source}.json.erb"
105
85
  check_source_path(path)
106
86
  else
107
87
  # default source path
@@ -113,7 +93,7 @@ module Ufo
113
93
 
114
94
  def check_source_path(path)
115
95
  unless File.exist?(path)
116
- friendly_path = path.sub("#{@project_root}/", '')
96
+ friendly_path = path.sub("#{Ufo.root}/", '')
117
97
  puts "ERROR: Could not find the #{friendly_path} template. Are sure it exists? Check where you called source in ufo/task_definitions.rb"
118
98
  exit 1
119
99
  else
@@ -1,9 +1,25 @@
1
+ =begin
2
+ Normally, you must authorized to AWS ECR to push to their registry with:
3
+
4
+ eval $(aws ecr get-login --no-include-email)
5
+
6
+ If you haven't ever ran the ecr get-login command before then you'll get this error:
7
+
8
+ no basic auth credentials
9
+
10
+ If you have ran it before but the auto token has expired you'll get this message:
11
+
12
+ denied: Your Authorization Token has expired. Please run 'aws ecr get-login' to fetch a new one.
13
+
14
+ This class manipulates the ~/.docker/config.json file which is an internal docker file to automatically update the auto token for you. If that format changes, the update will need to be updated.
15
+ =end
1
16
  module Ufo
2
17
  class Ecr::Auth
3
18
  include AwsService
4
19
 
5
- def initialize(repo_domain)
6
- @repo_domain = repo_domain
20
+ def initialize(full_image_name)
21
+ @full_image_name = full_image_name
22
+ @repo_domain = "#{full_image_name.split('/').first}"
7
23
  end
8
24
 
9
25
  def update
@@ -18,6 +34,10 @@ module Ufo
18
34
  IO.write(docker_config, JSON.pretty_generate(data))
19
35
  end
20
36
 
37
+ def ecr_image?
38
+ !!(@full_image_name =~ /\.amazonaws\.com/)
39
+ end
40
+
21
41
  def fetch_auth_token
22
42
  ecr.get_authorization_token.authorization_data.first.authorization_token
23
43
  end
@@ -0,0 +1,5 @@
1
+ module Ufo
2
+ module ECS
3
+ autoload :Service, 'ufo/ecs/service'
4
+ end
5
+ end
@@ -0,0 +1,21 @@
1
+ # Creating this class pass so we can have a reference to their properties in
2
+ # memory: cluster_name and service_name.
3
+ # This helps us avoid making additional API calls to describe and lookup the information.
4
+ #
5
+ # Also this class allows us to pass one object around instead of both
6
+ # cluster_name and service_name.
7
+ #
8
+ # This is really only used in the Ufo::Ship class.
9
+ module Ufo
10
+ module ECS
11
+ Service = Struct.new(:cluster_arn, :service_arn) do
12
+ def cluster_name
13
+ cluster_arn.split('/').last
14
+ end
15
+
16
+ def service_name
17
+ service_arn.split('/').last
18
+ end
19
+ end
20
+ end
21
+ end
@@ -12,7 +12,7 @@ Examples:
12
12
 
13
13
  To enable, TAB auto-completion add the following to your profile:
14
14
 
15
- eval $(ufo completion script)
15
+ eval $(ufo completion_script)
16
16
 
17
17
  Auto-completion example usage:
18
18
 
@@ -1,3 +1,3 @@
1
1
  To use, add the following to your ~/.bashrc or ~/.profile
2
2
 
3
- eval $(ufo completion script)
3
+ eval $(ufo completion_script)
@@ -0,0 +1,14 @@
1
+ It is useful to sometimes deploy only the task definition without re-building it. Say for example, you are debugging the task definition and just want to directly edit the `.ufo/output/hi-web.json` definition. You can accomplish this with the `ufo deploy` command. The `ufo deploy` command will deploy the task definition in `.ufo/output` unmodified. Example:
2
+
3
+ ufo deploy hi-web
4
+
5
+ The above command does the following:
6
+
7
+ 1. register the `.ufo/output/hi-web.json` task definition to ECS untouched.
8
+ 2. deploys it to ECS by updating the service
9
+
10
+ The `ufo deploy` command does less than the `ufo ship` command. Typically, people use `ufo ship` over the `ufo deploy` command do everything in one step:
11
+
12
+ 1. build the Docker image
13
+ 2. register the ECS task definition
14
+ 3. update the ECS service
@@ -1,5 +1,16 @@
1
+ This command fetches the last name that was generated when `docker build` was ran internally by `ufo docker build`. You can use it after you have built a docker image with `ufo docker build`.
2
+
1
3
  Examples:
2
4
 
3
- ufo docker name
5
+ ufo docker build # stores the docker image name in the .ufo/data folder
6
+ ufo docker name # fetches image name from .ufo/data folder
7
+
8
+ An example image name would look something like this: tongueroo/hi:ufo-2018-02-15T19-29-06-88071f5
9
+
10
+ Note, the .ufo/data folder is an internal data folder and it's structure can change in future releases.
11
+
12
+ If you want to generate a brand new name for whatever purpose, you can use the `--generate` flag. The generate does not write to the `.ufo/data` folder. It only generates a fresh name to stdout. If you run it multiple times, it will generate new names. You can notice this by seeing that the timestamp will always update. Examples:
4
13
 
5
- Docker image name that will be used: tongueroo/hi:ufo-2016-10-15T19-29-06-88071f5
14
+ ufo docker name --generate # example: tongueroo/hi:ufo-2018-02-15T10-00-00-88071f5
15
+ ufo docker name --generate # example: tongueroo/hi:ufo-2018-02-15T10-00-08-88071f5
16
+ ufo docker name --generate # example: tongueroo/hi:ufo-2018-02-15T10-00-16-88071f5
@@ -0,0 +1,11 @@
1
+ This command pushes a docker image up to the registry. By default it pushes the last image that was built with `ufo docker build`. To see what the image name is you can run `ufo docker name`. Example:
2
+
3
+ ufo docker build # to build the image
4
+ ufo docker name # to see the image name
5
+ ufo docker push # push up the registry
6
+
7
+ You can also push up a custom image by specifying the image name as the first parameter.
8
+
9
+ ufo docker push my/image:tag
10
+
11
+ The command also updates your ECR auth token in `~/.docker/config.json` in case it has expired.
@@ -1,80 +1,63 @@
1
- require 'colorize'
2
- require 'erb'
3
-
4
1
  module Ufo
5
- class Init
6
- def initialize(options = {})
7
- @options = options
8
- @project_root = options[:project_root] || '.'
2
+ class Init < Sequence
3
+ add_runtime_options! # force, pretend, quiet, skip options
4
+ # https://github.com/erikhuda/thor/blob/master/lib/thor/actions.rb#L49
5
+
6
+ # Ugly, this is how I can get the options from to match with this Thor::Group
7
+ def self.cli_options
8
+ [
9
+ [:force, type: :boolean, desc: "Bypass overwrite are you sure prompt for existing files."],
10
+ [:image, type: :string, required: true, desc: "Docker image name without the tag. Example: tongueroo/hi. Configures ufo/settings.yml"],
11
+ [:app, type: :string, required: true, desc: "App name. Preferably one word. Used in the generated ufo/task_definitions.rb."],
12
+ ]
9
13
  end
10
-
11
- def setup
12
- puts "Setting up ufo project...".blue unless @options[:quiet]
13
- source_root = File.expand_path("../../starter_project", __FILE__)
14
- # https://ruby-doc.org/core-2.2.0/Dir.html
15
- # use the File::FNM_DOTMATCH flag or something like "{*,.*}".
16
- paths = Dir.glob("#{source_root}/**/{*,.*}").
17
- select {|p| File.file?(p) }
18
- paths.each do |src|
19
- dest = src.gsub(%r{.*starter_project/},'')
20
- dest = "#{@project_root}/#{dest}"
21
-
22
- if File.exist?(dest) and !@options[:sure]
23
- puts "exists: #{dest}".yellow unless @options[:quiet]
24
- else
25
- dirname = File.dirname(dest)
26
- FileUtils.mkdir_p(dirname) unless File.exist?(dirname)
27
- if dest =~ /\.erb$/
28
- FileUtils.cp(src, dest)
29
- else
30
- write_erb_result(src, dest)
31
- end
32
- puts "created: #{dest}".green unless @options[:quiet]
33
- end
34
- end
35
- puts "Starter ufo files created.".blue
36
- File.chmod(0755, "#{@project_root}/bin/deploy")
37
- add_gitignore
14
+ cli_options.each do |args|
15
+ class_option *args
38
16
  end
39
17
 
40
- def write_erb_result(src, dest)
41
- source = IO.read(src)
42
- b = ERBContext.new(@options).get_binding
43
- output = ERB.new(source).result(b)
44
- IO.write(dest, output)
18
+ # for specs
19
+ def set_destination_root
20
+ return unless ENV['DEST_ROOT']
21
+
22
+ dest = ENV['DEST_ROOT']
23
+ FileUtils.rm_rf(dest) && FileUtils.mkdir_p(dest)
24
+ self.destination_root = dest
25
+ FileUtils.cd(dest)
45
26
  end
46
27
 
47
- def add_gitignore
48
- gitignore_path = "#{@project_root}/.gitignore"
49
- if File.exist?(gitignore_path)
50
- ignores = IO.read(gitignore_path)
51
- has_ignore = ignores.include?("ufo/output")
52
- ignores << ufo_ignores unless has_ignore
53
- else
54
- ignores = ufo_ignores
55
- end
56
- IO.write(gitignore_path, ignores)
28
+ def init_files
29
+ # map variables
30
+ @app = options[:app]
31
+ @image = options[:image]
32
+ # copy the files
33
+ puts "Setting up ufo project..."
34
+ directory "."
57
35
  end
58
36
 
59
- def ufo_ignores
60
- ignores =<<-EOL
61
- ufo/output
62
- ufo/data
37
+ def upsert_gitignore
38
+ return unless File.exist?(".gitignore")
39
+ append_to_file ".gitignore", <<-EOL
40
+ .ufo/output
41
+ .ufo/data
63
42
  EOL
64
43
  end
65
44
 
66
- end
67
- end
45
+ def user_message
46
+ puts "Starter ufo files created."
47
+ puts <<-EOL
48
+ #{"="*64}
49
+ Congrats 🎉 You have successfully set up ufo for your project. To deploy to ECS:
68
50
 
69
- # http://stackoverflow.com/questions/1338960/ruby-templates-how-to-pass-variables-into-inlined-erb
70
- class ERBContext
71
- def initialize(hash)
72
- hash.each_pair do |key, value|
73
- instance_variable_set('@' + key.to_s, value)
74
- end
75
- end
51
+ ufo ship #{@app}-web
52
+
53
+ If you need to customize the ECS task definition to configure things like memory and cpu allocation. You can do this by adjusting the files the .ufo/variables folder. These variables get applied to the .ufo/templates/main.json.erb task definition json that is passed to the ECS register task definition api.
54
+
55
+ Some additional starter example roles for your apps were set up in in .ufo/task_definitions.rb. Be sure to check it out and adjust it for your needs.
76
56
 
77
- def get_binding
78
- binding
57
+ This allows you to fully customize and control your environment to fit your application's needs.
58
+
59
+ More info: http://ufoships.com
60
+ EOL
61
+ end
79
62
  end
80
63
  end