lono 3.5.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -4
  3. data/.rspec +1 -0
  4. data/CHANGELOG.md +15 -1
  5. data/Gemfile +3 -3
  6. data/Guardfile +17 -8
  7. data/{LICENSE → LICENSE.txt} +1 -1
  8. data/README.md +20 -12
  9. data/Rakefile +1 -2
  10. data/{bin → exe}/lono +1 -0
  11. data/lib/lono.rb +12 -9
  12. data/lib/lono/cfn.rb +7 -9
  13. data/lib/lono/cfn/{aws_services.rb → aws_service.rb} +1 -1
  14. data/lib/lono/cfn/base.rb +41 -38
  15. data/lib/lono/cfn/create.rb +6 -2
  16. data/lib/lono/cfn/delete.rb +2 -2
  17. data/lib/lono/cfn/diff.rb +1 -1
  18. data/lib/lono/cfn/preview.rb +26 -15
  19. data/lib/lono/cfn/update.rb +11 -9
  20. data/lib/lono/cfn/util.rb +3 -3
  21. data/lib/lono/clean.rb +1 -1
  22. data/lib/lono/cli.rb +71 -39
  23. data/lib/lono/command.rb +42 -18
  24. data/lib/lono/completer.rb +162 -0
  25. data/lib/lono/completer/script.rb +6 -0
  26. data/lib/lono/completer/script.sh +10 -0
  27. data/lib/lono/completion.rb +15 -0
  28. data/lib/lono/core.rb +23 -9
  29. data/lib/lono/core/config.rb +20 -0
  30. data/lib/lono/default/settings.yml +33 -13
  31. data/lib/lono/help.rb +6 -79
  32. data/lib/lono/help/cfn.md +6 -0
  33. data/lib/lono/help/cfn/create.md +22 -0
  34. data/lib/lono/help/cfn/delete.md +5 -0
  35. data/lib/lono/help/cfn/diff.md +5 -0
  36. data/lib/lono/help/cfn/download.md +5 -0
  37. data/lib/lono/help/cfn/preview.md +11 -0
  38. data/lib/lono/help/cfn/update.md +21 -0
  39. data/lib/lono/help/completion.md +22 -0
  40. data/lib/lono/help/completion_script.md +3 -0
  41. data/lib/lono/help/generate.md +7 -0
  42. data/lib/lono/help/hello.md +5 -0
  43. data/lib/lono/help/import.md +7 -0
  44. data/lib/lono/help/inspect.md +4 -0
  45. data/lib/lono/help/inspect/depends.md +3 -0
  46. data/lib/lono/help/inspect/summary.md +3 -0
  47. data/lib/lono/help/new.md +8 -0
  48. data/lib/lono/help/param.md +3 -0
  49. data/lib/lono/{param/help.rb → help/param/generate.md} +1 -9
  50. data/lib/lono/help/script/build.md +5 -0
  51. data/lib/lono/help/script/upload.md +8 -0
  52. data/lib/lono/help/template.md +4 -0
  53. data/lib/lono/help/template/bashify.md +4 -0
  54. data/lib/lono/help/template/generate.md +7 -0
  55. data/lib/lono/help/user_data.md +3 -0
  56. data/lib/lono/importer.rb +43 -20
  57. data/lib/lono/inspector.rb +2 -19
  58. data/lib/lono/inspector/base.rb +2 -2
  59. data/lib/lono/inspector/{depends.rb → graph.rb} +3 -3
  60. data/lib/lono/inspector/summary.rb +1 -1
  61. data/lib/lono/new.rb +79 -26
  62. data/lib/lono/new/helper.rb +16 -0
  63. data/lib/lono/new/message.rb +35 -0
  64. data/lib/lono/param.rb +1 -2
  65. data/lib/lono/param/generator.rb +34 -86
  66. data/lib/lono/project_checker.rb +35 -40
  67. data/lib/lono/script.rb +19 -0
  68. data/lib/lono/script/base.rb +9 -0
  69. data/lib/lono/script/build.rb +73 -0
  70. data/lib/lono/script/upload.rb +81 -0
  71. data/lib/lono/sequence.rb +33 -0
  72. data/lib/lono/setting.rb +83 -0
  73. data/lib/lono/template.rb +8 -9
  74. data/lib/lono/template/{aws_services.rb → aws_service.rb} +1 -1
  75. data/lib/lono/template/context.rb +73 -0
  76. data/lib/lono/template/dsl.rb +63 -64
  77. data/lib/lono/template/helper.rb +201 -0
  78. data/lib/lono/template/template.rb +29 -221
  79. data/lib/lono/template/upload.rb +41 -33
  80. data/lib/lono/upgrade4.rb +175 -0
  81. data/lib/lono/user_data.rb +31 -0
  82. data/lib/lono/version.rb +1 -1
  83. data/lib/starter_projects/autoscaling/.gitignore +1 -0
  84. data/lib/starter_projects/{json_project → autoscaling}/Gemfile +0 -0
  85. data/lib/starter_projects/{yaml_project → autoscaling}/Guardfile +0 -0
  86. data/lib/starter_projects/autoscaling/README.md +118 -0
  87. data/lib/starter_projects/autoscaling/app/definitions/base.rb +2 -0
  88. data/lib/starter_projects/autoscaling/app/templates/autoscaling.yml +682 -0
  89. data/lib/starter_projects/autoscaling/config/params/base/autoscaling.txt +6 -0
  90. data/lib/starter_projects/autoscaling/config/settings.yml +33 -0
  91. data/lib/starter_projects/ec2/.gitignore +1 -0
  92. data/lib/starter_projects/{yaml_project → ec2}/Gemfile +0 -0
  93. data/lib/starter_projects/{json_project → ec2}/Guardfile +1 -1
  94. data/lib/starter_projects/ec2/README.md +86 -0
  95. data/lib/starter_projects/ec2/app/definitions/base.rb +2 -0
  96. data/lib/starter_projects/ec2/app/definitions/development.rb +1 -0
  97. data/lib/starter_projects/ec2/app/definitions/production.rb +1 -0
  98. data/lib/starter_projects/{yaml_project → ec2/app}/helpers/my_custom_helper.rb +0 -0
  99. data/lib/starter_projects/{json_project/templates/user_data/app.sh → ec2/app/partials/user_data/bootstrap.sh} +1 -2
  100. data/lib/starter_projects/{yaml_project → ec2/app}/templates/example.yml +0 -0
  101. data/lib/starter_projects/{json_project/params/base/api-web.txt → ec2/config/params/base/example.txt} +0 -0
  102. data/lib/starter_projects/ec2/config/params/development/example.txt +3 -0
  103. data/lib/starter_projects/ec2/config/params/production/example.txt +2 -0
  104. data/lib/starter_projects/ec2/config/settings.yml +33 -0
  105. data/lib/starter_projects/ec2/config/variables/base.rb +3 -0
  106. data/lib/starter_projects/ec2/config/variables/development.rb +2 -0
  107. data/lib/starter_projects/ec2/config/variables/production.rb +2 -0
  108. data/lib/starter_projects/ec2/welcome.txt +8 -0
  109. data/lib/starter_projects/skeleton/.gitignore +1 -0
  110. data/lib/starter_projects/skeleton/Gemfile +3 -0
  111. data/lib/starter_projects/skeleton/Guardfile +12 -0
  112. data/lib/starter_projects/skeleton/README.md +53 -0
  113. data/{spec/fixtures/my_project/templates/.gitkeep → lib/starter_projects/skeleton/app/definitions/base.rb} +0 -0
  114. data/lib/starter_projects/skeleton/config/settings.yml +33 -0
  115. data/lib/starter_projects/skeleton/welcome.txt +7 -0
  116. data/lono.gemspec +12 -10
  117. data/spec/fixtures/lono_project/.gitignore +1 -0
  118. data/spec/fixtures/lono_project/Gemfile +3 -0
  119. data/spec/fixtures/lono_project/Guardfile +12 -0
  120. data/spec/fixtures/lono_project/app/definitions/base.rb +10 -0
  121. data/spec/fixtures/lono_project/app/definitions/base/more.rb +7 -0
  122. data/spec/fixtures/lono_project/app/definitions/development.rb +1 -0
  123. data/spec/fixtures/lono_project/app/definitions/production.rb +1 -0
  124. data/spec/fixtures/lono_project/app/helpers/custom_helper.rb +5 -0
  125. data/spec/fixtures/lono_project/app/partials/security_group.yml +10 -0
  126. data/{lib/starter_projects/yaml_project/templates/partial → spec/fixtures/lono_project/app/partials}/user_data/bootstrap.sh +8 -2
  127. data/spec/fixtures/lono_project/app/templates/example.yml +50 -0
  128. data/{lib/starter_projects/yaml_project/params/base/api-web-prod.txt → spec/fixtures/lono_project/config/params/base/example.txt} +1 -0
  129. data/spec/fixtures/lono_project/config/params/development/example.txt +1 -0
  130. data/spec/fixtures/lono_project/config/params/production/example.txt +1 -0
  131. data/spec/fixtures/lono_project/config/settings.yml +31 -0
  132. data/spec/fixtures/lono_project/config/variables/base.rb +3 -0
  133. data/spec/fixtures/lono_project/config/variables/development.rb +1 -0
  134. data/spec/fixtures/lono_project/config/variables/production.rb +1 -0
  135. data/spec/fixtures/params/envonly/params/{prod → development}/network.txt +0 -0
  136. data/spec/fixtures/params/overlay/params/{prod → development}/network.txt +0 -0
  137. data/spec/fixtures/raw_templates/aws-waf-security-automations.template +2 -2
  138. data/spec/lib/lono/cfn_spec.rb +6 -9
  139. data/spec/lib/lono/cli_spec.rb +44 -0
  140. data/spec/lib/lono/completion_spec.rb +17 -0
  141. data/spec/lib/lono/inspect_spec.rb +6 -15
  142. data/spec/lib/lono/param/generator_spec.rb +45 -26
  143. data/spec/lib/lono/param_spec.rb +1 -3
  144. data/spec/lib/lono/setting_spec.rb +47 -0
  145. data/spec/lib/lono/template/dsl_spec.rb +33 -157
  146. data/spec/lib/lono/template_spec.rb +4 -16
  147. data/spec/spec_helper.rb +45 -14
  148. metadata +168 -82
  149. data/.coveralls.yml +0 -1
  150. data/lib/lono/cfn/help.rb +0 -103
  151. data/lib/lono/current_region.rb +0 -42
  152. data/lib/lono/inspector/help.rb +0 -21
  153. data/lib/lono/settings.rb +0 -45
  154. data/lib/lono/template/help.rb +0 -25
  155. data/lib/lono/template/helpers.rb +0 -136
  156. data/lib/starter_projects/json_project/.gitignore +0 -1
  157. data/lib/starter_projects/json_project/config/templates/base/blog.rb +0 -20
  158. data/lib/starter_projects/json_project/config/templates/base/stacks.rb +0 -58
  159. data/lib/starter_projects/json_project/templates/db.json +0 -212
  160. data/lib/starter_projects/json_project/templates/partial/host_record.json +0 -28
  161. data/lib/starter_projects/json_project/templates/partial/server.json +0 -45
  162. data/lib/starter_projects/json_project/templates/user_data/db.sh +0 -39
  163. data/lib/starter_projects/json_project/templates/user_data/db2.sh +0 -2
  164. data/lib/starter_projects/json_project/templates/user_data/ruby_script.rb +0 -5
  165. data/lib/starter_projects/json_project/templates/web.json +0 -386
  166. data/lib/starter_projects/yaml_project/.gitignore +0 -1
  167. data/lib/starter_projects/yaml_project/config/templates/base/blog.rb +0 -20
  168. data/lib/starter_projects/yaml_project/config/templates/base/stacks.rb +0 -56
  169. data/lib/starter_projects/yaml_project/config/templates/prod/stacks.rb +0 -1
  170. data/lib/starter_projects/yaml_project/config/templates/stag/stacks.rb +0 -1
  171. data/lib/starter_projects/yaml_project/config/variables/base/variables.rb +0 -4
  172. data/lib/starter_projects/yaml_project/config/variables/prod/variables.rb +0 -1
  173. data/lib/starter_projects/yaml_project/config/variables/stag/variables.rb +0 -1
  174. data/lib/starter_projects/yaml_project/params/base/example.txt +0 -2
  175. data/lib/starter_projects/yaml_project/params/prod/example.txt +0 -1
  176. data/lib/starter_projects/yaml_project/params/stag/example.txt +0 -1
  177. data/lib/starter_projects/yaml_project/templates/db.yml +0 -148
  178. data/lib/starter_projects/yaml_project/templates/partial/host_record.yml +0 -14
  179. data/lib/starter_projects/yaml_project/templates/partial/server.yml +0 -59
  180. data/lib/starter_projects/yaml_project/templates/web.yml +0 -206
  181. data/spec/fixtures/my_project/config/templates/base/stacks.rb +0 -3
  182. data/spec/fixtures/my_project/params/my-stack.txt +0 -3
  183. data/spec/fixtures/my_project/templates/my-stack.yml +0 -0
  184. data/spec/lib/lono/new_spec.rb +0 -59
  185. data/spec/lib/lono/template/template_spec.rb +0 -104
  186. data/spec/lib/lono_spec.rb +0 -27
