pups 1.0.0 → 1.1.1

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.
@@ -1,37 +1,37 @@
1
- class Pups::FileCommand < Pups::Command
2
- attr_accessor :path, :contents, :params, :type, :chmod
1
+ # frozen_string_literal: true
3
2
 
4
- def self.from_hash(hash, params)
5
- command = new
6
- command.path = hash["path"]
7
- command.contents = hash["contents"]
8
- command.chmod = hash["chmod"]
9
- command.params = params
3
+ module Pups
4
+ class FileCommand < Pups::Command
5
+ attr_accessor :path, :contents, :params, :type, :chmod, :chown
10
6
 
11
- command
12
- end
7
+ def self.from_hash(hash, params)
8
+ command = new
9
+ command.path = hash['path']
10
+ command.contents = hash['contents']
11
+ command.chmod = hash['chmod']
12
+ command.chown = hash['chown']
13
+ command.params = params
13
14
 
14
- def initialize
15
- @params = {}
16
- @type = :bash
17
- end
15
+ command
16
+ end
18
17
 
19
- def params=(p)
20
- @params = p
21
- end
18
+ def initialize
19
+ @params = {}
20
+ @type = :bash
21
+ end
22
22
 
23
- def run
24
- path = interpolate_params(@path)
23
+ attr_writer :params
25
24
 
26
- `mkdir -p #{File.dirname(path)}`
27
- File.open(path, "w") do |f|
28
- f.write(interpolate_params(contents))
29
- end
30
- if @chmod
31
- `chmod #{@chmod} #{path}`
25
+ def run
26
+ path = interpolate_params(@path)
27
+
28
+ `mkdir -p #{File.dirname(path)}`
29
+ File.open(path, 'w') do |f|
30
+ f.write(interpolate_params(contents))
31
+ end
32
+ `chmod #{@chmod} #{path}` if @chmod
33
+ `chown #{@chown} #{path}` if @chown
34
+ Pups.log.info("File > #{path} chmod: #{@chmod} chown: #{@chown}")
32
35
  end
33
- Pups.log.info("File > #{path} chmod: #{@chmod}")
34
36
  end
35
-
36
37
  end
37
-
@@ -1,48 +1,50 @@
1
- class Pups::MergeCommand < Pups::Command
2
- attr_reader :filename
3
- attr_reader :merge_hash
4
-
5
- def self.from_str(command, params)
6
- new(command,params)
7
- end
8
-
9
- def self.parse_command(command)
10
- split = command.split(" ")
11
- raise ArgumentError.new("Invalid merge command #{command}") unless split[-1][0] == "$"
12
-
13
- [split[0..-2].join(" ") , split[-1][1..-1]]
14
- end
15
-
16
- def initialize(command, params)
17
- @params = params
18
-
19
- filename, target_param = Pups::MergeCommand.parse_command(command)
20
- @filename = interpolate_params(filename)
21
- @merge_hash = params[target_param]
22
- end
23
-
24
- def run
25
- merged = self.class.deep_merge(YAML.load_file(@filename), @merge_hash)
26
- File.open(@filename,"w"){|f| f.write(merged.to_yaml) }
27
- Pups.log.info("Merge: #{@filename} with: \n#{@merge_hash.inspect}")
1
+ # frozen_string_literal: true
2
+
3
+ module Pups
4
+ class MergeCommand < Pups::Command
5
+ attr_reader :filename, :merge_hash
6
+
7
+ def self.from_str(command, params)
8
+ new(command, params)
9
+ end
10
+
11
+ def self.parse_command(command)
12
+ split = command.split(' ')
13
+ raise ArgumentError, "Invalid merge command #{command}" unless split[-1][0] == '$'
14
+
15
+ [split[0..-2].join(' '), split[-1][1..-1]]
16
+ end
17
+
18
+ def initialize(command, params)
19
+ @params = params
20
+
21
+ filename, target_param = Pups::MergeCommand.parse_command(command)
22
+ @filename = interpolate_params(filename)
23
+ @merge_hash = params[target_param]
24
+ end
25
+
26
+ def run
27
+ merged = self.class.deep_merge(YAML.load_file(@filename), @merge_hash)
28
+ File.open(@filename, 'w') { |f| f.write(merged.to_yaml) }
29
+ Pups.log.info("Merge: #{@filename} with: \n#{@merge_hash.inspect}")
30
+ end
31
+
32
+ def self.deep_merge(first, second, *args)
33
+ args ||= []
34
+ merge_arrays = args.include? :merge_arrays
35
+
36
+ merger = proc { |_key, v1, v2|
37
+ if v1.is_a?(Hash) && v2.is_a?(Hash)
38
+ v1.merge(v2, &merger)
39
+ elsif v1.is_a?(Array) && v2.is_a?(Array)
40
+ merge_arrays ? v1 + v2 : v2
41
+ elsif v2.is_a?(NilClass)
42
+ v1
43
+ else
44
+ v2
45
+ end
46
+ }
47
+ first.merge(second, &merger)
48
+ end
28
49
  end
