molder 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d2480986a1941cf8389155f51644915554997ce09b92437f3eb24c1b4bd6fbe9
4
- data.tar.gz: 3001d82af80718bc6f4db8ade5bef766e27d199f16fac8136d7a30a5924a036e
3
+ metadata.gz: 416984ac32edc7ff37f6d1e6af4452d6e76c06a067ef47d224f06d98e77e4f7b
4
+ data.tar.gz: 12793070ad5336d858f8ebe2059088c382f83419e5dfd49ee6378df7c0cc2770
5
5
  SHA512:
6
- metadata.gz: f94f91528b905aea08c623e7a50fa575304f6dfbd9ef8d8c8c821252ee1e3c7919237eff400c3398f0d78d868a7034524a6b63ec55d8eafc04cd487656ef3cb5
7
- data.tar.gz: 13f261c86a9ea2892d26790ef2b5bf17d76b4235d05e22e909df334f599821cfa777fad1079a78fc71ab6f3f868552c90399fbe807db13a353d33349b930fa4f
6
+ metadata.gz: ed68c853eb5586055bea4674204af94018d6e0e4816d63fbd924a90cce11cb5b2899ea451397e6557b1a099ceaa2218d3c3519c6f3a026fca3619f8246cad57b
7
+ data.tar.gz: c77e6d30a6e960ace71885e7e804b8c0924cafae972d30fbd54844e4c3f1afe4ddba1a569efa10a6c25bce8442219cdc6804364df2a899937fc344cfea8cbf67
@@ -1,26 +1,27 @@
1
1
  language: ruby
2
- env:
3
- global:
4
- - CODECLIMATE_REPO_TOKEN=49ca8c0e2d56ab70e7eabc237692e21cc8fe43ef13ed5d411fa20bf1e8997a44
5
2
  rvm:
6
- - 2.2.9
7
- - 2.3.6
8
- - 2.4.3
9
- - 2.5.0
3
+ - 2.2.9
4
+ - 2.3.6
5
+ - 2.4.3
6
+ - 2.5.0
10
7
  cache:
11
8
  - bundler
12
9
  before_script:
13
- - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
14
- - chmod +x ./cc-test-reporter
15
- - ./cc-test-reporter before-build
10
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64
11
+ > ./cc-test-reporter
12
+ - chmod +x ./cc-test-reporter
13
+ - "./cc-test-reporter before-build"
16
14
  after_script:
17
- - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
15
+ - "./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT"
18
16
  script: bundle exec rspec
19
17
  notifications:
20
18
  slack:
21
- rooms:
19
+ rooms:
22
20
  email:
23
21
  recipients:
24
- - kigster@gmail.com
22
+ - kigster@gmail.com
25
23
  on_success: change
26
24
  on_failure: always