@@ -0,0 +1,8 @@
1
+ Uploads output/scripts/scripts-md5sum.tgz to s3_folder configured in settings.yml. This command must be ran after `lono script build` since it relies the artifacts of that command. Namely:
2
+
3
+ * output/scripts/scripts-md5sum.tgz
4
+ * output/data/scripts_name.txt
5
+
6
+ Examples:
7
+
8
+ lono script upload
@@ -0,0 +1,4 @@
1
+ Examples:
2
+
3
+ lono template generate --help
4
+ lono template bashify --help
@@ -0,0 +1,4 @@
1
+ Examples:
2
+
3
+ lono template bashify /path/to/cloudformation-template.json
4
+ lono template bashify https://s3.amazonaws.com/cloudformation-templates-us-east-1/EC2WebSiteSample.template
@@ -0,0 +1,7 @@
1
+ Examples:
2
+
3
+ lono template generate
4
+ lono template generate --clean
5
+ lono template g --clean
6
+
7
+ Builds the CloudFormation templates files based on lono project and writes them to the output folder on the filesystem.
@@ -0,0 +1,3 @@
1
+ Generates user_data scripts in `app/user_data` so you can see it for debugging. Let's say you have a script in `app/user_data/bootstrap.sh`. To generate it:
2
+
3
+ lono user_data bootstrap
data/lib/lono/importer.rb CHANGED
@@ -7,7 +7,8 @@ class Lono::Importer
7
7
  def initialize(source, options)
