lono 3.5.0 → 4.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 (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