configgin 0.12.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.overcommit.yml +8 -0
- data/.rspec +3 -0
- data/.rubocop.yml +4 -0
- data/.rubocop_todo.yml +48 -0
- data/.ruby-version +1 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +58 -0
- data/LICENSE.md +7 -0
- data/Makefile +19 -0
- data/NOTICE +13 -0
- data/README.md +74 -0
- data/bin/configgin +36 -0
- data/bin/setup +6 -0
- data/configgin.gemspec +29 -0
- data/lib/cli.rb +38 -0
- data/lib/configgin.rb +3 -0
- data/lib/configgin/version.rb +5 -0
- data/lib/environment_config_transmogrifier.rb +132 -0
- data/lib/exceptions.rb +4 -0
- data/lib/generate.rb +48 -0
- data/make/include/darwin-support +26 -0
- data/make/include/versioning +20 -0
- data/make/lint +9 -0
- data/make/test +9 -0
- data/vendor/github.com/hpe-cloud-garage/git-notary/.gitignore +2 -0
- data/vendor/github.com/hpe-cloud-garage/git-notary/LICENSE.txt +21 -0
- data/vendor/github.com/hpe-cloud-garage/git-notary/README.org +140 -0
- data/vendor/github.com/hpe-cloud-garage/git-notary/bin/git-notary +262 -0
- data/vendor/github.com/hpe-cloud-garage/git-notary/git-notary.gemspec +11 -0
- data/vendor/github.com/hpe-cloud-garage/git-notary/hooks/pre-push/branch-has-notes +12 -0
- data/vendor/github.com/hpe-cloud-garage/git-notary/hooks/pre-push/sync-notes +6 -0
- metadata +169 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c0d8a6a8b00f54998849502a456de5a17b83b265
|
4
|
+
data.tar.gz: 9bbe965be9848864dbff2b6e3600d83805225347
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e21878032ef6a02a5647fd9e3ccee06d32e1b6f7caa39f4498b52f13fc133e7d72de1979536134e3f94af273d96f86c0ee8e4b65aa7f6e9ac4327f15a777e7ec
|
7
|
+
data.tar.gz: fa8e769269405ecb26fdf0338535d06c9cd88b17fdb34758b5ea6f02d5b5d6d0ccf484edbe0c9b16f88f10c5e7554b8ad2ad1eacffc7455c63a5309046539617
|
data/.gitignore
ADDED
data/.overcommit.yml
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# This configuration was generated by `rubocop --auto-gen-config`
|
2
|
+
# on 2015-10-14 10:11:25 -0700 using RuboCop version 0.31.0.
|
3
|
+
# The point is for the user to remove these configuration records
|
4
|
+
# one by one as the offenses are removed from the code base.
|
5
|
+
# Note that changes in the inspected code, or installation of new
|
6
|
+
# versions of RuboCop, may require this file to be generated again.
|
7
|
+
|
8
|
+
# Offense count: 4
|
9
|
+
Metrics/AbcSize:
|
10
|
+
Max: 26
|
11
|
+
|
12
|
+
# Offense count: 2
|
13
|
+
Metrics/CyclomaticComplexity:
|
14
|
+
Max: 10
|
15
|
+
|
16
|
+
# Offense count: 20
|
17
|
+
# Configuration parameters: AllowURI, URISchemes.
|
18
|
+
Metrics/LineLength:
|
19
|
+
Max: 108
|
20
|
+
|
21
|
+
# Offense count: 7
|
22
|
+
# Configuration parameters: CountComments.
|
23
|
+
Metrics/MethodLength:
|
24
|
+
Max: 28
|
25
|
+
|
26
|
+
# Offense count: 1
|
27
|
+
Metrics/PerceivedComplexity:
|
28
|
+
Max: 11
|
29
|
+
|
30
|
+
# Offense count: 10
|
31
|
+
# Cop supports --auto-correct.
|
32
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles, ProceduralMethods, FunctionalMethods, IgnoredMethods.
|
33
|
+
Style/BlockDelimiters:
|
34
|
+
Enabled: false
|
35
|
+
|
36
|
+
# Offense count: 3
|
37
|
+
Style/ClassVars:
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
# Offense count: 1
|
41
|
+
Style/EachWithObject:
|
42
|
+
Enabled: false
|
43
|
+
|
44
|
+
# Offense count: 1
|
45
|
+
# Cop supports --auto-correct.
|
46
|
+
# Configuration parameters: MaxLineLength.
|
47
|
+
Style/IfUnlessModifier:
|
48
|
+
Enabled: false
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.7
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
configgin (0.1.0)
|
5
|
+
bosh-template (~> 1.3262.24.0)
|
6
|
+
deep_merge (~> 1.0.1)
|
7
|
+
mustache (~> 1.0)
|
8
|
+
rainbow (~> 2.0, != 2.2.1)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
ast (2.3.0)
|
14
|
+
bosh-template (1.3262.24.0)
|
15
|
+
semi_semantic (~> 1.2.0)
|
16
|
+
deep_merge (1.0.1)
|
17
|
+
diff-lcs (1.3)
|
18
|
+
mustache (1.0.5)
|
19
|
+
parser (2.4.0.0)
|
20
|
+
ast (~> 2.2)
|
21
|
+
powerpack (0.1.1)
|
22
|
+
rainbow (2.1.0)
|
23
|
+
rake (10.4.2)
|
24
|
+
rspec (3.5.0)
|
25
|
+
rspec-core (~> 3.5.0)
|
26
|
+
rspec-expectations (~> 3.5.0)
|
27
|
+
rspec-mocks (~> 3.5.0)
|
28
|
+
rspec-core (3.5.4)
|
29
|
+
rspec-support (~> 3.5.0)
|
30
|
+
rspec-expectations (3.5.0)
|
31
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
32
|
+
rspec-support (~> 3.5.0)
|
33
|
+
rspec-mocks (3.5.0)
|
34
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
35
|
+
rspec-support (~> 3.5.0)
|
36
|
+
rspec-support (3.5.0)
|
37
|
+
rubocop (0.48.1)
|
38
|
+
parser (>= 2.3.3.1, < 3.0)
|
39
|
+
powerpack (~> 0.1)
|
40
|
+
rainbow (>= 1.99.1, < 3.0)
|
41
|
+
ruby-progressbar (~> 1.7)
|
42
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
43
|
+
ruby-progressbar (1.8.1)
|
44
|
+
semi_semantic (1.2.0)
|
45
|
+
unicode-display_width (1.2.1)
|
46
|
+
|
47
|
+
PLATFORMS
|
48
|
+
ruby
|
49
|
+
|
50
|
+
DEPENDENCIES
|
51
|
+
bundler (~> 1.14)
|
52
|
+
configgin!
|
53
|
+
rake (~> 10.0)
|
54
|
+
rspec
|
55
|
+
rubocop
|
56
|
+
|
57
|
+
BUNDLED WITH
|
58
|
+
1.14.6
|
data/LICENSE.md
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
© Copyright 2016 Hewlett Packard Enterprise Development LP
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
|
4
|
+
|
5
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
|
7
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
data/Makefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env make
|
2
|
+
|
3
|
+
GIT_ROOT:=$(shell git rev-parse --show-toplevel)
|
4
|
+
|
5
|
+
.PHONY: lint test dist
|
6
|
+
|
7
|
+
all: lint test dist
|
8
|
+
|
9
|
+
test:
|
10
|
+
${GIT_ROOT}/make/test
|
11
|
+
|
12
|
+
lint:
|
13
|
+
${GIT_ROOT}/make/lint
|
14
|
+
|
15
|
+
dist:
|
16
|
+
gem build ${GIT_ROOT}/configgin.gemspec
|
17
|
+
|
18
|
+
clean:
|
19
|
+
rm -rf output
|
data/NOTICE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright 2016 Hewlett Packard Enterprise, Inc. All rights reserved.
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# configgin
|
2
|
+
|
3
|
+
A simple cli app in Ruby to generate configurations using [BOSH](https://bosh.io) ERB templates and
|
4
|
+
a BOSH spec, but also using configurations based on environment variables,
|
5
|
+
processed using a set of templates.
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
```
|
10
|
+
Usage: configgin [options]
|
11
|
+
-j, --jobs file Job configuration JSON
|
12
|
+
-e, --env2conf file Environment to configuration templates YAML
|
13
|
+
```
|
14
|
+
|
15
|
+
## Examples
|
16
|
+
|
17
|
+
### Example BOSH spec (bosh_spec.json)
|
18
|
+
```json
|
19
|
+
{
|
20
|
+
"job": {
|
21
|
+
"name": "mysql",
|
22
|
+
"templates": [
|
23
|
+
{
|
24
|
+
"name": "mysql"
|
25
|
+
},
|
26
|
+
{
|
27
|
+
"name": "consul_agent"
|
28
|
+
}
|
29
|
+
]
|
30
|
+
},
|
31
|
+
"networks": {
|
32
|
+
"default": {}
|
33
|
+
},
|
34
|
+
"properties": {
|
35
|
+
"acceptance_tests": {
|
36
|
+
"include_services": false,
|
37
|
+
"include_sso": false,
|
38
|
+
"nodes": 2
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
```
|
43
|
+
|
44
|
+
### Example job configuration file (job_config.json)
|
45
|
+
```json
|
46
|
+
{
|
47
|
+
"job_name": {
|
48
|
+
"base": "/tmp/bosh_spec.json",
|
49
|
+
"files": {
|
50
|
+
"/tmp/my_template.erb": "/tmp/output_file"
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
```
|
55
|
+
|
56
|
+
### Example environment variable template file (env2.conf.yml)
|
57
|
+
```yaml
|
58
|
+
---
|
59
|
+
properties.acceptance_tests.nodes: "((TEST_NODE_COUNT))"
|
60
|
+
properties.uaa.scim.users: "'((TEST_VAR))'"
|
61
|
+
```
|
62
|
+
|
63
|
+
### Example template (my_template.erb)
|
64
|
+
```erb
|
65
|
+
Hello, this is the users property: <%= p("uaa.scim.users") %>
|
66
|
+
```
|
67
|
+
|
68
|
+
### Example of using the tool
|
69
|
+
```bash
|
70
|
+
TEST_VAR=foo
|
71
|
+
configgin \
|
72
|
+
-e ~/tmp/env2.conf.yml \
|
73
|
+
-j ~/tmp/job_config.json
|
74
|
+
```
|
data/bin/configgin
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative "../lib/configgin"
|
4
|
+
|
5
|
+
options = {}
|
6
|
+
parser = Cli.make_option_parser(options)
|
7
|
+
|
8
|
+
parser.parse!(ARGV)
|
9
|
+
|
10
|
+
begin
|
11
|
+
Cli.check_opts(options)
|
12
|
+
rescue ArgMissingError => e
|
13
|
+
STDERR.puts("missing argument: #{e}")
|
14
|
+
exit(1)
|
15
|
+
end
|
16
|
+
|
17
|
+
jobs = JSON.load(File.read(options[:jobs]))
|
18
|
+
templates = YAML.load_file(options[:env2conf])
|
19
|
+
|
20
|
+
jobs.each do |job, job_config|
|
21
|
+
base_config = JSON.load(File.read(job_config['base']))
|
22
|
+
|
23
|
+
job_config['files'].each do |infile, outfile|
|
24
|
+
begin
|
25
|
+
bosh_spec = EnvironmentConfigTransmogrifier.transmogrify(base_config,
|
26
|
+
templates,
|
27
|
+
secrets: '/etc/secrets')
|
28
|
+
rescue NonHashValueOverride => e
|
29
|
+
STDERR.puts e.to_s
|
30
|
+
STDERR.puts "Error generating #{job}: #{outfile} from #{infile}"
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
|
34
|
+
Generate.generate(bosh_spec, infile, outfile)
|
35
|
+
end
|
36
|
+
end
|
data/bin/setup
ADDED
data/configgin.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'configgin/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "configgin"
|
8
|
+
spec.version = Configgin::VERSION
|
9
|
+
spec.authors = ["hpcloud"]
|
10
|
+
|
11
|
+
spec.summary = "A simple cli app in Ruby to generate configurations using BOSH ERB templates and a BOSH spec."
|
12
|
+
spec.description = "A simple cli app in Ruby to generate configurations using BOSH ERB templates and a BOSH spec, but also using configurations based on environment variables, processed using a set of templates."
|
13
|
+
spec.homepage = "https://github.com/hpcloud/configgin"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
16
|
+
f.match(%r{^(test|spec|features)/})
|
17
|
+
end
|
18
|
+
spec.bindir = "bin"
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
|
25
|
+
spec.add_dependency 'bosh-template', '~> 1.3262.24.0'
|
26
|
+
spec.add_dependency 'rainbow', '~>2.0', '!=2.2.1'
|
27
|
+
spec.add_dependency 'deep_merge', '~> 1.0.1'
|
28
|
+
spec.add_dependency 'mustache', '~> 1.0'
|
29
|
+
end
|
data/lib/cli.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'generate'
|
3
|
+
require 'exceptions'
|
4
|
+
|
5
|
+
# Cli is a helper module for dealing with command line flags
|
6
|
+
module Cli
|
7
|
+
# Check options for any errors
|
8
|
+
#
|
9
|
+
# @param options [Hash] The options to check
|
10
|
+
def self.check_opts(options)
|
11
|
+
[:jobs, :env2conf].each do |key|
|
12
|
+
if options[key].nil? || options[key].empty?
|
13
|
+
raise ArgMissingError, key.to_s
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Make an option parser bound to the hash passed in.
|
19
|
+
#
|
20
|
+
# @param options [Hash] The hash that the options will be bound to on parse!
|
21
|
+
# @return [Object] The option parser that can be used.
|
22
|
+
def self.make_option_parser(options)
|
23
|
+
OptionParser.new do |opts|
|
24
|
+
opts.banner = 'Usage: configgin [options]'
|
25
|
+
|
26
|
+
# Job definition file
|
27
|
+
opts.on('-j', '--jobs file', 'Job definitions') do |j|
|
28
|
+
options[:jobs] = j
|
29
|
+
end
|
30
|
+
|
31
|
+
# Environment to configuration templates file
|
32
|
+
opts.on('-e', '--env2conf file',
|
33
|
+
'Environment to configuration templates YAML') do |e|
|
34
|
+
options[:env2conf] = e
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/configgin.rb
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'mustache'
|
3
|
+
require 'shellwords'
|
4
|
+
|
5
|
+
# EnvironmentConfigTransmogrifier uses environment variables to generate config values
|
6
|
+
# for specific keys.
|
7
|
+
module EnvironmentConfigTransmogrifier
|
8
|
+
@@memoize_mustache = {}
|
9
|
+
|
10
|
+
# NoEscapeMustache does not escape these characters: & \ " < > '
|
11
|
+
class NoEscapeMustache < Mustache
|
12
|
+
# Disabling this cop because this is the function we need to override
|
13
|
+
# rubocop:disable MethodName
|
14
|
+
def escapeHTML(str)
|
15
|
+
str
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Processes the mustache templates and injects new keys into the configuration
|
20
|
+
#
|
21
|
+
# @return [Hash] Hash containing the updated configuration
|
22
|
+
def self.transmogrify(base_config, environment_templates, secrets: nil)
|
23
|
+
# build input hash for mustache
|
24
|
+
input_hash = ENV.to_hash
|
25
|
+
|
26
|
+
# load secrets
|
27
|
+
extendReplace(input_hash, secrets) if secrets && File.directory?(secrets)
|
28
|
+
|
29
|
+
# remove empty values
|
30
|
+
input_hash.reject! { |_, v| v.nil? || v.empty? }
|
31
|
+
|
32
|
+
# iterate through templates
|
33
|
+
environment_templates.each do |key, value|
|
34
|
+
# generate value from template
|
35
|
+
|
36
|
+
# we need to process the template at least once, even if it doesn't
|
37
|
+
# actually contain a mustache template, to get value types correctly;
|
38
|
+
# by default, all values are strings, because they come from the environment
|
39
|
+
# we need to unmarshall them using YAML.load
|
40
|
+
loop do
|
41
|
+
value = processMustacheTemplate(value, input_hash, key)
|
42
|
+
break unless value.respond_to?(:include?) && value.include?('((')
|
43
|
+
end
|
44
|
+
|
45
|
+
# inject value in huge json
|
46
|
+
inject_value(base_config, key.split('.'), value, key)
|
47
|
+
end
|
48
|
+
|
49
|
+
base_config['bootstrap'] = (base_config['index'] || 0) == 0
|
50
|
+
|
51
|
+
base_config
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.processMustacheTemplate(value, input_hash, key)
|
55
|
+
val = @@memoize_mustache.fetch(value, {})[input_hash]
|
56
|
+
return val if val
|
57
|
+
|
58
|
+
delimiter = '{{=(( ))=}}'
|
59
|
+
begin
|
60
|
+
mustache_value = NoEscapeMustache.render("#{delimiter}#{value}", input_hash)
|
61
|
+
# replace new lines with double new lines for proper new-line YAML parsing
|
62
|
+
mustache_value = mustache_value.to_s.gsub("\n", "\n\n")
|
63
|
+
@@memoize_mustache[value] ||= {}
|
64
|
+
@@memoize_mustache[value][input_hash] = YAML.load(mustache_value)
|
65
|
+
rescue => e
|
66
|
+
msg = mustacheMessageFromError(e)
|
67
|
+
raise LoadYamlFromMustacheError, "Could not load config key '#{key}': #{msg}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.mustacheMessageFromError(e)
|
72
|
+
lines = e.message.split(/\n/)
|
73
|
+
return 'No reason for failure given by mustache library' if lines.empty?
|
74
|
+
return lines.first if lines.size < 4
|
75
|
+
|
76
|
+
caret_line = lines[3]
|
77
|
+
caret_pos = caret_line.index('^')
|
78
|
+
return lines[0] + '.' unless caret_pos
|
79
|
+
|
80
|
+
delimiter = '{{=(( ))=}}'
|
81
|
+
actual_line = lines[2]
|
82
|
+
leading_junk = actual_line.lstrip.start_with?(delimiter) ? actual_line.index(delimiter) : 0
|
83
|
+
lines[0] + ": Error at or near position #{caret_pos - leading_junk} of template value."
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.extendReplace(hash, path)
|
87
|
+
# This code assumes that 'path' points to a directory of files.
|
88
|
+
# The name of each file is the key into the hash, and the contents
|
89
|
+
# of the file are the value to enter, as-is. The order of the
|
90
|
+
# files in the directory does not matter.
|
91
|
+
Dir.glob(File.join(path, '*')).each do |file|
|
92
|
+
key = File.basename(file)
|
93
|
+
value = File.read(file)
|
94
|
+
|
95
|
+
# Write the collected information to the hash. This will
|
96
|
+
# overwrite, i.e. replace an existing value for that name. This
|
97
|
+
# means that the values found in 'path' have priority over the
|
98
|
+
# values already in the 'hash'. This is what we want for
|
99
|
+
# '/etc/secrets'
|
100
|
+
hash[key.upcase.tr('-', '_')] = value
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.inject_value(hash, key_grams, value, original_key)
|
105
|
+
# if we only have 1 gram, we can set the value
|
106
|
+
if key_grams.size == 1
|
107
|
+
# If the new value is nil, and the old value was a hash, it's because
|
108
|
+
# somebody didn't provide a full default value; ignore it.
|
109
|
+
unless value.nil? && hash[key_grams[0]].is_a?(Hash)
|
110
|
+
hash[key_grams[0]] = value
|
111
|
+
end
|
112
|
+
return
|
113
|
+
end
|
114
|
+
|
115
|
+
# if there's more than one gram, keep going
|
116
|
+
|
117
|
+
# Initialize a hash if we're going deeper than what's currently available;
|
118
|
+
# sometimes we want to override when the old value is nil (i.e. no default)
|
119
|
+
# but the new value is a hash.
|
120
|
+
hash[key_grams[0]] = {} if hash[key_grams[0]].nil?
|
121
|
+
# error out if we're trying to override
|
122
|
+
# an existing value that's not a hash
|
123
|
+
unless hash[key_grams[0]].is_a?(Hash)
|
124
|
+
raise NonHashValueOverride, \
|
125
|
+
"Refusing to override non-hash value #{hash[key_grams[0]].inspect} " \
|
126
|
+
"with #{value.inspect}: '#{key_grams.join('.')}'" \
|
127
|
+
" - Complete key: '#{original_key}'"
|
128
|
+
end
|
129
|
+
# keep going deeper
|
130
|
+
inject_value(hash[key_grams[0]], key_grams.drop(1), value, original_key)
|
131
|
+
end
|
132
|
+
end
|
data/lib/exceptions.rb
ADDED
data/lib/generate.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'bosh/template/renderer'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
# Generate has methods for manipulating streams and generating configuration
|
5
|
+
# files using those streams.
|
6
|
+
module Generate
|
7
|
+
# Proces the given template using a provided spec and output filename
|
8
|
+
#
|
9
|
+
# @param bosh_spec [Hash] The input data as a hash
|
10
|
+
# @param input_file_path [String] The input filepath for the template
|
11
|
+
# @param output_file_path [String] The output filepath
|
12
|
+
def self.generate(bosh_spec, input_file_path, output_file_path, &_block)
|
13
|
+
# Make sure we're getting all the parameters we need
|
14
|
+
raise NoDataProvided if bosh_spec.nil?
|
15
|
+
raise NoInputFileProvided if input_file_path.nil?
|
16
|
+
raise NoOutputFileProvided if output_file_path.nil?
|
17
|
+
|
18
|
+
# Read the erb template
|
19
|
+
begin
|
20
|
+
perms = File.stat(input_file_path).mode
|
21
|
+
erb_template = ERB.new(File.read(input_file_path))
|
22
|
+
erb_template.filename = input_file_path
|
23
|
+
rescue Errno::ENOENT
|
24
|
+
raise "failed to read template file #{input_file_path}"
|
25
|
+
end
|
26
|
+
|
27
|
+
# Create a BOSH evaluation context
|
28
|
+
evaluation_context = Bosh::Template::EvaluationContext.new(bosh_spec)
|
29
|
+
# Process the Template
|
30
|
+
output = erb_template.result(evaluation_context.get_binding)
|
31
|
+
|
32
|
+
begin
|
33
|
+
# Open the output file
|
34
|
+
output_dir = File.dirname(output_file_path)
|
35
|
+
FileUtils.mkdir_p(output_dir)
|
36
|
+
out_file = File.open(output_file_path, 'w')
|
37
|
+
# Write results to the output file
|
38
|
+
out_file.write(output)
|
39
|
+
# Set the appropriate permissions on the output file
|
40
|
+
out_file.chmod(perms)
|
41
|
+
rescue Errno::ENOENT, Errno::EACCES => e
|
42
|
+
out_file = nil
|
43
|
+
raise "failed to open output file #{output_file_path}: #{e}"
|
44
|
+
ensure
|
45
|
+
out_file.close unless out_file.nil?
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -o errexit
|
4
|
+
|
5
|
+
if [ "$(uname)" == "Darwin" ]; then
|
6
|
+
DOCKER_RUNTIME=${DOCKER_RUNTIME:-'helioncf/hcf-pipeline-ruby-bosh'}
|
7
|
+
|
8
|
+
# We need to mount the enclosing repo in case we are just a submodule
|
9
|
+
# (still doesn't support being a nested submodule though)
|
10
|
+
ROOT=${PWD}
|
11
|
+
if [ -f .git ]; then cd ..; fi
|
12
|
+
GIT_ROOT=$(git rev-parse --show-toplevel)
|
13
|
+
cd ${ROOT}
|
14
|
+
|
15
|
+
WORK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
16
|
+
|
17
|
+
docker run \
|
18
|
+
--rm \
|
19
|
+
--volume ${GIT_ROOT}:${GIT_ROOT} \
|
20
|
+
--workdir ${WORK_DIR} \
|
21
|
+
--entrypoint bash \
|
22
|
+
${DOCKER_RUNTIME} \
|
23
|
+
-l -c "export RBENV_VERSION=2.1.7 && ${BASH_SOURCE[1]}"
|
24
|
+
|
25
|
+
exit
|
26
|
+
fi
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
test -n "${XTRACE}" && set -o xtrace
|
4
|
+
|
5
|
+
set -o errexit -o nounset
|
6
|
+
|
7
|
+
GIT_ROOT=${GIT_ROOT:-$(git rev-parse --show-toplevel)}
|
8
|
+
GIT_DESCRIBE=${GIT_DESCRIBE:-$(git describe --tags --long)}
|
9
|
+
GIT_BRANCH=${GIT_BRANCH:-$(git name-rev --name-only HEAD)}
|
10
|
+
|
11
|
+
GIT_TAG=${GIT_TAG:-$(echo ${GIT_DESCRIBE} | awk -F - '{ print $1 }' )}
|
12
|
+
GIT_COMMITS=${GIT_COMMITS:-$(echo ${GIT_DESCRIBE} | awk -F - '{ print $2 }' )}
|
13
|
+
GIT_SHA=${GIT_SHA:-$(echo ${GIT_DESCRIBE} | awk -F - '{ print $3 }' )}
|
14
|
+
|
15
|
+
ARTIFACT_NAME=${ARTIFACT_NAME:-$(basename $(git config --get remote.origin.url) .git | sed s/^hcf-//)}
|
16
|
+
ARTIFACT_VERSION=${GIT_TAG}+${GIT_COMMITS}.${GIT_SHA}
|
17
|
+
|
18
|
+
APP_VERSION=${ARTIFACT_NAME}-${ARTIFACT_VERSION}
|
19
|
+
|
20
|
+
set +o errexit +o nounset +o xtrace
|
data/make/lint
ADDED
data/make/test
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
The MIT License (MIT)
|
3
|
+
Copyright © 2016 Chris Olstrom <chris@olstrom.com>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the “Software”), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
@@ -0,0 +1,140 @@
|
|
1
|
+
#+TITLE: git-notary
|
2
|
+
#+SUBTITLE: a versioning experiment for git
|
3
|
+
#+LATEX: \pagebreak
|
4
|
+
|
5
|
+
* Overview
|
6
|
+
|
7
|
+
~git-notary~ generates canonical version tags from versioning notes.
|
8
|
+
|
9
|
+
** Why would I want this?
|
10
|
+
|
11
|
+
~git-notary~ may be helpful if you want to use Semantic Versioning in a project
|
12
|
+
with many contributors and some manner of branch-oriented workflow. Tracking
|
13
|
+
versioning information with a ~VERSION~ file seems like a great idea, but has
|
14
|
+
some quirks.
|
15
|
+
|
16
|
+
** An Example Scenario
|
17
|
+
|
18
|
+
Consider the following (simplified) scenario:
|
19
|
+
|
20
|
+
#+BEGIN_EXAMPLE
|
21
|
+
,* e44e210 - (HEAD -> develop) Merge branch 'bar' into develop
|
22
|
+
|\
|
23
|
+
| * e1793f3 - (bar) PATCH
|
24
|
+
| * f231d3b - MAJOR
|
25
|
+
| * 5c69653 - MAJOR
|
26
|
+
,* | 67543e1 - Merge branch 'foo' into develop
|
27
|
+
|\ \
|
28
|
+
| |/
|
29
|
+
|/|
|
30
|
+
| * ea81623 - (foo) MAJOR
|
31
|
+
| * 8b773db - PATCH
|
32
|
+
| * 6613b79 - MINOR
|
33
|
+
|/
|
34
|
+
,* 21c36f3 - (master) MINOR
|
35
|
+
,* 64357c2 - MINOR
|
36
|
+
,* 9ebfd7d - MINOR
|
37
|
+
,* cc5d832 - PATCH
|
38
|
+
,* ebc851f - MINOR
|
39
|
+
,* a75790f - PATCH
|
40
|
+
,* 572a9e8 - MAJOR
|
41
|
+
,* a990127 - (tag: 0.0.0) INITIAL
|
42
|
+
#+END_EXAMPLE
|
43
|
+
|
44
|
+
In this example, two branches (~foo~ and ~bar~) were created from ~master~
|
45
|
+
(~21c36f3~). Both branches know that ~1.4.0~ is the latest tag (at the time they
|
46
|
+
branched). Let's assume these branches do not conflict with each other.
|
47
|
+
|
48
|
+
With a ~VERSION~ file, a project generally chooses one of two places to update it:
|
49
|
+
|
50
|
+
- Updates occur in the branch. In this case, once either branch is merged, the
|
51
|
+
other is in conflict with it.
|
52
|
+
- Updates occur in the trunk. In this case, the trunk now contains code that did
|
53
|
+
not originate in a branch. Again, the first merged is safe, but the other is
|
54
|
+
in a conflicting state.
|
55
|
+
|
56
|
+
If ~foo~ merges first, the expected version post-merge is ~2.0.0~.
|
57
|
+
|
58
|
+
If ~bar~ merges first, the expected version is ~3.0.1~.
|
59
|
+
|
60
|
+
At ~e44e210~ (~HEAD~ of ~develop~), the final version should be ~4.0.1~, but if
|
61
|
+
the merge order were reversed, it should be ~4.0.0~. This gets worse as the
|
62
|
+
number of active branches increases.
|
63
|
+
|
64
|
+
* Assumptions
|
65
|
+
|
66
|
+
- Versioning is important.
|
67
|
+
- Versions should communicate scope of change.
|
68
|
+
- Humans can signal the scope of their own changes.
|
69
|
+
- Machines can figure out the rest.
|
70
|
+
|
71
|
+
* Installation
|
72
|
+
|
73
|
+
** Install via RubyGems
|
74
|
+
|
75
|
+
~gem install --no-wrapper git-notary~
|
76
|
+
|
77
|
+
** Manual Installation
|
78
|
+
|
79
|
+
Download the latest release of ~git-notary~ and place it somewhere in your ~$PATH~.
|
80
|
+
|
81
|
+
#+LATEX: \pagebreak
|
82
|
+
|
83
|
+
* Usage
|
84
|
+
|
85
|
+
** Add new versioning information
|
86
|
+
|
87
|
+
#+BEGIN_SRC shell
|
88
|
+
git-notary new <version> [object] [namespace]
|
89
|
+
#+END_SRC
|
90
|
+
|
91
|
+
Where <version> is one of (major, minor, patch).
|
92
|
+
|
93
|
+
** Undo a version
|
94
|
+
|
95
|
+
#+BEGIN_SRC shell
|
96
|
+
git-notary undo [object] [namespace]
|
97
|
+
#+END_SRC
|
98
|
+
|
99
|
+
** Fetch versioning notes
|
100
|
+
|
101
|
+
#+BEGIN_SRC shell
|
102
|
+
git-notary fetch [remote] [namespace]
|
103
|
+
#+END_SRC
|
104
|
+
|
105
|
+
** Fetch and merge versioning notes
|
106
|
+
|
107
|
+
#+BEGIN_SRC shell
|
108
|
+
git-notary pull [remote] [namespace] [merge-strategy]
|
109
|
+
#+END_SRC
|
110
|
+
|
111
|
+
** Push versioning notes
|
112
|
+
|
113
|
+
#+BEGIN_SRC shell
|
114
|
+
git-notary push [remote] [namespace]
|
115
|
+
#+END_SRC
|
116
|
+
|
117
|
+
** Extract Notes
|
118
|
+
|
119
|
+
#+BEGIN_SRC shell
|
120
|
+
git-notary notes [branch] [base] [namespace]
|
121
|
+
#+END_SRC
|
122
|
+
|
123
|
+
** Compute Versions from Notes
|
124
|
+
|
125
|
+
#+BEGIN_SRC shell
|
126
|
+
git-notary notes | git-notary versions [initial]
|
127
|
+
#+END_SRC
|
128
|
+
|
129
|
+
** Generate Tags from Versions
|
130
|
+
|
131
|
+
#+BEGIN_SRC shell
|
132
|
+
git-notary notes | git-notary versions | git-notary tags [--apply]
|
133
|
+
#+END_SRC
|
134
|
+
|
135
|
+
* License
|
136
|
+
|
137
|
+
~git-notary~ is available under the [[https://tldrlegal.com/license/mit-license][MIT License]]. See ~LICENSE.txt~ for the full text.
|
138
|
+
|
139
|
+
* Contributors
|
140
|
+
- [[https://colstrom.github.io/][Chris Olstrom]] | [[mailto:chris@olstrom.com][e-mail]] | [[https://twitter.com/ChrisOlstrom][Twitter]]
|
@@ -0,0 +1,262 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
GIT_NOTARY_VERSION=2.3.1
|
4
|
+
GIT_NOTARY_NAMESPACE=${GIT_NOTARY_NAMESPACE:-'versioning'}
|
5
|
+
|
6
|
+
# notes [branch] [base] [namespace]
|
7
|
+
notes() {
|
8
|
+
BRANCH=${1-'develop'}
|
9
|
+
BASE=${2:-$(git describe --tags --abbrev=0)}
|
10
|
+
NAMESPACE=${3:-${GIT_NOTARY_NAMESPACE}}
|
11
|
+
|
12
|
+
git rev-list --topo-order ${BASE}..${BRANCH} --reverse | while read OBJECT; do
|
13
|
+
printf "${OBJECT} "
|
14
|
+
git notes --ref=${NAMESPACE} show ${OBJECT} 2> /dev/null || echo
|
15
|
+
done | grep -E '(MAJOR|MINOR|PATCH)$'
|
16
|
+
}
|
17
|
+
|
18
|
+
# squash
|
19
|
+
squash() {
|
20
|
+
while read OBJECT_CHANGE; do
|
21
|
+
OBJECT=$(echo ${OBJECT_CHANGE} | awk '{ print $1 }')
|
22
|
+
CHANGE=$(echo ${OBJECT_CHANGE} | awk '{ print $2 }')
|
23
|
+
|
24
|
+
case ${CHANGE} in
|
25
|
+
MAJOR)
|
26
|
+
RESULT=MAJOR;;
|
27
|
+
MINOR)
|
28
|
+
test "${RESULT}" != MAJOR && RESULT=MINOR;;
|
29
|
+
PATCH)
|
30
|
+
test -z "${RESULT}" && RESULT=PATCH;;
|
31
|
+
esac
|
32
|
+
done
|
33
|
+
|
34
|
+
test ! -z "${RESULT}" && echo ${OBJECT} ${RESULT}
|
35
|
+
}
|
36
|
+
|
37
|
+
# squeeze <up|down>
|
38
|
+
squeeze() {
|
39
|
+
case ${1} in
|
40
|
+
d|down|f|first|o|old*)
|
41
|
+
DIRECTION=DOWN;;
|
42
|
+
u|up|l|last|n|new*)
|
43
|
+
DIRECTION=UP;;
|
44
|
+
*)
|
45
|
+
echo 'git-notary squeeze requires a direction (up or down)' >&2
|
46
|
+
exit 23;;
|
47
|
+
esac
|
48
|
+
|
49
|
+
while read OBJECT_CHANGE; do
|
50
|
+
OBJECT=$(echo ${OBJECT_CHANGE} | awk '{ print $1 }')
|
51
|
+
CHANGE=$(echo ${OBJECT_CHANGE} | awk '{ print $2 }')
|
52
|
+
|
53
|
+
if test "${CHANGE}" != "${LAST_CHANGE}"; then
|
54
|
+
case ${DIRECTION} in
|
55
|
+
DOWN)
|
56
|
+
echo ${OBJECT} ${CHANGE};;
|
57
|
+
UP)
|
58
|
+
test ! -z "${LAST_OBJECT}" && echo ${LAST_OBJECT} ${LAST_CHANGE};;
|
59
|
+
esac
|
60
|
+
fi
|
61
|
+
|
62
|
+
LAST_OBJECT=${OBJECT}
|
63
|
+
LAST_CHANGE=${CHANGE}
|
64
|
+
done
|
65
|
+
|
66
|
+
test "${DIRECTION}" = UP && echo ${LAST_OBJECT} ${LAST_CHANGE}
|
67
|
+
}
|
68
|
+
|
69
|
+
# versions [initial]
|
70
|
+
versions() {
|
71
|
+
set -o errexit
|
72
|
+
VERSION=${1:-$(git describe --tags --abbrev=0)}
|
73
|
+
|
74
|
+
MAJOR=$(echo ${VERSION} | awk -F . '{ print $1 }')
|
75
|
+
MINOR=$(echo ${VERSION} | awk -F . '{ print $2 }')
|
76
|
+
PATCH=$(echo ${VERSION} | awk -F . '{ print $3 }')
|
77
|
+
|
78
|
+
next() {
|
79
|
+
echo ${1} + 1 | bc
|
80
|
+
}
|
81
|
+
|
82
|
+
while read OBJECT_CHANGE; do
|
83
|
+
OBJECT=$(echo ${OBJECT_CHANGE} | awk '{ print $1 }')
|
84
|
+
CHANGE=$(echo ${OBJECT_CHANGE} | awk '{ print $2 }')
|
85
|
+
|
86
|
+
case ${CHANGE} in
|
87
|
+
MAJOR)
|
88
|
+
MAJOR=$(next ${MAJOR})
|
89
|
+
MINOR=0
|
90
|
+
PATCH=0
|
91
|
+
;;
|
92
|
+
MINOR)
|
93
|
+
MINOR=$(next ${MINOR})
|
94
|
+
PATCH=0
|
95
|
+
;;
|
96
|
+
PATCH)
|
97
|
+
PATCH=$(next ${PATCH})
|
98
|
+
;;
|
99
|
+
esac
|
100
|
+
|
101
|
+
VERSION=${MAJOR}.${MINOR}.${PATCH}
|
102
|
+
echo ${OBJECT} ${VERSION}
|
103
|
+
done
|
104
|
+
}
|
105
|
+
|
106
|
+
# tags [--apply]
|
107
|
+
tags() {
|
108
|
+
while read OBJECT_TAG; do
|
109
|
+
OBJECT=$(echo ${OBJECT_TAG} | awk '{ print $1 }')
|
110
|
+
TAG=$(echo ${OBJECT_TAG} | awk '{ print $2 }')
|
111
|
+
|
112
|
+
if test "${1}" = '--apply'; then
|
113
|
+
git tag ${TAG} ${OBJECT}
|
114
|
+
else
|
115
|
+
echo git tag ${TAG} ${OBJECT}
|
116
|
+
fi
|
117
|
+
done
|
118
|
+
}
|
119
|
+
|
120
|
+
# fetch [remote] [namespace]
|
121
|
+
fetch() {
|
122
|
+
FORCE=""
|
123
|
+
if test "${1:-}" = "--force"; then
|
124
|
+
shift
|
125
|
+
FORCE="+"
|
126
|
+
fi
|
127
|
+
REMOTE=${1:-'origin'}
|
128
|
+
NAMESPACE=${2:-${GIT_NOTARY_NAMESPACE}}
|
129
|
+
|
130
|
+
git fetch ${REMOTE} ${FORCE}refs/notes/${NAMESPACE}:refs/notes/${NAMESPACE}
|
131
|
+
}
|
132
|
+
|
133
|
+
# pull [remote] [namespace] [strategy]
|
134
|
+
pull() {
|
135
|
+
REMOTE=${1:-'origin'}
|
136
|
+
NAMESPACE=${2:-${GIT_NOTARY_NAMESPACE}}
|
137
|
+
STRATEGY=${3:-'theirs'}
|
138
|
+
|
139
|
+
git fetch ${REMOTE} refs/notes/${NAMESPACE}
|
140
|
+
env GIT_NOTES_REF=refs/notes/${NAMESPACE} git notes merge -s ${STRATEGY} FETCH_HEAD
|
141
|
+
}
|
142
|
+
|
143
|
+
# push [remote] [namespace]
|
144
|
+
push() {
|
145
|
+
REMOTE=${1:-'origin'}
|
146
|
+
NAMESPACE=${2:-${GIT_NOTARY_NAMESPACE}}
|
147
|
+
|
148
|
+
git push --no-verify ${REMOTE} refs/notes/${NAMESPACE}
|
149
|
+
}
|
150
|
+
|
151
|
+
# new <major|minor|patch> [object] [namespace]
|
152
|
+
new() {
|
153
|
+
CHANGE=$(echo ${1} | tr [:lower:] [:upper:])
|
154
|
+
OBJECT=${2:-HEAD}
|
155
|
+
NAMESPACE=${3:-${GIT_NOTARY_NAMESPACE}}
|
156
|
+
|
157
|
+
if echo ${CHANGE} | grep -qE '^(MAJOR|MINOR|PATCH)$'; then
|
158
|
+
git notes --ref=${NAMESPACE} add --message ${CHANGE} ${OBJECT}
|
159
|
+
else
|
160
|
+
echo MAJOR MINOR and PATCH are valid. ${CHANGE} is not.
|
161
|
+
exit 23
|
162
|
+
fi
|
163
|
+
}
|
164
|
+
|
165
|
+
# delta (--squash) [object] [base] [namespace]
|
166
|
+
delta() {
|
167
|
+
if test "${1}" = '--squash'; then
|
168
|
+
SQUASH=true
|
169
|
+
shift
|
170
|
+
fi
|
171
|
+
|
172
|
+
OBJECT=${1:-HEAD}
|
173
|
+
BASE=${2:-$(git describe --tags --abbrev=0)}
|
174
|
+
NAMESPACE=${3:-${GIT_NOTARY_NAMESPACE}}
|
175
|
+
|
176
|
+
if test "${SQUASH}" = 'true'; then
|
177
|
+
NEW=$(git-notary notes ${OBJECT} ${BASE} ${NAMESPACE} | git-notary squash | git-notary versions | awk '{ print $2 }')
|
178
|
+
else
|
179
|
+
NEW=$(git-notary notes ${OBJECT} ${BASE} ${NAMESPACE} | git-notary versions | tail -1 | awk '{ print $2 }')
|
180
|
+
fi
|
181
|
+
|
182
|
+
LATEST_TAG_ON_BASE=$(git describe --tags --abbrev=0 ${BASE})
|
183
|
+
OLD=${LATEST_TAG_ON_BASE:-'0.0.0'}
|
184
|
+
echo "${OLD} -> ${NEW}"
|
185
|
+
}
|
186
|
+
|
187
|
+
# undo [object] [namespace]
|
188
|
+
undo() {
|
189
|
+
OBJECT=${1:-HEAD}
|
190
|
+
NAMESPACE=${2:-${GIT_NOTARY_NAMESPACE}}
|
191
|
+
|
192
|
+
git notes --ref=${NAMESPACE} remove ${OBJECT}
|
193
|
+
}
|
194
|
+
|
195
|
+
# version
|
196
|
+
version() {
|
197
|
+
echo "git-notary ${GIT_NOTARY_VERSION}"
|
198
|
+
}
|
199
|
+
|
200
|
+
# help
|
201
|
+
help() {
|
202
|
+
cat <<EOF
|
203
|
+
$(version)
|
204
|
+
usage:
|
205
|
+
git-notary new <major|minor|patch> [object] [namespace]
|
206
|
+
git-notary undo [object] [namespace]
|
207
|
+
git-notary delta [--squash] [object] [base] [namespace]
|
208
|
+
|
209
|
+
git-notary fetch [remote] [namespace]
|
210
|
+
git-notary push [remote] [namespace]
|
211
|
+
|
212
|
+
git-notary notes [branch] [base] [namespace]
|
213
|
+
git-notary versions [initial]
|
214
|
+
git-notary tags [--apply]
|
215
|
+
EOF
|
216
|
+
}
|
217
|
+
|
218
|
+
# notary <command> [args]
|
219
|
+
notary() {
|
220
|
+
COMMAND=${1}
|
221
|
+
shift
|
222
|
+
case ${COMMAND} in
|
223
|
+
N|notes)
|
224
|
+
notes ${@};;
|
225
|
+
V|versions)
|
226
|
+
versions ${@};;
|
227
|
+
T|tags)
|
228
|
+
tags ${@};;
|
229
|
+
S|squash)
|
230
|
+
squash ${@};;
|
231
|
+
Z|squeeze)
|
232
|
+
squeeze ${@};;
|
233
|
+
n|new)
|
234
|
+
new ${@};;
|
235
|
+
u|undo)
|
236
|
+
undo ${@};;
|
237
|
+
d|delta)
|
238
|
+
delta ${@};;
|
239
|
+
P|push)
|
240
|
+
push ${@};;
|
241
|
+
f|fetch)
|
242
|
+
fetch ${@};;
|
243
|
+
fm|fetch-merge|pull)
|
244
|
+
pull ${@};;
|
245
|
+
M|major)
|
246
|
+
new MAJOR ${@};;
|
247
|
+
m|minor)
|
248
|
+
new MINOR ${@};;
|
249
|
+
p|patch)
|
250
|
+
new PATCH ${@};;
|
251
|
+
v|version|-v|--version)
|
252
|
+
version;;
|
253
|
+
h|help|-h|--help)
|
254
|
+
help;;
|
255
|
+
*)
|
256
|
+
help
|
257
|
+
exit 1
|
258
|
+
;;
|
259
|
+
esac
|
260
|
+
}
|
261
|
+
|
262
|
+
notary "${@:-}"
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Gem::Specification.new do |gem|
|
2
|
+
gem.name = 'git-notary'
|
3
|
+
gem.version = `git describe --tags --abbrev=0`.chomp
|
4
|
+
gem.license = 'MIT'
|
5
|
+
gem.author = 'Chris Olstrom'
|
6
|
+
gem.email = 'chris@olstrom.com'
|
7
|
+
gem.homepage = 'https://github.com/colstrom/git-notary'
|
8
|
+
gem.summary = 'generates canonical version tags from versioning notes'
|
9
|
+
gem.files = `git ls-files`.split("\n")
|
10
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,169 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: configgin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.12.0.pre
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- hpcloud
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-05-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.14'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.14'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bosh-template
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.3262.24.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.3262.24.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rainbow
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.0'
|
62
|
+
- - "!="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: 2.2.1
|
65
|
+
type: :runtime
|
66
|
+
prerelease: false
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - "~>"
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '2.0'
|
72
|
+
- - "!="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 2.2.1
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: deep_merge
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 1.0.1
|
82
|
+
type: :runtime
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 1.0.1
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: mustache
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '1.0'
|
96
|
+
type: :runtime
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '1.0'
|
103
|
+
description: A simple cli app in Ruby to generate configurations using BOSH ERB templates
|
104
|
+
and a BOSH spec, but also using configurations based on environment variables, processed
|
105
|
+
using a set of templates.
|
106
|
+
email:
|
107
|
+
executables:
|
108
|
+
- configgin
|
109
|
+
- setup
|
110
|
+
extensions: []
|
111
|
+
extra_rdoc_files: []
|
112
|
+
files:
|
113
|
+
- ".gitignore"
|
114
|
+
- ".overcommit.yml"
|
115
|
+
- ".rspec"
|
116
|
+
- ".rubocop.yml"
|
117
|
+
- ".rubocop_todo.yml"
|
118
|
+
- ".ruby-version"
|
119
|
+
- Gemfile
|
120
|
+
- Gemfile.lock
|
121
|
+
- LICENSE.md
|
122
|
+
- Makefile
|
123
|
+
- NOTICE
|
124
|
+
- README.md
|
125
|
+
- bin/configgin
|
126
|
+
- bin/setup
|
127
|
+
- configgin.gemspec
|
128
|
+
- lib/cli.rb
|
129
|
+
- lib/configgin.rb
|
130
|
+
- lib/configgin/version.rb
|
131
|
+
- lib/environment_config_transmogrifier.rb
|
132
|
+
- lib/exceptions.rb
|
133
|
+
- lib/generate.rb
|
134
|
+
- make/include/darwin-support
|
135
|
+
- make/include/versioning
|
136
|
+
- make/lint
|
137
|
+
- make/test
|
138
|
+
- vendor/github.com/hpe-cloud-garage/git-notary/.gitignore
|
139
|
+
- vendor/github.com/hpe-cloud-garage/git-notary/LICENSE.txt
|
140
|
+
- vendor/github.com/hpe-cloud-garage/git-notary/README.org
|
141
|
+
- vendor/github.com/hpe-cloud-garage/git-notary/bin/git-notary
|
142
|
+
- vendor/github.com/hpe-cloud-garage/git-notary/git-notary.gemspec
|
143
|
+
- vendor/github.com/hpe-cloud-garage/git-notary/hooks/pre-push/branch-has-notes
|
144
|
+
- vendor/github.com/hpe-cloud-garage/git-notary/hooks/pre-push/sync-notes
|
145
|
+
homepage: https://github.com/hpcloud/configgin
|
146
|
+
licenses: []
|
147
|
+
metadata: {}
|
148
|
+
post_install_message:
|
149
|
+
rdoc_options: []
|
150
|
+
require_paths:
|
151
|
+
- lib
|
152
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
154
|
+
- - ">="
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: '0'
|
157
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - ">"
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: 1.3.1
|
162
|
+
requirements: []
|
163
|
+
rubyforge_project:
|
164
|
+
rubygems_version: 2.6.10
|
165
|
+
signing_key:
|
166
|
+
specification_version: 4
|
167
|
+
summary: A simple cli app in Ruby to generate configurations using BOSH ERB templates
|
168
|
+
and a BOSH spec.
|
169
|
+
test_files: []
|