8
8
  @source = source
9
9
  @options = options
10
- @format = normalize_format(@options[:format])
10
+ @format = 'yml'
11
+ Lono::ProjectChecker.check
11
12
  end
12
13
 
13
14
  def run
@@ -15,20 +16,43 @@ class Lono::Importer
15
16
  download_template
16
17
  template_definition_path = add_template_definition
17
18
  create_params
18
- puts "Imported raw CloudFormation template and lono-fied it!"
19
- puts "Template definition added to #{template_definition_path}."
20
- puts "Params file created to #{params_path}."
19
+ puts "=> Imported CloudFormation template and lono-fied it.".colorize(:green)
20
+ puts "Template definition added to #{pretty_path(template_definition_path)}"
21
+ puts "Params file created to #{pretty_path(params_path)}"
21
22
  end
22
- puts "Template downloaded to #{template_path}." # like having this message at the end
23
+ puts "Template downloaded to #{pretty_path(template_path)}" # like having this message at the end
24
+
25
+ # at the end display some useful info for the user
26
+ return unless options[:summary]
27
+ summarize
28
+ show_params_file
29
+ end
30
+
31
+ def summarize
32
+ Lono::Inspector::Summary.new(template_name, @options).run
33
+ end
34
+
35
+ def show_params_file
36
+ path = "config/params/base/#{template_name}.txt"
37
+ puts "Here are contents of the params #{path} file:"
38
+ puts IO.read("#{Lono.root}/#{path}")
39
+ end
40
+
41
+ def json?(text)
42
+ JSON.load(text)
43
+ true # if reach here than it's just
44
+ rescue JSON::ParserError
45
+ false # not json
23
46
  end