29
-
30
- def self.deep_merge(first,second, *args)
31
- args ||= []
32
- merge_arrays = args.include? :merge_arrays
33
-
34
- merger = proc { |key, v1, v2|
35
- if Hash === v1 && Hash === v2
36
- v1.merge(v2, &merger)
37
- elsif Array === v1 && Array === v2
38
- merge_arrays ? v1 + v2 : v2
39
- elsif NilClass === v2
40
- v1
41
- else
42
- v2
43
- end
44
- }
45
- first.merge(second, &merger)
46
- end
47
-
48
50
  end
@@ -1,43 +1,45 @@
1
- class Pups::ReplaceCommand < Pups::Command
2
- attr_accessor :text, :from, :to, :filename, :direction, :global
1
+ # frozen_string_literal: true
3
2
 
4
- def self.from_hash(hash, params)
5
- replacer = new(params)
6
- replacer.from = guess_replace_type(hash["from"])
7
- replacer.to = guess_replace_type(hash["to"])
8
- replacer.text = File.read(hash["filename"])
9
- replacer.filename = hash["filename"]
10
- replacer.direction = hash["direction"].to_sym if hash["direction"]
11
- replacer.global = hash["global"].to_s == "true"
12
- replacer
13
- end
3
+ module Pups
4
+ class ReplaceCommand < Pups::Command
5
+ attr_accessor :text, :from, :to, :filename, :direction, :global
14
6
 
15
- def self.guess_replace_type(item)
16
- # evaling to get all the regex flags easily
17
- item[0] == "/" ? eval(item) : item
18
- end
7
+ def self.from_hash(hash, params)
8
+ replacer = new(params)
9
+ replacer.from = guess_replace_type(hash['from'])
10
+ replacer.to = guess_replace_type(hash['to'])
11
+ replacer.text = File.read(hash['filename'])
12
+ replacer.filename = hash['filename']
13
+ replacer.direction = hash['direction'].to_sym if hash['direction']
14
+ replacer.global = hash['global'].to_s == 'true'
15
+ replacer
16
+ end
19
17
 
20
- def initialize(params)
21
- @params = params
22
- end
18
+ def self.guess_replace_type(item)
19
+ # evaling to get all the regex flags easily
20
+ item[0] == '/' ? eval(item) : item
21
+ end
23
22
 
24
- def replaced_text
25
- new_to = to
26
- if String === to
27
- new_to = interpolate_params(to)
23
+ def initialize(params)
24
+ @params = params
28
25
  end
29
- if global
30
- text.gsub(from,new_to)
31
- elsif direction == :reverse
32
- index = text.rindex(from)
33
- text[0..index-1] << text[index..-1].sub(from,new_to)
34
- else
35
- text.sub(from,new_to)
26
+
27
+ def replaced_text
28
+ new_to = to
29
+ new_to = interpolate_params(to) if to.is_a?(String)
30
+ if global
31
+ text.gsub(from, new_to)
32
+ elsif direction == :reverse
33
+ index = text.rindex(from)
34
+ text[0..index - 1] << text[index..-1].sub(from, new_to)
35
+ else
36
+ text.sub(from, new_to)
37
+ end
36
38
  end
