lono 0.5.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/CHANGELOG.md +5 -0
- data/README.md +152 -23
- data/lib/lono.rb +1 -0
- data/lib/lono/cli.rb +3 -2
- data/lib/lono/dsl.rb +59 -12
- data/lib/lono/new.rb +4 -2
- data/lib/lono/template.rb +22 -9
- data/lib/lono/version.rb +1 -1
- data/lib/{starter_project → starter_project_json}/Gemfile +2 -1
- data/lib/{starter_project → starter_project_json}/Guardfile +0 -0
- data/lib/starter_project_json/config/lono.rb +20 -0
- data/lib/{starter_project → starter_project_json}/config/lono/api.rb +9 -9
- data/lib/{starter_project → starter_project_json}/templates/db.json.erb +1 -1
- data/lib/{starter_project → starter_project_json}/templates/partial/host_record.json.erb +0 -0
- data/lib/{starter_project → starter_project_json}/templates/partial/server.json.erb +0 -0
- data/lib/{starter_project → starter_project_json}/templates/user_data/app.sh.erb +1 -4
- data/lib/{starter_project → starter_project_json}/templates/user_data/db.sh.erb +0 -0
- data/lib/{starter_project → starter_project_json}/templates/user_data/db2.sh.erb +0 -0
- data/lib/{starter_project → starter_project_json}/templates/user_data/ruby_script.rb.erb +0 -0
- data/lib/{starter_project/templates/app.json.erb → starter_project_json/templates/web.json.erb} +1 -1
- data/lib/starter_project_yaml/Gemfile +4 -0
- data/lib/starter_project_yaml/Guardfile +12 -0
- data/lib/{starter_project → starter_project_yaml}/config/lono.rb +5 -5
- data/lib/starter_project_yaml/config/lono/api.rb +58 -0
- data/lib/starter_project_yaml/templates/db.yml.erb +148 -0
- data/lib/starter_project_yaml/templates/partial/host_record.yml.erb +14 -0
- data/lib/starter_project_yaml/templates/partial/server.yml.erb +59 -0
- data/lib/starter_project_yaml/templates/partial/user_data/bootstrap.sh.erb +5 -0
- data/lib/starter_project_yaml/templates/web.yml.erb +205 -0
- data/lono.gemspec +1 -1
- data/spec/lib/lono/dsl_spec.rb +184 -0
- data/spec/lib/lono/new_spec.rb +59 -0
- data/spec/lib/lono_spec.rb +6 -116
- data/spec/spec_helper.rb +1 -0
- metadata +42 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6375e08e65be7c8a3a1eec9356454c1975a40400
|
4
|
+
data.tar.gz: 753b81d7bc5b3d1b5dd6fab7ed01858db6aeb7e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1e1f22813a7e5ab6444aafc53d21fc6dfec39b71ea2992d027e832429283a196360a4e9dabbc839b9b1d7e24800c322ffb49df9627662e6687e8c543008d2c7
|
7
|
+
data.tar.gz: 05f0f728a8e87110ee5641ce3f0da27ebbcb12719e3b619eccb2dc634b9df156536ebbccc1a95581be1f300280a291c3d332f23cc4bb3a2e3abb5e387926ff5a
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.3.
|
1
|
+
2.3.3
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,11 @@
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
This project *tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
|
5
5
|
|
6
|
+
## [1.0.0]
|
7
|
+
- Yaml support added! Makes for much more clean and concise templates. The `lono new` command defaults to yaml format.
|
8
|
+
- The starter project is app centric instead of env centric. Example: blog-web-prod vs prod-blog-web.
|
9
|
+
|
10
|
+
|
6
11
|
## [0.5.2]
|
7
12
|
- Add helper encode_base64 method in case you want to base64 encode a string in the ERB template and you are using lono outside of the context of CloudFormation where you will not have access to the FN::Base64 Function.
|
8
13
|
|
data/README.md
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
[3]: https://codeclimate.com/repos/51d7f1407e00a4042c010ab4/badges/5273fe6cdb5a13e58554/gpa.png
|
13
13
|
[4]: https://codeclimate.com/repos/51d7f1407e00a4042c010ab4/feed
|
14
14
|
|
15
|
-
Lono is a CloudFormation Template
|
15
|
+
Lono is a CloudFormation Template generator. Lono generates CloudFormation templates based on ERB ruby templates.
|
16
16
|
|
17
17
|
## Usage
|
18
18
|
|
@@ -27,14 +27,14 @@ $ cd infra
|
|
27
27
|
$ lono generate
|
28
28
|
</pre>
|
29
29
|
|
30
|
-
This generates the templates
|
30
|
+
This generates the templates in the `config` and `templates` folders to the `output` folder.
|
31
31
|
|
32
32
|
The starter lono template project config files looks like [this](lib/starter_project/config/lono.rb) and [this](lib/starter_project/config/lono/api.rb). Here's a snippet from one of the config files with the template call:
|
33
33
|
|
34
34
|
```ruby
|
35
|
-
template "
|
36
|
-
|
37
|
-
source "
|
35
|
+
template "api-web-prod.yml" do
|
36
|
+
app,role,env = name.sub('.yml','').split('-')
|
37
|
+
source "web.yml.erb"
|
38
38
|
variables(
|
39
39
|
env: env,
|
40
40
|
app: app,
|
@@ -55,20 +55,122 @@ template "prod-api-app.json" do
|
|
55
55
|
end
|
56
56
|
```
|
57
57
|
|
58
|
-
The corresponding ERB template
|
58
|
+
The corresponding ERB template looks like the following. Note that some of the output has been shorten for brevity.
|
59
|
+
|
60
|
+
```yaml
|
61
|
+
<% @app,@role,@env = name.sub('.yml','').split('-') %>
|
62
|
+
---
|
63
|
+
AWSTemplateFormatVersion: '2010-09-09'
|
64
|
+
Description: <%= @app.capitalize %> Stack
|
65
|
+
Mappings:
|
66
|
+
...
|
67
|
+
Outputs:
|
68
|
+
...
|
69
|
+
Parameters:
|
70
|
+
Application:
|
71
|
+
Default: <%= @app %>
|
72
|
+
Description: Application name
|
73
|
+
Type: String
|
74
|
+
...
|
75
|
+
Resources:
|
76
|
+
CPUAlarmHigh:
|
77
|
+
Properties:
|
78
|
+
AlarmActions:
|
79
|
+
- Ref: WebServerScaleUpPolicy
|
80
|
+
AlarmDescription: Scale-up if CPU > <%= @high_threshold %>% for <%= @high_mins %>
|
81
|
+
...
|
82
|
+
<%= partial("host_record.yml.erb", domain: "mydomain.com") %>
|
83
|
+
LaunchConfig:
|
84
|
+
Properties:
|
85
|
+
BlockDeviceMappings:
|
86
|
+
- DeviceName: "/dev/sdb"
|
87
|
+
VirtualName: ephemeral0
|
88
|
+
ImageId:
|
89
|
+
...
|
90
|
+
UserData:
|
91
|
+
Fn::Base64: !Sub | # No more Fn::Join needed
|
92
|
+
#!/bin/bash -lexv
|
93
|
+
<% stack_name = "#{@env}-#{@app}-#{@role}" %>
|
94
|
+
exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
|
95
|
+
echo <%= stack_name %> > /tmp/stack_name
|
96
|
+
cat /proc/uptime | cut -f1 -d'.' > /tmp/time-to-boot
|
97
|
+
Type: AWS::AutoScaling::LaunchConfiguration
|
98
|
+
|
99
|
+
```
|
100
|
+
|
101
|
+
The output looks like this:
|
102
|
+
|
103
|
+
```yaml
|
104
|
+
---
|
105
|
+
AWSTemplateFormatVersion: '2010-09-09'
|
106
|
+
Description: Api Stack
|
107
|
+
Mappings:
|
108
|
+
...
|
109
|
+
Outputs:
|
110
|
+
...
|
111
|
+
Parameters:
|
112
|
+
Application:
|
113
|
+
Default: api
|
114
|
+
Description: Application name
|
115
|
+
Type: String
|
116
|
+
...
|
117
|
+
Resources:
|
118
|
+
CPUAlarmHigh:
|
119
|
+
Properties:
|
120
|
+
AlarmActions:
|
121
|
+
- Ref: WebServerScaleUpPolicy
|
122
|
+
AlarmDescription: Scale-up if CPU > 15% for
|
123
|
+
...
|
124
|
+
HostRecord:
|
125
|
+
Properties:
|
126
|
+
Comment: DNS name for mydomain.com
|
127
|
+
HostedZoneName: ".mydomain.net."
|
128
|
+
Name:
|
129
|
+
Fn::Join:
|
130
|
+
- ''
|
131
|
+
- - Ref: AWS::StackName
|
132
|
+
- mydomain.com
|
133
|
+
ResourceRecords:
|
134
|
+
- Fn::GetAtt:
|
135
|
+
- elb
|
136
|
+
- DNSName
|
137
|
+
TTL: '60'
|
138
|
+
Type: CNAME
|
139
|
+
Type: AWS::Route53::RecordSet
|
140
|
+
LaunchConfig:
|
141
|
+
Properties:
|
142
|
+
BlockDeviceMappings:
|
143
|
+
- DeviceName: "/dev/sdb"
|
144
|
+
VirtualName: ephemeral0
|
145
|
+
ImageId:
|
146
|
+
...
|
147
|
+
UserData:
|
148
|
+
Fn::Base64: |
|
149
|
+
#!/bin/bash -lexv
|
150
|
+
|
151
|
+
exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
|
152
|
+
echo api-web-prod > /tmp/stack_name
|
153
|
+
cat /proc/uptime | cut -f1 -d'.' > /tmp/time-to-boot
|
154
|
+
Type: AWS::AutoScaling::LaunchConfiguration
|
155
|
+
```
|
59
156
|
|
60
157
|
## Template helper methods
|
61
158
|
|
62
159
|
There are helper methods that are available in templates.
|
63
160
|
|
64
|
-
* partial - can be use to embed other files in a template. The partial should be placed in the templates/partial folder of the project. So:
|
65
|
-
* partial('
|
66
|
-
* partial('
|
161
|
+
* partial(relative_path, variables, options) - can be use to embed other files in a template. The partial view should be placed in the `templates/partial` folder of the project. So:
|
162
|
+
* partial('launch\_config.json.erb') -> `templates/partial/launch_config.json.erb`
|
163
|
+
* partial('launch\_config.json.erb', foo: "bar", hello: "world") - variables can be passed to the partial helper method are available to the partial as instance variables. So, in this case `@foo` and `@hello` will be available in the `launch_config.json.erb` partial.
|
164
|
+
* partial('user_data/bootstrap.sh.erb', {}, indent: 10) - Indent the result partial by 10 spaces. Useful for yaml format.
|
165
|
+
|
166
|
+
## user\_data helper for json format
|
167
|
+
|
168
|
+
The user\_data helper method is helpful for writting a script in bash form and having lono convert it to a json compatiable format. It is only really useful if you are using json as the CloudFormation format. If you are using yaml as the format, which is recommended, then you should simply use raw yaml.
|
67
169
|
|
68
|
-
*
|
69
|
-
*
|
70
|
-
*
|
71
|
-
*
|
170
|
+
* user\_data - can be used to include a user data script which is written in bash script form. The user data script should be placed in the `templates/user_data` folder of the project. So:
|
171
|
+
* user\_data('bootstrap.sh.erb') -> templates/user\_data/bootstrap.sh.erb
|
172
|
+
* user\_data('db.sh.erb') -> templates/user\_data/db.sh.erb
|
173
|
+
* user\_data('script1.sh.erb', foo: "bar", hello: "world") - variables can be passed to the user\_data helper method and will be available to the partial as instance variables. So, in this case `@foo` and `@hello` will be available in `script1.sh.erb`.
|
72
174
|
|
73
175
|
Here's how you would call it in the template.
|
74
176
|
|
@@ -84,9 +186,9 @@ Here's how you would call it in the template.
|
|
84
186
|
}
|
85
187
|
```
|
86
188
|
|
87
|
-
Within the
|
189
|
+
Within the user\_data script you can use helper methods that correspond to CloudFormation [Instrinic Functions](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/concept-intrinsic-functions.html). Currently, `base64`, `find_in_map`, `get_att`, `get_azs`, `join`, and `ref` are supported. Here's a short example of a user\_data script using a helper method:
|
88
190
|
|
89
|
-
If you have a templates/user_data/db.sh.erb that looks like this:
|
191
|
+
If you have a `templates/user_data/db.sh.erb` that looks like this:
|
90
192
|
|
91
193
|
```bash
|
92
194
|
#!/bin/bash -lexv
|
@@ -118,7 +220,7 @@ chown -R redis:redis /media/redis
|
|
118
220
|
/usr/local/bin/cfn-signal -e $? -r "Ready to rock" '<%= ref("WaitHandle") %>'
|
119
221
|
```
|
120
222
|
|
121
|
-
The
|
223
|
+
The user\_data helper will transform the bash script into a json array of elements for CloudFormation:
|
122
224
|
|
123
225
|
```json
|
124
226
|
[
|
@@ -174,7 +276,7 @@ The user_data helper will transform the bash script into a json array of element
|
|
174
276
|
]
|
175
277
|
```
|
176
278
|
|
177
|
-
More examples of
|
279
|
+
More examples of user\_data and instrinic function helper method usage are found in the starter [project template](https://github.com/tongueroo/lono/blob/master/lib/starter_project_json/templates/user_data/db.sh.erb)
|
178
280
|
|
179
281
|
## Converting UserData scripts
|
180
282
|
|
@@ -186,11 +288,11 @@ $ lono bash cloud_formation_template.json # shorthand
|
|
186
288
|
$ lono b https://s3.amazonaws.com/cloudformation-templates-us-east-1/LAMP_Single_Instance.template # shorthand and url
|
187
289
|
</pre>
|
188
290
|
|
189
|
-
This is useful if you want to take an existing [CloudFormation Template example](http://aws.amazon.com/cloudformation/aws-cloudformation-templates/) and quicklly change the UserData section into a bash script. The bashify command will generate a snippet that is meant to be copied and pasted into a bash script and used with
|
291
|
+
This is useful if you want to take an existing json [CloudFormation Template example](http://aws.amazon.com/cloudformation/aws-cloudformation-templates/) and quicklly change the UserData section into a bash script. The bashify command will generate a snippet that is meant to be copied and pasted into a bash script and used with user\_data helper method. The bash script should work right off the bat as lono will transform the generated CloudFormation object references to json objects, there's no need to manually change what is generated to the helper methods, though you can if you prefer the look of the helper methods.
|
190
292
|
|
191
293
|
## Breaking up config/lono.rb
|
192
294
|
|
193
|
-
If you have a lot of templates, the config/lono.rb file can get unwieldy long. You can break up the lono.rb file and put template defintions in the config/lono directory. Any file in this directory will be automatically loaded. An [example](lib/
|
295
|
+
If you have a lot of templates, the config/lono.rb file can get unwieldy long. You can break up the lono.rb file and put template defintions in the config/lono directory. Any file in this directory will be automatically loaded. An [example](lib/starter_project_yaml/config/lono/api.rb) is in the starter project.
|
194
296
|
|
195
297
|
|
196
298
|
## Generate
|
@@ -208,10 +310,37 @@ The lono init command also sets up guard-lono. Guard-lono continuously generate
|
|
208
310
|
$ guard
|
209
311
|
</pre>
|
210
312
|
|
211
|
-
##
|
313
|
+
## lono-cfn and lono-params
|
212
314
|
|
213
|
-
|
315
|
+
Running `lono generate` and building up the `aws cloudformation create-stack` command repeatedly gets old. The `lono-cfn` tool will automatically run `lono generate` and then launch the CloudFormation stack all in one command. Example usage:
|
214
316
|
|
215
|
-
|
216
|
-
|
317
|
+
```
|
318
|
+
$ lono-cfn create mystack-$(date +%Y%m%d%H%M%S) --template mystack --params mystack
|
319
|
+
$ lono-cfn create mystack-$(date +%Y%m%d%H%M%S) # shorthand if template and params file matches.
|
320
|
+
```
|
321
|
+
|
322
|
+
More info about lono-cfn here: [lono-cfn](https://github.com/tongueroo/lono-cfn) - Wrapper cfn tool to quickly create CloudFormation stacks from lono templates and params files.
|
323
|
+
|
324
|
+
The params file is formatted with a simple `key=value`, env-like file. It is cleaner to have a `params/mystack.txt` file like so:
|
325
|
+
|
326
|
+
```bash
|
327
|
+
Param1=1
|
328
|
+
Param2=2
|
329
|
+
```
|
330
|
+
|
331
|
+
Verus the rather verbose standard CloudFormation parameters json file:
|
332
|
+
|
333
|
+
```json
|
334
|
+
[
|
335
|
+
{
|
336
|
+
"ParameterKey": "Param1",
|
337
|
+
"ParameterValue": "1"
|
338
|
+
},
|
339
|
+
{
|
340
|
+
"ParameterKey": "Param2",
|
341
|
+
"ParameterValue": "2"
|
342
|
+
}
|
343
|
+
]
|
344
|
+
```
|
217
345
|
|
346
|
+
More info about lono-parmas here: [lono-params](https://github.com/tongueroo/lono-params) - Tool to generate a CloudFormation parameters json formatted file from a simplier env like file.
|
data/lib/lono.rb
CHANGED
data/lib/lono/cli.rb
CHANGED
@@ -8,6 +8,7 @@ module Lono
|
|
8
8
|
Help.new_long_desc
|
9
9
|
option :force, type: :boolean, aliases: "-f", desc: "override existing starter files"
|
10
10
|
option :quiet, type: :boolean, aliases: "-q", desc: "silence the output"
|
11
|
+
option :format, type: :string, default: "yaml", desc: "starter project template format: json or yaml"
|
11
12
|
def new(project_root)
|
12
13
|
Lono::New.new(options.clone.merge(project_root: project_root)).run
|
13
14
|
end
|
@@ -17,7 +18,7 @@ module Lono
|
|
17
18
|
option :clean, type: :boolean, aliases: "-c", desc: "remove all output files before generating"
|
18
19
|
option :project_root, default: ".", aliases: "-r", desc: "project root"
|
19
20
|
option :quiet, type: :boolean, aliases: "-q", desc: "silence the output"
|
20
|
-
option :pretty, type: :boolean, default: true, desc: "json pretty the output"
|
21
|
+
option :pretty, type: :boolean, default: true, desc: "json pretty the output. only applies with json format"
|
21
22
|
def generate
|
22
23
|
Lono::DSL.new(options.clone).run
|
23
24
|
end
|
@@ -33,5 +34,5 @@ module Lono
|
|
33
34
|
puts Lono::VERSION
|
34
35
|
end
|
35
36
|
|
36
|
-
end
|
37
|
+
end
|
37
38
|
end
|
data/lib/lono/dsl.rb
CHANGED
@@ -6,11 +6,38 @@ module Lono
|
|
6
6
|
@path = "#{@options[:project_root]}/config/lono.rb"
|
7
7
|
@templates = []
|
8
8
|
@results = {}
|
9
|
+
@detected_format = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def run(options={})
|
13
|
+
evaluate
|
14
|
+
build
|
15
|
+
output
|
9
16
|
end
|
10
17
|
|
11
18
|
def evaluate
|
12
19
|
instance_eval(File.read(@path), @path)
|
13
20
|
load_subfolder
|
21
|
+
@detected_format = detect_format
|
22
|
+
end
|
23
|
+
|
24
|
+
# Detects the format of the templates. Simply checks the extension of all the
|
25
|
+
# templates files.
|
26
|
+
# All the templates must be of the same format, either all json or all yaml.
|
27
|
+
def detect_format
|
28
|
+
# @templates contains Array of Hashes. Example:
|
29
|
+
# [{name: ""blog-web-prod.json", block: ...},
|
30
|
+
# {name: ""api-web-prod.json", block: ...}]
|
31
|
+
formats = @templates.map{ |t| File.extname(t[:name]) }.uniq
|
32
|
+
if formats.size > 1
|
33
|
+
puts "ERROR: Detected multiple formats: #{formats.join(", ")}".colorize(:red)
|
34
|
+
puts "All the source values in the template blocks in the config folder must have the same format extension."
|
35
|
+
exit 1
|
36
|
+
else
|
37
|
+
detected_format = formats.first.sub(/^\./,'')
|
38
|
+
detected_format = "yaml" if detected_format == "yml"
|
39
|
+
end
|
40
|
+
detected_format
|
14
41
|
end
|
15
42
|
|
16
43
|
# load any templates defined in project/config/lono/*
|
@@ -35,40 +62,60 @@ module Lono
|
|
35
62
|
FileUtils.rm_rf(output_path) if @options[:clean]
|
36
63
|
FileUtils.mkdir(output_path) unless File.exist?(output_path)
|
37
64
|
puts "Generating CloudFormation templates:" unless @options[:quiet]
|
38
|
-
@results.each do |name,
|
65
|
+
@results.each do |name,text|
|
39
66
|
path = "#{output_path}/#{name}"
|
40
67
|
puts " #{path}" unless @options[:quiet]
|
41
68
|
ensure_parent_dir(path)
|
42
|
-
validate(
|
69
|
+
validate(text, path)
|
43
70
|
File.open(path, 'w') do |f|
|
44
|
-
f.write(
|
71
|
+
f.write(output_format(text))
|
45
72
|
end
|
46
73
|
end
|
47
74
|
end
|
48
75
|
|
49
|
-
|
76
|
+
# TODO: set @detected_format upon DSL.new
|
77
|
+
def validate(text, path)
|
78
|
+
if @detected_format == "json"
|
79
|
+
validate_json(text, path)
|
80
|
+
else
|
81
|
+
validate_yaml(text, path)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def validate_yaml(yaml, path)
|
86
|
+
begin
|
87
|
+
YAML.load(yaml)
|
88
|
+
rescue Psych::SyntaxError => e
|
89
|
+
puts "Invalid yaml. Output written to #{path} for debugging".colorize(:red)
|
90
|
+
puts "ERROR: #{e.message}".colorize(:red)
|
91
|
+
File.open(path, 'w') {|f| f.write(yaml) }
|
92
|
+
exit 1
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def validate_json(json, path)
|
50
97
|
begin
|
51
98
|
JSON.parse(json)
|
52
99
|
rescue JSON::ParserError => e
|
53
100
|
puts "Invalid json. Output written to #{path} for debugging".colorize(:red)
|
101
|
+
puts "ERROR: #{e.message}".colorize(:red)
|
54
102
|
File.open(path, 'w') {|f| f.write(json) }
|
55
103
|
exit 1
|
56
104
|
end
|
57
105
|
end
|
58
106
|
|
59
|
-
def
|
60
|
-
@options[:pretty] ?
|
107
|
+
def output_format(text)
|
108
|
+
@options[:pretty] ? prettify(text) : text
|
109
|
+
end
|
110
|
+
|
111
|
+
# do not prettify yaml format because it removes the !Ref like CloudFormation notation
|
112
|
+
def prettify(text)
|
113
|
+
@detected_format == "json" ? JSON.pretty_generate(JSON.parse(text)) : text
|
61
114
|
end
|
62
115
|
|
63
116
|
def ensure_parent_dir(path)
|
64
117
|
dir = File.dirname(path)
|
65
118
|
FileUtils.mkdir_p(dir) unless File.exist?(dir)
|
66
119
|
end
|
67
|
-
|
68
|
-
def run(options={})
|
69
|
-
evaluate
|
70
|
-
build
|
71
|
-
output
|
72
|
-
end
|
73
120
|
end
|
74
121
|
end
|
data/lib/lono/new.rb
CHANGED
@@ -4,15 +4,17 @@ module Lono
|
|
4
4
|
def initialize(options)
|
5
5
|
@options = options
|
6
6
|
@project_root = options[:project_root] || '.'
|
7
|
+
@format = options[:format] || 'json'
|
7
8
|
end
|
8
9
|
|
9
10
|
def run
|
10
11
|
puts "Setting up lono project" unless options[:quiet]
|
11
|
-
source_root = File.expand_path("../../
|
12
|
+
source_root = File.expand_path("../../starter_project_#{@format}", __FILE__)
|
12
13
|
paths = Dir.glob("#{source_root}/**/*").
|
13
14
|
select {|p| File.file?(p) }
|
14
15
|
paths.each do |src|
|
15
|
-
|
16
|
+
regexp = Regexp.new(".*starter_project_#{@format}/")
|
17
|
+
dest = src.gsub(regexp,'')
|
16
18
|
dest = "#{@project_root}/#{dest}"
|
17
19
|
|
18
20
|
if File.exist?(dest) and !options[:force]
|
data/lib/lono/template.rb
CHANGED
@@ -16,7 +16,7 @@ module Lono
|
|
16
16
|
def build
|
17
17
|
instance_eval(&@block)
|
18
18
|
template = IO.read(@source)
|
19
|
-
|
19
|
+
erb_result(template)
|
20
20
|
end
|
21
21
|
|
22
22
|
def source(path)
|
@@ -29,18 +29,31 @@ module Lono
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def partial(path,vars={})
|
32
|
+
def partial(path,vars={}, options={})
|
33
33
|
path = "#{@options[:project_root]}/templates/partial/#{path}"
|
34
34
|
template = IO.read(path)
|
35
35
|
variables(vars)
|
36
|
-
|
36
|
+
result = erb_result(template)
|
37
|
+
result = indent(result, options[:indent]) if options[:indent]
|
38
|
+
result
|
39
|
+
end
|
40
|
+
|
41
|
+
# add indentation
|
42
|
+
def indent(result, indentation_amount)
|
43
|
+
result.split("\n").map do |line|
|
44
|
+
" " * indentation_amount + line
|
45
|
+
end.join("\n")
|
46
|
+
end
|
47
|
+
|
48
|
+
def erb_result(template)
|
49
|
+
ERB.new(template, nil, "-").result(binding)
|
37
50
|
end
|
38
51
|
|
39
52
|
def user_data(path, vars={})
|
40
53
|
path = "#{@options[:project_root]}/templates/user_data/#{path}"
|
41
54
|
template = IO.read(path)
|
42
55
|
variables(vars)
|
43
|
-
result =
|
56
|
+
result = erb_result(template)
|
44
57
|
output = []
|
45
58
|
result.split("\n").each do |line|
|
46
59
|
output += transform(line)
|
@@ -87,7 +100,7 @@ module Lono
|
|
87
100
|
def transform(data)
|
88
101
|
data = evaluate(data)
|
89
102
|
if data[-1].is_a?(String)
|
90
|
-
data[0..-2] + ["#{data[-1]}\n"]
|
103
|
+
data[0..-2] + ["#{data[-1]}\n"]
|
91
104
|
else
|
92
105
|
data + ["\n"]
|
93
106
|
end
|
@@ -98,7 +111,7 @@ module Lono
|
|
98
111
|
# Output:
|
99
112
|
# Array of parse positions
|
100
113
|
#
|
101
|
-
# The positions of tokens taking into account when brackets start and close,
|
114
|
+
# The positions of tokens taking into account when brackets start and close,
|
102
115
|
# handles nested brackets.
|
103
116
|
def bracket_positions(line)
|
104
117
|
positions,pair,count = [],[],0
|
@@ -106,7 +119,7 @@ module Lono
|
|
106
119
|
line.split('').each_with_index do |char,i|
|
107
120
|
pair << i if pair.empty?
|
108
121
|
|
109
|
-
first_pair_char = line[pair[0]]
|
122
|
+
first_pair_char = line[pair[0]]
|
110
123
|
if first_pair_char == '{' # object logic
|
111
124
|
if char == '{'
|
112
125
|
count += 1
|
@@ -203,8 +216,8 @@ module Lono
|
|
203
216
|
recompose(decompose(line))
|
204
217
|
end
|
205
218
|
|
206
|
-
# For simple just parameters files that can also be generated with lono, the CFN
|
207
|
-
# Fn::Base64 function is not available and as lono is not being used in the context
|
219
|
+
# For simple just parameters files that can also be generated with lono, the CFN
|
220
|
+
# Fn::Base64 function is not available and as lono is not being used in the context
|
208
221
|
# of CloudFormation. So this can be used in it's place.
|
209
222
|
def encode_base64(text)
|
210
223
|
Base64.strict_encode64(text).strip
|