24
47
 
25
48
  def download_template
26
49
  template = open(@source).read
27
50
 
28
- result = if @format == 'yml'
51
+ result = if json?(template)
52
+ # abusing YAML.dump(YAML.load()) to convert json to yaml
29
53
  YAML.dump(YAML.load(template))
30
54
  else
31
- JSON.pretty_generate(JSON.load(template))
55
+ template # template is already in YAML format
32
56
  end
33
57
 
34
58
  folder = File.dirname(template_path)
@@ -36,9 +60,9 @@ class Lono::Importer
36
60
  IO.write(template_path, result)
37
61
  end
38
62
 
39
- # Add template definition to config/templates/base/stacks.rb.
63
+ # Add template definition to app/definitions/base.rb.
40
64
  def add_template_definition
41
- path = "#{Lono.root}/config/templates/base/stacks.rb"
65
+ path = "#{Lono.config.definitions_path}/base.rb"
42
66
  lines = File.exist?(path) ? IO.readlines(path) : []
43
67
  new_template_definition = %Q|template "#{template_name}"|
44
68
  unless lines.detect { |l| l.include?(new_template_definition) }
@@ -51,11 +75,7 @@ class Lono::Importer
51
75
 
52
76
  # Creates starter params/base/[stack-name].txt file
53
77
  def create_params
54
- template = if @format == 'yml'
55
- YAML.load_file(template_path)
56
- else
57
- JSON.load(IO.read(template_path))
58
- end
78
+ template = YAML.load_file(template_path)
59
79
 
60
80
  result = []
61
81
  required_parameters.each do |name, attributes|
@@ -73,17 +93,19 @@ class Lono::Importer
73
93
  end
74
94
 
75
95
  def params_path
76
- "#{Lono.root}/params/base/#{template_name}.txt"
96
+ "#{Lono.config.params_path}/base/#{template_name}.txt"
77
97
  end
78
98
 
79
99
 
80
100
  def template_path
81
- "#{Lono.root}/templates/#{template_name}.#{@format}"
101
+ "#{Lono.config.templates_path}/#{template_name}.#{@format}"
82
102
  end
83
103
 
84
104
  def template_name