37
- end
38
39
 
39
- def run
40
- Pups.log.info("Replacing #{from.to_s} with #{to.to_s} in #{filename}")
41
- File.open(filename, "w"){|f| f.write replaced_text }
40
+ def run
41
+ Pups.log.info("Replacing #{from} with #{to} in #{filename}")
42
+ File.open(filename, 'w') { |f| f.write replaced_text }
43
+ end
42
44
  end
43
45
  end
data/lib/pups/runit.rb CHANGED
@@ -1,40 +1,39 @@
1
- class Pups::Runit
1
+ # frozen_string_literal: true
2
2
 
3
- attr_accessor :env, :exec, :cd, :name
3
+ module Pups
4
+ class Runit
5
+ attr_accessor :env, :exec, :cd, :name
4
6
 
7
+ def initialize(name)
8
+ @name = name
9
+ end
5
10
 
6
- def initialize(name)
7
- @name = name
8
- end
9
-
10
- def setup
11
- `mkdir -p /etc/service/#{name}`
12
- run = "/etc/service/#{name}/run"
13
- File.open(run, "w") do |f|
14
- f.write(run_script)
11
+ def setup
12
+ `mkdir -p /etc/service/#{name}`
13
+ run = "/etc/service/#{name}/run"
14
+ File.open(run, 'w') do |f|
15
+ f.write(run_script)
16
+ end
17
+ `chmod +x #{run}`
15
18
  end
16
- `chmod +x #{run}`
17
- end
18
19
 
19
- def run_script
20
- "#!/bin/bash
20
+ def run_script
21
+ "#!/bin/bash
21
22
  exec 2>&1
22
23
  #{env_script}
23
24
  #{cd_script}
24
25
  #{exec}
25
26
  "
26
- end
27
+ end
27
28
 
28
- def cd_script
29
- "cd #{@cd}" if @cd
30
- end
29
+ def cd_script
30
+ "cd #{@cd}" if @cd
31
+ end
31
32
 
32
- def env_script
33
- if @env
34
- @env.map do |k,v|
33
+ def env_script
34
+ @env&.map do |k, v|
35
35
  "export #{k}=#{v}"
36
- end.join("\n")
36
+ end&.join("\n")
37
37
  end
38
38
  end
39
-
40
39
  end
data/lib/pups/version.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Pups
2
- VERSION = "1.0.0"
4
+ VERSION = '1.1.1'
3
5
  end
data/pups.gemspec CHANGED
@@ -1,26 +1,31 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'pups/version'
5
6
 
6
7
  Gem::Specification.new do |spec|
7
- spec.name = "pups"
8
+ spec.name = 'pups'
8
9
  spec.version = Pups::VERSION
9
- spec.authors = ["Sam Saffron"]
10
- spec.email = ["sam.saffron@gmail.com"]
11
- spec.description = %q{Process orchestrator}
12
- spec.summary = %q{Process orchestrator}
13
- spec.homepage = ""
14
- spec.license = "MIT"
10
+ spec.authors = ['Sam Saffron']
11
+ spec.email = ['sam.saffron@gmail.com']
12
+ spec.description = 'Simple docker image creator'
13
+ spec.summary = 'Toolkit for orchestrating a composed docker image'
14
+ spec.homepage = ''
15
+ spec.license = 'MIT'
15
16
 
16
- spec.files = `git ls-files`.split($/)
17
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
17
18
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
20
+ spec.require_paths = ['lib']
20
21
 
21
- spec.add_development_dependency "bundler", "~> 1.3"
22
- spec.add_development_dependency "rake"
23
- spec.add_development_dependency "minitest"
24
- spec.add_development_dependency "guard"
25
- spec.add_development_dependency "guard-minitest"
22
+ spec.add_development_dependency 'bundler'
23
+ spec.add_development_dependency 'guard'
24
+ spec.add_development_dependency 'guard-minitest'
25
+ spec.add_development_dependency 'minitest'
26
+ spec.add_development_dependency 'rake'
27
+ spec.add_development_dependency 'rubocop'
28
+ spec.add_development_dependency 'rubocop-discourse'
29
+ spec.add_development_dependency 'rubocop-minitest'
30
+ spec.add_development_dependency 'rubocop-rake'
26
31
  end