25
+ env:
26
+ global:
27
+ secure: ojmeEPTv11JMBQcHdPq96qEVk+TTmuJp+HeTIrhCUwNuTXMIUUhTXyhKWCuzNN2J7YxzkyzxKx5cWGd0ydBCv6F91dEmyiaLmtBGsRp+aF30bmPWeiu8srvUVU7RfP9AOzJPrgruFoSfJOKUvwERgs3gUZRwNMBlWIK18hY7jZRLziVFrqf9QAIhC/DMqjjwq/ko9VCj+Lf3YgW88fk83TobXGLXtaoLoj5h9Vo2AYHCd9P4bq5vr1HirUOG9j3+CVI0fUprvifK8nrxYBCk6nCX7rYgkdLzYRg8BaNj8MDUSZ2eMwyNsVaY0VisC2vAg1LdvO2nsKtFzgdZ/etAP5iOuS+Lc/IhrYKdM9bgXB2eb8cC68NQ+15YW2nuFdyv9F7gMEKiQIZoyU9Vw607Dk5vogBQdIajwUUQHnEHyU4rwUNZ8V5+XLDsNnm7Ky8JlTQuv1SMbForNiCTfiei5aX0ETsu+02+lgDOXy2nIUZ+tXfPzjD5IMbK+hHKE0I0wUX9R/W68wYyVZW975yvIeW9VraU+IhIQheUqqWhBx7cbMCh7bb1SJWp6ggT30tD4SMAozSVvcApARCom3olXz1orL29A7DAaqa8O/J5/97uHRDWrqR2jahwD1ZAetYXyBHVj23JgL29PCYQ92yp1zwj93c4Nww4a4MTOSXTcx4=
data/README.md CHANGED
@@ -1,4 +1,7 @@
1
1
  [![Build Status](https://travis-ci.org/kigster/molder.svg?branch=master)](https://travis-ci.org/kigster/molder)
2
+ [![Maintainability](https://api.codeclimate.com/v1/badges/853bd70fd12ab4a372d5/maintainability)](https://codeclimate.com/github/kigster/molder/maintainability)
3
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/853bd70fd12ab4a372d5/test_coverage)](https://codeclimate.com/github/kigster/molder/test_coverage)
4
+ [![Version](https://badge.fury.io/rb/molder.svg)](https://rubygems.org/gems/molder)
2
5
 
3
6
  # Molder
4
7
 
@@ -169,6 +172,8 @@ Let's understand this command:
169
172
  * next we pass `-a environment=production` — notice that our provision command defined in the template uses `{{ environment }}` token, even though no such attribute is defined in any of the templates. if we do not supply this argument, the value of environment in the command line would be blank.
170
173
 
171
174
  * Note that you can pass multiple attributes, separated by a slash, like so: `-a environment=production/flavor=c5.4xlarge`
175
+
176
+ * You can also pass multiple attributes by using `-a/--attrs` more than once, eg. `-a key1=value1 -a key2=value2 ....`
172
177
 
173
178
  * The final argument is the template file. The default location is `config/molder.yml` — so if you place the file in that folder you don't need to pass `-c` argument.
174
179
 
@@ -24,22 +24,34 @@ module Molder
24
24
  colors = %i(yellow blue red green magenta cyan white)
25
25
 
26
26
  FileUtils.mkdir_p(log_dir)
27
- puts "Executing #{commands.size} commands using a pool of up to #{options.max_processes} processes:\n".bold.cyan.underlined
28
- ::Parallel.each((1..commands.size),
29
- :in_processes => options.max_processes) do |i|
30
-
31
- color = colors[(i - 1) % colors.size]
32
- cmd = commands[i - 1]
27
+ if options.dry_run
28
+ puts "\nDry-run print of #{commands.size} commands:\n".bold.cyan.underlined
29
+ commands.count.times do |i|
30
+ color = colors[i % colors.size]
31
+ cmd = commands[i ]
32
+ puts "#{cmd}\n".send(color).send(:bold)
33
+ end
34
+ else
35
+ puts "Executing #{commands.size} commands using a pool of up to #{options.max_processes} processes:\n".bold.cyan.underlined
36
+ ::Parallel.each((1..commands.size),
37
+ :in_processes => options.max_processes) do |i|
33
38
 
34
- printf('%s', "Worker: #{Parallel.worker_number}, command #{i}\n".send(color)) if options.verbose
35
- puts "#{cmd}\n".send(color)
39
+ color = colors[(i - 1) % colors.size]
40
+ cmd = commands[i - 1]
41
+ printf('%s', "Worker: #{Parallel.worker_number}, command #{i}\n".send(color)) if options.verbose
42
+ puts "#{cmd}\n".send(color)
36
43
 
37
- system %Q(( #{cmd} ) > #{log_dir}/#{command_name}.#{i}.log) unless options.dry_run
44
+ system %Q(( #{cmd} ) > #{log_dir}/#{command_name}.#{i}.log)
45
+ end
38
46
  end
39
47
  end
40
48
 
41
49
  private
42
50
 
51
+ def puts(*args)
52
+ ::Molder::CLI.instance.stdout.puts(*args)
53
+ end
54
+
43
55
  def resolve_templates!
44
56
  self.templates ||= []
45
57
  options.names.each_pair do |name, indexes|
@@ -7,6 +7,11 @@ require 'etc'
7
7
  module Molder
8
8
  class CLI
9
9
  attr_accessor :argv, :original_argv, :options, :config, :command
10
+ attr_reader :stdout, :stdin, :stderr, :kernel
11
+
12
+ class << self
13
+ attr_accessor :instance
14
+ end
10
15
 
11
16
  def initialize(argv, stdin = STDIN, stdout = STDOUT, stderr = STDERR, kernel = Kernel)
12
17
  @argv, @stdin, @stdout, @stderr, @kernel = argv, stdin, stdout, stderr, kernel
@@ -15,41 +20,27 @@ module Molder
15
20
  self.options[:max_processes] = Etc.nprocessors - 2
16
21
  self.argv = argv.dup
17
22
  self.original_argv = argv.dup
23
+ self.class.instance = self
24
+ end
25
+
26
+ def execute!
18
27
 
19
28
  self.argv << '-h' if argv.empty?
20
29
 
21
30
  parser.parse!(self.argv)
22
- exit(0) if options.help
23
-
24
- pre_parse!
25
31
 
26
- if options.indexes
27
- override = {}
28
- options.names.each_pair do |name, values|
29
- if values.nil?
30
- override[name] = option.indexes
31
- end
32
- end
33
- options.names.merge!(override)
32
+ if options.help
33
+ @kernel.exit(0)
34
+ return
34
35
  end
35
36
 
36
- self.config = if options.config
37
- if File.exist?(options.config)
38
- Configuration.load(options.config)
39
- else
40
- report_error(message: "file #{options.config} does not exist.")
41
- end
42
- else
43
- Configuration.default
44
- end
45
- end
46
-
47
- def execute!
48
37
  exit_code = begin
49
38
  $stderr = @stderr
50
39
  $stdin = @stdin
51
40
  $stdout = @stdout
52
41
 
42
+ parse_args!
43
+
53
44
  App.new(config: config, options: options, command_name: command).execute!
54
45
 
55
46
  0
@@ -68,6 +59,30 @@ module Molder
68
59
 
69
60
  private
70
61
 
62
+ def parse_args!
63
+ pre_parse!
64
+
65
+ if options.indexes
66
+ override = {}
67
+ options.names.each_pair do |name, values|
68
+ if values.nil?
69
+ override[name] = option.indexes
70
+ end
71
+ end
72
+ options.names.merge!(override)
73
+ end
74
+
75
+ self.config = if options.config
76
+ if File.exist?(options.config)
77
+ Configuration.load(options.config)
78
+ else
79
+ report_error(message: "file #{options.config} does not exist.")
80
+ end
81
+ else
82
+ Configuration.default
83
+ end
84
+ end
85
+
71
86
  def pre_parse!
72
87
  if argv[0] && !argv[0].start_with?('-')
73
88
  self.command = argv.shift
@@ -84,10 +99,10 @@ module Molder
84
99
  opts.separator 'OPTIONS:'.bold.yellow
85
100
 
86
101
  opts.on('-c', '--config [file]',
87
- 'Main YAML configuration file') { |config| options[:config] = config }
102
+ 'Main YAML configuration file', ' ') { |config| options[:config] = config }
88
103
 
89
104
  opts.on('-t', '--template [n1/n2/..]',
90
- 'Names of the templates to use') do |value|
105
+ 'Names of the templates to use', ' ') do |value|
91
106
  options[:names] ||= Hashie::Mash.new
92
107
  value.split('/').each { |arg| parse_templates(arg) }
93
108
  end
@@ -95,25 +110,30 @@ module Molder
95
110
  opts.on('-i', '--index [range/array]',
96
111
  'Numbers to use in generating commands',
97
112
  'Can be a comma-separated list of values,',
98
- 'or a range, eg "1..5"') do |value|
113
+ 'or a range, eg "1..5"', ' ') do |value|
99
114
  options[:indexes] = index_expression_to_array(value)
100
115
  end
101
116
 
102
117
  opts.on('-a', '--attrs [k1=v1/k2=v2/...]',
103
- 'Provide additional attributes, or override existing ones') do |value|
118
+ 'Provide additional attributes, or ',
119
+ 'override existing ones. Can be used ',
120
+ 'more than once on a command line', ' ') do |value|
104
121
  h = {}
105
122
  value.split('/').each do |pair|
106
123
  key, value = pair.split('=')
107
124
  h[key] = value
108
125
  end
109
- options[:override] = h
126
+ options[:override] ||= {}
127
+ options[:override].merge!(h)
110
128
  end
111
129
 
112
130
  opts.on('-m', '--max-processes [number]',
113
- 'Do not start more than this many processes at once') { |value| options[:max_processes] = value.to_i }
131
+ 'Limit number of concurrent running processes',
132
+ 'The default is the number of CPU cores', ' '
133
+ ) { |value| options[:max_processes] = value.to_i }
114
134
 
115
135
  opts.on('-l', '--log-dir [dir]',
116
- 'Directory where STDOUT of running commands is saved') { |value| options[:log_dir] = value }
136
+ 'Folder where STDOUT of the commands is saved') { |value| options[:log_dir] = value }
117
137
 
118
138
  opts.on('-n', '--dry-run',
119
139
  'Don\'t actually run commands, just print them') { |_value| options[:dry_run] = true }
@@ -132,17 +152,21 @@ module Molder
132
152
 
133
153
  end.tap do |p|
134
154
  p.banner = <<-eof
155
+
135
156
  #{'DESCRIPTION'.bold.yellow}
136
- Molder is a template based command generator and runner for cases where you need to
137
- generate many similar and yet somewhat different commands, defined in the
138
- YAML template. Please read #{'https://github.com/kigster/molder'.bold.blue.underlined} for
139
- a detailed explanation of the config file structure.
157
+ Molder is a template-based command generator and runner for cases where
158
+ you need to generate many similar and yet somewhat different commands,
159
+ defined in the YAML template. Please visit #{'https://github.com/kigster/molder'.bold.blue.underlined}
160
+ for a detailed explanation of the config file structure.
140
161
 
141
- Note that the default configuration file is #{Molder::Configuration::DEFAULT_CONFIG.bold.green}.
162
+ Note, that the default config is #{Molder::Configuration::DEFAULT_CONFIG.bold.green}.
142
163
 
143
164
  #{'USAGE'.bold.yellow}
144
- #{'molder [-c config.yml] command template1[n1..n2]/template2[n1,n2,..]/... [options]'.bold.blue}
145
- #{'molder [-c config.yml] command -t template -i index [options]'.blue.bold}
165
+ #{'# shorthand usage - combine multiple templates with a slash:'.bold.black}
166
+ #{'molder [-c config.yml] command template1[n1..n2]/... [options]'.bold.blue}
167
+
168
+ #{'# alternatively, use -t and -i CLI options:'.bold.black}
169
+ #{'molder [-c config.yml] command -t template -i index [options]'.blue.bold}
146
170
 
147
171
  #{'EXAMPLES'.bold.yellow}
148
172
  #{'# The following commands assume YAML file is in the default location:'.bold.black}
@@ -151,6 +175,10 @@ module Molder
151
175
  #{'# -n flag means dry run — so instead of running commands, just print them:'.bold.black}
152
176
  #{'molder provision web[1..4]/job[1..4] -n'.bold.blue}
153
177
 
178
+ #{'# Here we supply (or override) attributes "environment" and "flavor":'.bold.black}
179
+ #{'molder provision web[1..4]/job[1..4] -n -a environment=production \
180
+ -a flavor=c5.8xlarge'.bold.blue}
181
+
154
182
  eof
155
183
  end
156
184
  end
@@ -1,7 +1,19 @@
1
1
  module Molder
2
- VERSION = '0.1.4'.freeze
2
+ VERSION = '0.2.0'.freeze
3
3
  DESCRIPTION = <<-eof
4
- Molder is a command line tool for generating and running (in parallel, across a configurable number of processes) a set of related but similar commands that are generated based on a merge of a template with a set of attributes. A key use-case is auto-generation of the host provisioning commands for an arbitrary cloud environment. The gem is not constrained to any particular cloud tool or even a command, and can be used to generate a consistent set of commands based on several customizable dimensions. For example, you could generate 600 provisioning commands for hosts in EC2, numbered from 1 to 100, constrained to the dimensions "zone-id" (values: ["a", "b", "c"]) and the data center "dc" (values: ['us-west2', 'us-east1' ]).
4
+ Molder is a handy command line tool for generating and running (in parallel,
5
+ using a pool of processes with a configurable size) a set of related and yet
6
+ different commands. A YAML file defines both the attributes and the command
7
+ template, and Molder then merges the two with CLI arguments to give you a
8
+ consistent set of commands for, eg. provisioning thousands of virtual hosts
9
+ in a cloud. The gem is not limnited to any particular cloud, tool, or a
10
+ command, and can be used across various domains to generate a consistent set
11
+ of commands based on the YAML-supplied attributes and templates, that might
12
+ vary across custom dimensions. For example, you could generate 600 provisioning
13
+ commands for hosts in EC2, numbered from 1 to 100, but constrained to the
14
+ zones "a", "b", "c", and data centers "dc" (values: ['us-west2', 'us-east1' ]).
15
+ Behind the scenes Molder uses another Ruby gem Parallel — for actually running
16
+ the provisioning commands.
5
17
  eof
6
18
  .gsub(/\s{2,}/, ' ')
7
19
  end
@@ -32,4 +32,5 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency 'yard'
33
33
  spec.add_development_dependency 'rspec', '~> 3'
34
34
  spec.add_development_dependency 'rspec-its'
35
+ spec.add_development_dependency 'aruba'
35
36
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: molder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Konstantin Gredeskoul
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-04-02 00:00:00.000000000 Z
11
+ date: 2018-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: liquid
@@ -164,17 +164,27 @@ dependencies:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
- description: 'Molder is a command line tool for generating and running (in parallel,
168
- across a configurable number of processes) a set of related but similar commands
169
- that are generated based on a merge of a template with a set of attributes. A key
170
- use-case is auto-generation of the host provisioning commands for an arbitrary cloud
171
- environment. The gem is not constrained to any particular cloud tool or even a command,
172
- and can be used to generate a consistent set of commands based on several customizable
173
- dimensions. For example, you could generate 600 provisioning commands for hosts
174
- in EC2, numbered from 1 to 100, constrained to the dimensions "zone-id" (values:
175
- ["a", "b", "c"]) and the data center "dc" (values: [''us-west2'', ''us-east1'' ]).
176
-
177
- '
167
+ - !ruby/object:Gem::Dependency
168
+ name: aruba
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ description: |2
182
+ Molder is a handy command line tool for generating and running (in parallel, using a pool of processes with a configurable size) a set of related and yet
183
+ different commands. A YAML file defines both the attributes and the command
184
+ template, and Molder then merges the two with CLI arguments to give you a
185
+ consistent set of commands for, eg. provisioning thousands of virtual hosts in a cloud. The gem is not limnited to any particular cloud, tool, or a command, and can be used across various domains to generate a consistent set of commands based on the YAML-supplied attributes and templates, that might
186
+ vary across custom dimensions. For example, you could generate 600 provisioning commands for hosts in EC2, numbered from 1 to 100, but constrained to the zones "a", "b", "c", and data centers "dc" (values: ['us-west2', 'us-east1' ]). Behind the scenes Molder uses another Ruby gem Parallel — for actually running
187
+ the provisioning commands.
178
188
  email:
179
189
  - kigster@gmail.com
180
190
  executables:
@@ -228,13 +238,16 @@ rubyforge_project:
228
238
  rubygems_version: 2.7.6
229
239
  signing_key:
230
240
  specification_version: 4
231
- summary: 'Molder is a command line tool for generating and running (in parallel, across
232
- a configurable number of processes) a set of related but similar commands that are
233
- generated based on a merge of a template with a set of attributes. A key use-case
234
- is auto-generation of the host provisioning commands for an arbitrary cloud environment.
235
- The gem is not constrained to any particular cloud tool or even a command, and can
236
- be used to generate a consistent set of commands based on several customizable dimensions.
237
- For example, you could generate 600 provisioning commands for hosts in EC2, numbered
238
- from 1 to 100, constrained to the dimensions "zone-id" (values: ["a", "b", "c"])
239
- and the data center "dc" (values: [''us-west2'', ''us-east1'' ]).'
241
+ summary: 'Molder is a handy command line tool for generating and running (in parallel,
242
+ using a pool of processes with a configurable size) a set of related and yet different
243
+ commands. A YAML file defines both the attributes and the command template, and
244
+ Molder then merges the two with CLI arguments to give you a consistent set of commands
245
+ for, eg. provisioning thousands of virtual hosts in a cloud. The gem is not limnited
246
+ to any particular cloud, tool, or a command, and can be used across various domains
247
+ to generate a consistent set of commands based on the YAML-supplied attributes and
248
+ templates, that might vary across custom dimensions. For example, you could generate
249
+ 600 provisioning commands for hosts in EC2, numbered from 1 to 100, but constrained
250
+ to the zones "a", "b", "c", and data centers "dc" (values: [''us-west2'', ''us-east1''
251
+ ]). Behind the scenes Molder uses another Ruby gem Parallel — for actually running
252
+ the provisioning commands.'
240
253
  test_files: []