85
105
  return @options[:name] if @options[:name]
86
- # else infer name from the original source
106
+ # Else infer name from the original source.
107
+ # Not really being used since --name is now required but leaving in place
108
+ # in case we decide to make --name optional again
87
109
  name = File.basename(@source, ".*")
88
110
  @options[:casing] == "camelcase" ? name.camelize : name.underscore.dasherize
89
111
  end
@@ -103,11 +125,12 @@ private
103
125
 
104
126
  def template_data
105
127
  return @template_data if @template_data
106
- template_path = "#{Lono.root}/templates/#{template_name}.#{@format}"
128
+ template_path = "#{Lono.config.templates_path}/#{template_name}.#{@format}"
107
129
  @template_data = YAML.load(IO.read(template_path))
108
130
  end
109
131
 
110
- def normalize_format(format)
111
- format == 'yaml' ? 'yml' : format
132
+ # removes the ./ at the beginning if it's there in the path
133
+ def pretty_path(path)
134
+ path[0..1] == './' ? path[2..-1] : path
112
135
  end
113
136
  end
@@ -1,24 +1,7 @@
1
1
  require "thor"
2
2
 
3
- class Lono::Inspector < Lono::Command
4
- autoload :Help, 'lono/inspector/help'
3
+ class Lono::Inspector
5
4
  autoload :Base, 'lono/inspector/base'
6
- autoload :Depends, 'lono/inspector/depends'
5
+ autoload :Graph, 'lono/inspector/graph'
7
6
  autoload :Summary, 'lono/inspector/summary'
8
-
9
- class_option :verbose, type: :boolean
10
- class_option :noop, type: :boolean
11
-
12
- desc "depends STACK", "Prints dependencies tree of CloudFormation template resources"
13
- long_desc Help.depends
14
- option :display, type: :string, desc: "graph or text", default: "graph"
15
- def depends(name)
16
- Depends.new(name, options).run
17
- end
18
-
19
- desc "summary STACK", "Prints summary of CloudFormation template"
20
- long_desc Help.summary
21
- def summary(name)
22
- Summary.new(name, options).run
23
- end
24
7
  end
@@ -5,7 +5,7 @@ class Lono::Inspector::Base
5
5
  end
6
6
 
7
7
  def generate_templates
8
- Lono::Template::DSL.new(@options.clone).run
8
+ Lono::Template::DSL.new(@options.clone.merge(quiet: true)).run
9
9
  end
10
10
 
11
11
  def run
@@ -15,7 +15,7 @@ class Lono::Inspector::Base
15
15
 
16
16
  def data
17
17
  return @data if @data
18
- template_path = "#{Lono.root}/output/#{@stack_name}.yml"
18
+ template_path = "#{Lono.config.output_path}/templates/#{@stack_name}.yml"
19
19
  check_template_exists(template_path)
20
20
  @data = YAML.load(IO.read(template_path))
21
21
  end
@@ -1,7 +1,7 @@
1
1
  require "yaml"
2
2
  require "graph"
3
3
 
4
- class Lono::Inspector::Depends < Lono::Inspector::Base
4
+ class Lono::Inspector::Graph < Lono::Inspector::Base
5
5
  def initialize(stack_name, options)
6
6
  super
7
7
  @nodes = [] # lookup map
@@ -38,9 +38,9 @@ class Lono::Inspector::Depends < Lono::Inspector::Base
38
38
  end
39
39
  end
40
40
 
41
- # normalized DependsOn attribute to an Array of Strings
41
+ # normalized DependOn attribute to an Array of Strings
42
42
  def normalize_depends_on(resource)
43
- dependencies = resource["DependsOn"] || []
43
+ dependencies = resource["DependOn"] || []
44
44
  [dependencies].flatten
45
45
  end
46
46
 
@@ -1,6 +1,6 @@
1
1
  class Lono::Inspector::Summary < Lono::Inspector::Base
2
2
  def perform
3
- puts "CloudFormation Template Summary:".colorize(:green)
3
+ puts "=> CloudFormation Template Summary:".colorize(:green)
4
4
  return if @options[:noop]
5
5
 
6
6
  puts "Parameters:"