data/test/cli_test.rb ADDED
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+ require 'tempfile'
5
+ require 'stringio'
6
+
7
+ module Pups
8
+ class CliTest < MiniTest::Test
9
+ def test_cli_option_parsing_stdin
10
+ options = Cli.parse_args(['--stdin'])
11
+ assert_equal(true, options[:stdin])
12
+ end
13
+
14
+ def test_cli_option_parsing_none
15
+ options = Cli.parse_args([])
16
+ assert_nil(options[:stdin])
17
+ end
18
+
19
+ def test_cli_read_config_from_file
20
+ # for testing output
21
+ f = Tempfile.new('test_output')
22
+ f.close
23
+
24
+ # for testing input
25
+ cf = Tempfile.new('test_config')
26
+ cf.puts <<~YAML
27
+ params:
28
+ run: #{f.path}
29
+ run:
30
+ - exec: echo hello world >> #{f.path}
31
+ YAML
32
+ cf.close
33
+
34
+ Cli.run([cf.path])
35
+ assert_equal('hello world', File.read(f.path).strip)
36
+ end
37
+
38
+ def test_cli_ignore_config_element
39
+ # for testing output
40
+ f = Tempfile.new('test_output')
41
+ f.close
42
+
43
+ # for testing input
44
+ cf = Tempfile.new('test_config')
45
+ cf.puts <<~YAML
46
+ env:
47
+ MY_IGNORED_VAR: a_word
48
+ params:
49
+ a_param_var: another_word
50
+ run:
51
+ - exec: echo repeating $MY_IGNORED_VAR and also $a_param_var >> #{f.path}
52
+ YAML
53
+ cf.close
54
+
55
+ Cli.run(["--ignore", "env,params", cf.path])
56
+ assert_equal('repeating and also', File.read(f.path).strip)
57
+ end
58
+
59
+ def test_cli_gen_docker_run_args_ignores_other_config
60
+ # When generating the docker run arguments it should ignore other template configuration
61
+ # like 'run' directives.
62
+
63
+ # for testing output
64
+ f = Tempfile.new("test_output")
65
+ f.close
66
+
67
+ # for testing input
68
+ cf = Tempfile.new("test_config")
69
+ cf.puts <<~YAML
70
+ env:
71
+ foo: 1
72
+ bar: 5
73
+ baz: 'hello_{{spam}}'
74
+ env_template:
75
+ spam: 'eggs'
76
+ config: my_app
77
+ params:
78
+ run: #{f.path}
79
+ run:
80
+ - exec: echo hello world >> #{f.path}
81
+ expose:
82
+ - "2222:22"
83
+ - "127.0.0.1:20080:80"
84
+ - 5555
85
+ volumes:
86
+ - volume:
87
+ host: /var/discourse/shared
88
+ guest: /shared
89
+ - volume:
90
+ host: /bar
91
+ guest: /baz
92
+ links:
93
+ - link:
94
+ name: postgres
95
+ alias: postgres
96
+ - link:
97
+ name: foo
98
+ alias: bar
99
+ labels:
100
+ monitor: "true"
101
+ app_name: "{{config}}_discourse"
102
+ YAML
103
+ cf.close
104
+
105
+ expected = []
106
+ expected << "--env foo=1 --env bar=5 --env baz=hello_eggs"
107
+ expected << "--publish 2222:22 --publish 127.0.0.1:20080:80 --expose 5555"
108
+ expected << "--volume /var/discourse/shared:/shared --volume /bar:/baz"
109
+ expected << "--link postgres:postgres --link foo:bar"
110
+ expected << "--label monitor=true --label app_name=my_app_discourse"
111
+ expected.sort!
112
+
113
+ assert_equal("", File.read(f.path).strip)
114
+ assert_output(expected.join(" ")) { Cli.run(["--gen-docker-run-args", cf.path]) }
115
+ end
116
+ end
117
+ end