data/lib/lono/new.rb CHANGED
@@ -1,31 +1,84 @@
1
- class Lono::New
2
- attr_reader :options
3
- def initialize(options)
4
- @options = options
5
- @project_root = options[:project_root] || '.'
6
- @format = options[:format] || 'json'
7
- end
1
+ module Lono
2
+ class New < Sequence
3
+ autoload :Helper, 'lono/new/helper'
4
+ autoload :Message, 'lono/new/message'
5
+ include Helper
6
+ include Message
7
+
8
+ argument :project_name
9
+
10
+ # Ugly, but when the class_option is only defined in the Thor::Group class
11
+ # it doesnt show up with cli-template new help :(
12
+ # If anyone knows how to fix this let me know.
13
+ # Also options from the cli can be pass through to here
14
+ def self.cli_options
15
+ [
16
+ [:force, type: :boolean, desc: "Bypass overwrite are you sure prompt for existing files."],
17
+ [:bundle, type: :boolean, default: true, desc: "Runs bundle install on the project"],
18
+ [:git, type: :boolean, default: true, desc: "Git initialize the project"],
19
+ ]
20
+ end
21
+
22
+ cli_options.each do |args|
23
+ class_option *args
24
+ end
8
25
 
9
- def run
10
- puts "Setting up lono project" unless options[:quiet]
11
- source_root = File.expand_path("../../starter_projects/#{@format}_project", __FILE__)
12
- paths = Dir.glob("#{source_root}/**/*").
13
- select {|p| File.file?(p) }
14
- paths.each do |src|
15
- # starter_projects/yaml_project/ ->
16
- regexp = Regexp.new(".*starter_projects/#{@format}_project/")
17
- dest = src.gsub(regexp,'')
18
- dest = "#{@project_root}/#{dest}"
19
-
20
- if File.exist?(dest) and !options[:force]
21
- puts "already exists: #{dest}" unless options[:quiet]
22
- else
23
- puts "creating: #{dest}" unless options[:quiet]
24
- dirname = File.dirname(dest)
25
- FileUtils.mkdir_p(dirname) unless File.exist?(dirname)
26
- FileUtils.cp(src, dest)
26
+ # for specs
27
+ def set_cwd
28
+ @cwd = ENV['TEST'] ? File.dirname(Lono.root) : Dir.pwd
29
+ end
30
+
31
+ def create_project
32
+ puts "=> Creating new project called #{project_name}."
33
+ directory ".", "#{@cwd}/#{project_name}"
34
+ end
35
+
36
+ def create_empty_directories
37
+ meths = Lono::Core::Config::PATHS.keys
38
+ meths.each do |meth|
39
+ path = "#{@cwd}/#{project_name}/#{Lono.config.send(meth)}"
40
+ next if File.exist?(path)
41
+ if ENV['TEST']
42
+ empty_directory Lono.config.send(meth)
43
+ else
44
+ empty_directory path
45
+ end
27
46
  end
28
47
  end
29
- puts "Starter lono project created" unless options[:quiet]
48
+
49
+ # After this commands are executed with the newly created project
50
+ def set_destination_root
51
+ destination_root = "#{@cwd}/#{project_name}"
52
+ self.destination_root = destination_root
53
+ FileUtils.cd(self.destination_root)
54
+ end
55
+
56
+ def make_executable
57
+ chmod("exe", 0755 & ~File.umask, verbose: false) if File.exist?("exe")
58
+ end
59
+
60
+ def bundle_install
61
+ return unless options[:bundle]
62
+
63
+ puts "=> Installing dependencies with: bundle install"
64
+ Bundler.with_clean_env do
65
+ system("BUNDLE_IGNORE_CONFIG=1 bundle install")
66
+ end
67
+ end
68
+
69
+ def git_init
70
+ return if !options[:git]
71
+ return unless git_installed?
72
+ return if File.exist?(".git") # this is a clone repo
73
+
74
+ puts "=> Initialize git repo"
75
+ run("git init")
76
+ run("git add .")
77
+ run("git commit -m 'first commit'")
78
+ end
79
+
80
+ def final_message
81
+ puts welcome_message
82
+ end
30
83
  end
31
84
  end
@@ -0,0 +1,16 @@
1
+ module Lono::New::Helper
2
+ private
3
+ def project_class_name
4
+ project_name.underscore.camelize
5
+ end
6
+
7
+ # Files should be named with underscores instead of dashes even
8
+ # though project name can contain a dash. This is because autoloading
9
+ # works will underscores in the filenames only.
10
+ def underscored_name
11
+ project_name.underscore
12
+ end
13
+
14
+ # project_name is also available from new.rb:
15
+ # argument :project_name
16
+ end
@@ -0,0 +1,35 @@
1
+ module Lono::New::Message
2
+ private
3
+ def welcome_message
4
+ <<-EOL
5
+ #{"="*64}
6
+ Congrats 🎉 You have successfully created a lono project.
7
+
8
+ Cd into your project and check things out:
9
+
10
+ cd #{project_name}
11
+
12
+ #{template_specific_message}
13
+ To re-generate your templates without launching a stack, you can run:
14
+
15
+ lono generate
16
+
17
+ The generated CloudFormation templates are in the output/templates folder.
18
+ The generated stack parameters are in the output/params folder.
19
+
20
+ More info: http://lono.cloud/
21
+ EOL
22
+ end
23
+
24
+ def template_specific_message
25
+ starter_projects = File.expand_path("../../starter_projects", File.dirname(__FILE__))
26
+ welcome_path = "#{starter_projects}/#{ENV['TEMPLATE']}/welcome.txt"
27
+ puts "welcome_path #{welcome_path.inspect}"
28
+
29
+ # default to the skeleton welcome message
30
+ unless File.exist?(welcome_path)
31
+ welcome_path = "#{starter_projects}/skeleton/welcome.txt"
32
+ end
33
+ IO.read(welcome_path)
34
+ end
35
+ end
data/lib/lono/param.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  require "thor"
2
2
 
3
3
  class Lono::Param < Lono::Command
4
- autoload :Help, 'lono/param/help'
5
4
  autoload :Generator, 'lono/param/generator'
6
5
 
7
6
  class_option :verbose, type: :boolean
@@ -9,7 +8,7 @@ class Lono::Param < Lono::Command
9
8
  class_option :mute, type: :boolean
10
9
 
11
10
  desc "generate", "generate all parameter files to json format"
12
- long_desc Help.generate
11
+ long_desc Lono::Help.text("param/generate")
13
12
  option :path, desc: "Name of the source that maps to the params txt file. name -> params/NAME.txt. Use this to override the params/NAME.txt convention"
14
13
  def generate
15
14
  Generator.generate_all(options)
@@ -1,8 +1,6 @@
1
1
  class Lono::Param::Generator
2
- include Lono::CurrentRegion
3
-
4
2
  def self.generate_all(options)
5
- puts "Generating params files"
3
+ puts "Generating parameter files:"
6
4
 
7
5
  params = param_names("base") + param_names(Lono.env)
8
6
  params.uniq.each do |name|
@@ -18,39 +16,48 @@ class Lono::Param::Generator
18
16
  # Returns:
19
17
  # param_names("base") => ["a", "b", "c"]
20
18
  def self.param_names(folder)
21
- base_folder = "#{Lono.root}/params/#{folder}" # Example: "./params/base"
19
+ base_folder = "#{Lono.config.params_path}/#{folder}" # Example: "./params/base"
22
20
  Dir.glob("#{base_folder}/**/*.txt").map do |path|
23
21
  path.sub("#{base_folder}/", '').sub('.txt','')
24
22
  end
25
23
  end
26
24
 
27
25
  def initialize(name, options)
28
- @_name = "#{Lono.env}/#{name}"
29
- @_options = options
30
- @_env_path = options[:path] || "#{Lono.root}/params/#{@_name}.txt"
31
- @_base_path = @_env_path.sub("/#{Lono.env}/", "/base/")
26
+ @name = "#{Lono.env}/#{name}"
27
+ @options = options
28
+ @env_path = options[:path] || "#{Lono.config.params_path}/#{@name}.txt"
29
+ @base_path = @env_path.sub("/#{Lono.env}/", "/base/")
32
30
  end
33
31
 
34
32
  def generate
35
33
  # useful option for lono cfn
36
- return if @_options[:allow_no_file] && !source_exist?
34
+ return if @options[:allow_no_file] && !source_exist?
37
35
 
38
36
  if source_exist?
39
- contents = overlay_sources
37
+ contents = process_erb
40
38
  data = convert_to_cfn_format(contents)
41
39
  json = JSON.pretty_generate(data)
42
40
  write_output(json)
43
- # Example: @_name = stag/ecs/private
41
+ # Example: @name = stag/ecs/private
44
42
  # pretty_name = ecs/private
45
- pretty_name = @_name.sub("#{Lono.env}/", '')
46
- puts "Params file generated for #{pretty_name} at #{output_path}" unless @_options[:mute]
43
+ pretty_name = @name.sub("#{Lono.env}/", '')
44
+ puts " #{output_path}" unless @options[:mute]
47
45
  else
48
- puts "#{@_base_path} or #{@_env_path} could not be found? Are you sure it exist?"
46
+ puts "#{@base_path} or #{@env_path} could not be found? Are you sure it exist?"
49
47
  exit 1
50
48
  end
51
49
  json
52
50
  end
53
51
 
52
+ # useful for when calling CloudFormation via the aws-sdk gem
53
+ def params(casing = :underscore)
54
+ # useful option for lono cfn
55
+ return {} if @options[:allow_no_file] && !source_exist?
56
+
57
+ contents = process_erb
58
+ convert_to_cfn_format(contents, casing)
59
+ end
60
+
54
61
  # Reads both the base source and env source and overlay the two
55
62
  # Example 1:
56
63
  # params/base/mystack.txt - base path
@@ -68,51 +75,23 @@ class Lono::Param::Generator
68
75
  # params/prod/mystack.txt - env path
69
76
  #
70
77
  # the prod/mystack.txt is used to produced a prod/mystack.txt
71
- def overlay_sources
78
+ def process_erb
72
79
  contents = []
73
- contents << process_erb(@_base_path)
74
- contents << process_erb(@_env_path)
80
+ contents << render_erb(@base_path)
81
+ contents << render_erb(@env_path)
75
82
  contents.compact.join("\n")
76
83
  end
77
84
 
78
- def process_erb(path)
85
+ def render_erb(path)
79
86
  if File.exist?(path)
80
- template = IO.read(path)
81
- erb_result(path, template)
87
+ RenderMePretty.result(path, context: context)
82
88
  end
83
89
  end
84
90
 
85
- def erb_result(path, template)
86
- load_variables
87
- begin
88
- ERB.new(template, nil, "-").result(binding)
89
- rescue Exception => e
90
- puts e
91
- puts e.backtrace if ENV['DEBUG']
92
-
93
- # how to know where ERB stopped? - https://www.ruby-forum.com/topic/182051
94
- # syntax errors have the (erb):xxx info in e.message
95
- # undefined variables have (erb):xxx info in e.backtrac
96
- error_info = e.message.split("\n").grep(/\(erb\)/)[0]
97
- error_info ||= e.backtrace.grep(/\(erb\)/)[0]
98
- raise unless error_info # unable to find the (erb):xxx: error line
99
- line = error_info.split(':')[1].to_i
100
- puts "Error evaluating ERB template on line #{line.to_s.colorize(:red)} of: #{path.sub(/^\.\//, '').colorize(:green)}"
101
-
102
- template_lines = template.split("\n")
103
- context = 5 # lines of context
104
- top, bottom = [line-context-1, 0].max, line+context-1
105
- spacing = template_lines.size.to_s.size
106
- template_lines[top..bottom].each_with_index do |line_content, index|
107
- line_number = top+index+1
108
- if line_number == line
109
- printf("%#{spacing}d %s\n".colorize(:red), line_number, line_content)
110
- else
111
- printf("%#{spacing}d %s\n", line_number, line_content)
112
- end
113
- end
114
- exit 1 unless ENV['TEST']
115
- end
91
+ # Context for ERB rendering.
92
+ # This is where we control what references get passed to the ERB rendering.
93
+ def context
94
+ @context ||= Lono::Template::Context.new(@options)
116
95
  end
117
96
 
118
97
  # Checks both base and source path for existing of the param file.
@@ -120,16 +99,7 @@ class Lono::Param::Generator
120
99
  # params/base/mystack.txt - base path
121
100
  # params/prod/mystack.txt - source path
122
101
  def source_exist?
123
- File.exist?(@_base_path) || File.exist?(@_env_path)
124
- end
125
-
126
- # useful for when calling CloudFormation via the aws-sdk gem
127
- def params(casing = :underscore)
128
- # useful option for lono cfn
129
- return {} if @_options[:allow_no_file] && !source_exist?
130
-
131
- contents = overlay_sources
132
- convert_to_cfn_format(contents, casing)
102
+ File.exist?(@base_path) || File.exist?(@env_path)
133
103
  end
134
104
 
135
105
  def parse_contents(contents)
@@ -177,35 +147,13 @@ class Lono::Param::Generator
177
147
  end
178
148
 
179
149
  def output_path
180
- "#{Lono.root}/output/params/#{@_name}.json".sub(/\.\//,'')
150
+ name = @name.sub("#{Lono.env}/", "") # remove the Lono.env from the output path
151
+ "#{Lono.config.output_path}/params/#{name}.json".sub(/\.\//,'')
181
152
  end
182
153
 
183
154
  def write_output(json)
184
155
  dir = File.dirname(output_path)
185
- FileUtils.mkdir_p(dir) unless File.exist?(dir)
156
+ FileUtils.mkdir_p(dir)
186
157
  IO.write(output_path, json)
187
158
  end
188
-
189
-
190
- def load_variables
191
- load_variables_folder("base")
192
- load_variables_folder(Lono.env)
193
- end
194
-
195
- # Load the variables defined in config/variables/* to make available the params/*.txt files
196
- #
197
- # Example:
198
- #
199
- # `config/variables/base/variables.rb`:
200
- # @ami = 123
201
- #
202
- # `params/ecs/private.txt`:
203
- # AmiId=<%= @ami %>
204
- #
205
- def load_variables_folder(folder)
206
- paths = Dir.glob("#{Lono.root}/config/variables/#{folder}/**/*")
207
- paths.select{ |e| File.file? e }.each do |path|
208
- instance_eval(IO.read(path))
209
- end
210
- end
211
159
  end