helmsnap 0.1.0 → 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: 3c1238eff1b14a2e564bd43769307c6cb94659b6c838029420bc6a95bf01bde4
4
- data.tar.gz: f3c102029eb427e5d511062349007568e80a7c7b55ed6bd0adbabdf4593e0afe
3
+ metadata.gz: d23d2a85913e1acb605cf90521fdcf9f9ce6a3c95bfcecc24b1aae69a68d33a6
4
+ data.tar.gz: 927df5851020d802c04de2c2ebcb8e0c8078869087e7db735c39f02d1168b6bf
5
5
  SHA512:
6
- metadata.gz: a0ca141cdc412b9f7ca384b0ce6169fedeb74796f11fa0e957e3f63f06c2e24fb3a3a957b7ce46a1af19cb884b5e3c37faca7e85935bb2db76c839e373136a96
7
- data.tar.gz: ad5bccf70fc572be8d8dbd6e3f8c2ffeb166d92314c34e72a9090725c60cb60a02e6cc310f7577466a485c1113f76f90e68cb01a3a4d9dc85e0beca8e28137de
6
+ metadata.gz: 25a1d7514779a13e738169c2119bfc9ea27b1f5f092d2ac15fc381749763a5210efc07a8b52546eb7bc4045b3a6330d0e37176c8eea8bfb756176564551dfdda
7
+ data.tar.gz: 3ae5fe678eb301418175f688adc06478b7ac5b7e775d9a9e16e1bf5fcb97c8d48ed763fd7895ccddabe21d2e72e26acfb3616340ce1b4ab630d1ad0898b8baff
data/.rubocop.yml CHANGED
@@ -1,13 +1,17 @@
1
- AllCops:
2
- TargetRubyVersion: 2.6
3
-
4
- Style/StringLiterals:
5
- Enabled: true
6
- EnforcedStyle: double_quotes
1
+ inherit_gem:
2
+ rubocop-config-umbrellio: lib/rubocop.yml
7
3
 
8
- Style/StringLiteralsInInterpolation:
9
- Enabled: true
10
- EnforcedStyle: double_quotes
11
-
12
- Layout/LineLength:
13
- Max: 120
4
+ AllCops:
5
+ DisplayCopNames: true
6
+ TargetRubyVersion: 2.7
7
+ Include:
8
+ - bin/console
9
+ - Gemfile
10
+ - helmsnap.gemspec
11
+ - Rakefile
12
+ - lib/**/*
13
+ - spec/**/*
14
+ - gemfile/**/*
15
+ Exclude:
16
+ - vendor/**/*
17
+ - gemfiles/**/*
data/Gemfile.lock CHANGED
@@ -6,16 +6,27 @@ PATH
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ activesupport (6.1.4.1)
10
+ concurrent-ruby (~> 1.0, >= 1.0.2)
11
+ i18n (>= 1.6, < 2)
12
+ minitest (>= 5.1)
13
+ tzinfo (~> 2.0)
14
+ zeitwerk (~> 2.3)
9
15
  ast (2.4.2)
10
16
  coderay (1.1.3)
17
+ concurrent-ruby (1.1.9)
11
18
  diff-lcs (1.4.4)
19
+ i18n (1.8.11)
20
+ concurrent-ruby (~> 1.0)
12
21
  method_source (1.0.0)
22
+ minitest (5.14.4)
13
23
  parallel (1.21.0)
14
- parser (3.0.2.0)
24
+ parser (3.0.3.0)
15
25
  ast (~> 2.4.1)
16
26
  pry (0.14.1)
17
27
  coderay (~> 1.1)
18
28
  method_source (~> 1.0)
29
+ rack (2.2.3)
19
30
  rainbow (3.0.0)
20
31
  rake (13.0.6)
21
32
  regexp_parser (2.1.1)
@@ -33,19 +44,43 @@ GEM
33
44
  diff-lcs (>= 1.2.0, < 2.0)
34
45
  rspec-support (~> 3.10.0)
35
46
  rspec-support (3.10.3)
36
- rubocop (1.23.0)
47
+ rubocop (1.17.0)
37
48
  parallel (~> 1.10)
38
49
  parser (>= 3.0.0.0)
39
50
  rainbow (>= 2.2.2, < 4.0)
40
51
  regexp_parser (>= 1.8, < 3.0)
41
52
  rexml
42
- rubocop-ast (>= 1.12.0, < 2.0)
53
+ rubocop-ast (>= 1.7.0, < 2.0)
43
54
  ruby-progressbar (~> 1.7)
44
55
  unicode-display_width (>= 1.4.0, < 3.0)
45
56
  rubocop-ast (1.13.0)
46
57
  parser (>= 3.0.1.1)
58
+ rubocop-config-umbrellio (1.17.0.53)
59
+ rubocop (= 1.17.0)
60
+ rubocop-performance (= 1.10.0)
61
+ rubocop-rails (= 2.9.1)
62
+ rubocop-rake (= 0.5.1)
63
+ rubocop-rspec (= 2.2.0)
64
+ rubocop-sequel (= 0.2.0)
65
+ rubocop-performance (1.10.0)
66
+ rubocop (>= 0.90.0, < 2.0)
67
+ rubocop-ast (>= 0.4.0)
68
+ rubocop-rails (2.9.1)
69
+ activesupport (>= 4.2.0)
70
+ rack (>= 1.1)
71
+ rubocop (>= 0.90.0, < 2.0)
72
+ rubocop-rake (0.5.1)
73
+ rubocop
74
+ rubocop-rspec (2.2.0)
75
+ rubocop (~> 1.0)
76
+ rubocop-ast (>= 1.1.0)
77
+ rubocop-sequel (0.2.0)
78
+ rubocop (~> 1.0)
47
79
  ruby-progressbar (1.11.0)
80
+ tzinfo (2.0.4)
81
+ concurrent-ruby (~> 1.0)
48
82
  unicode-display_width (2.1.0)
83
+ zeitwerk (2.5.1)
49
84
 
50
85
  PLATFORMS
51
86
  x86_64-darwin-20
@@ -56,6 +91,7 @@ DEPENDENCIES
56
91
  rake
57
92
  rspec
58
93
  rubocop
94
+ rubocop-config-umbrellio
59
95
 
60
96
  BUNDLED WITH
61
97
  2.2.31
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/exe/helmsnap CHANGED
@@ -1,117 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require "digest"
5
- require "fileutils"
6
- require "open3"
7
- require "optparse"
8
- require "pathname"
9
- require "shellwords"
4
+ require_relative "../lib/helmsnap"
10
5
 
11
- def run(*cmd_parts)
12
- cmd = Shellwords.join(cmd_parts)
13
-
14
- puts "\e[1m\e[33m#{cmd}\e[0m\e[22m"
15
-
16
- Open3.popen3(cmd) do |_stdin, stdout, stderr, wait_thr|
17
- output = +""
18
-
19
- while chunk = stdout.gets
20
- $stdout.print(chunk)
21
- output << chunk
22
- end
23
-
24
- exit_status = wait_thr.value
25
-
26
- unless exit_status.success?
27
- $stderr.print(stderr.read)
28
- abort "Command failed with status #{exit_status.to_i}"
29
- end
30
-
31
- puts
32
- output
33
- end
34
- end
35
-
36
- class ArgsParser
37
- Args = Struct.new(:chart, :snapshots, :values)
38
- MissingOption = Class.new(OptionParser::ParseError)
39
-
40
- def initialize(options)
41
- self.options = options
42
- self.args = Args.new("k8s/chart", "k8s/snapshots")
43
- self.parser = build_parser
44
- end
45
-
46
- def get_options!
47
- parser.parse!(options)
48
- raise MissingOption, "missing option: VALUES" unless args.values
49
- args
50
- rescue OptionParser::ParseError => e
51
- puts e, nil
52
- print_help!
53
- exit 1
54
- end
55
-
56
- private
57
-
58
- attr_accessor :options, :parser, :args
59
-
60
- def build_parser
61
- OptionParser.new do |opts|
62
- opts.banner = "Usage: render-helm [options]"
63
-
64
- opts.on("-c", "--chart-dir [DIR]",
65
- "Chart directory (default: #{args.chart})") do |option|
66
- args.chart = option
67
- end
68
-
69
- opts.on("-s", "--snapshots-dir DIR",
70
- "Snapshots directory (default #{args.snapshots})") do |option|
71
- args.snapshots = option
72
- end
73
-
74
- opts.on("-v", "--values VALUES", "Values file") do |option|
75
- args.values = option
76
- end
77
-
78
- opts.on("-h", "--help", "Show this message") do
79
- puts opts
80
- exit
81
- end
82
- end
83
- end
84
-
85
- def print_help!
86
- puts parser.help
87
- end
88
- end
89
-
90
- options = ArgsParser.new(ARGV).get_options!
91
-
92
- chart_path = Pathname.new(options.chart)
93
- snapshots_path = Pathname.new(options.snapshots)
94
-
95
- dep_list = run "helm", "dependency", "list", "--max-col-width", 0, chart_path
96
-
97
- dep_list.scan(%r{file://(.+?)\t}) do |dep_path|
98
- run "helm", "dependency", "update", "--skip-refresh", chart_path.join(dep_path.first)
99
- end
100
-
101
- dep_list.scan(%r{(https?://.+?)\t}) do |dep_path|
102
- run "helm", "repo", "add", Digest::MD5.hexdigest(dep_path.first), dep_path.first
103
- end
104
-
105
- run "helm", "dependency", "update", "--skip-refresh", chart_path
106
-
107
- FileUtils.rmtree(snapshots_path)
108
-
109
- run "helm", "template", chart_path,
110
- "--values", options.values,
111
- "--output-dir", snapshots_path
112
-
113
- snapshots_path.glob(["**/*yaml", "**/*.yml"]).each do |path|
114
- content = path.read
115
- content.gsub!(/\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\.\d+/, "2022-01-01 00:00:00.000") or next
116
- path.write(content)
117
- end
6
+ Helmsnap::Runner.call(ARGV)
data/helmsnap.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
  spec.summary = "A tool for creating and checking helm chart snapshots."
12
12
  spec.homepage = "https://github.com/tycooon/helmsnap"
13
13
  spec.license = "MIT"
14
- spec.required_ruby_version = ">= 2.6.0"
14
+ spec.required_ruby_version = ">= 2.7.0"
15
15
 
16
16
  # spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
17
17
  spec.metadata["homepage_uri"] = spec.homepage
@@ -22,11 +22,13 @@ Gem::Specification.new do |spec|
22
22
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
23
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
24
24
  `git ls-files -z`.split("\x0").reject do |f|
25
- (f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
25
+ (f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci))})
26
26
  end
27
27
  end
28
28
 
29
29
  spec.bindir = "exe"
30
30
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
31
31
  spec.require_paths = ["lib"]
32
+
33
+ spec.add_development_dependency "rubocop-config-umbrellio"
32
34
  end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Helmsnap::ArgsParser
4
+ Args = Struct.new(:chart_path, :snapshots_path, :values_path, keyword_init: true)
5
+ MissingOption = Class.new(OptionParser::ParseError)
6
+
7
+ def initialize(options)
8
+ self.options = options
9
+ self.args = Args.new
10
+ self.parser = build_parser
11
+ end
12
+
13
+ def get_options!
14
+ parser.parse!(options)
15
+ raise MissingOption, "Missing option: CHARTDIR" unless args.chart_path
16
+ raise MissingOption, "Missing option: SNAPDIR" unless args.snapshots_path
17
+ raise MissingOption, "Missing option: VALUES" unless args.values_path
18
+ args
19
+ rescue OptionParser::ParseError => error
20
+ print_help!(error)
21
+ end
22
+
23
+ def print_help!(msg)
24
+ puts msg, nil
25
+ puts parser.help
26
+ exit 1
27
+ end
28
+
29
+ private
30
+
31
+ attr_accessor :options, :parser, :args
32
+
33
+ def build_parser
34
+ OptionParser.new do |opts|
35
+ opts.banner = "Usage: helmsnap CMD [options]"
36
+ opts.separator("Supported commands: `generate` and `check`.")
37
+ opts.separator("")
38
+ opts.separator("Specific options:")
39
+
40
+ opts.on("-c", "--chart-dir CHARTDIR", "Chart directory") do |option|
41
+ args.chart_path = pn(option)
42
+ end
43
+
44
+ opts.on("-s", "--snapshots-dir SNAPDIR", "Snapshots directory") do |option|
45
+ args.snapshots_path = pn(option)
46
+ end
47
+
48
+ opts.on("-v", "--values VALUES", "Values file") do |option|
49
+ args.values_path = pn(option)
50
+ end
51
+
52
+ opts.on("-h", "--help", "Show this message") do
53
+ puts opts
54
+ exit
55
+ end
56
+ end
57
+ end
58
+
59
+ def pn(...)
60
+ Pathname.new(...)
61
+ end
62
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Helmsnap::Check
4
+ def self.call(...)
5
+ new(...).call
6
+ end
7
+
8
+ def initialize(chart_path:, snapshots_path:, values_path:)
9
+ self.chart_path = chart_path
10
+ self.snapshots_path = snapshots_path
11
+ self.values_path = values_path
12
+ end
13
+
14
+ def call
15
+ Dir.mktmpdir do |temp_dir|
16
+ pp temp_dir_path = Pathname.new(temp_dir)
17
+
18
+ Helmsnap::Generate.call(
19
+ chart_path: chart_path,
20
+ snapshots_path: temp_dir_path,
21
+ values_path: values_path,
22
+ )
23
+
24
+ Helmsnap.run_cmd!("colordiff", "-r", temp_dir_path, snapshots_path)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ attr_accessor :chart_path, :snapshots_path, :values_path
31
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Helmsnap::Command
4
+ def self.call(...)
5
+ new(...).call
6
+ end
7
+
8
+ def initialize(cmd)
9
+ self.cmd = cmd
10
+ end
11
+
12
+ def call
13
+ puts "\e[1m\e[33m#{cmd}\e[0m\e[22m"
14
+
15
+ Open3.popen3(cmd) do |_stdin, stdout, stderr, wait_thr|
16
+ output = +""
17
+
18
+ while (chunk = stdout.gets)
19
+ $stdout.print(chunk)
20
+ output << chunk
21
+ end
22
+
23
+ exit_status = wait_thr.value
24
+
25
+ unless exit_status.success?
26
+ $stderr.print(stderr.read)
27
+ abort "Command failed with status #{exit_status.to_i}"
28
+ end
29
+
30
+ puts
31
+ output
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ attr_accessor :cmd
38
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Helmsnap::Generate
4
+ def self.call(...)
5
+ new(...).call
6
+ end
7
+
8
+ def initialize(chart_path:, snapshots_path:, values_path:)
9
+ self.chart_path = chart_path
10
+ self.snapshots_path = snapshots_path
11
+ self.values_path = values_path
12
+ end
13
+
14
+ def call
15
+ dep_list = run_cmd!("helm", "dependency", "list", "--max-col-width", 0, chart_path)
16
+
17
+ dep_list.scan(%r{file://(.+?)\t}) do |dep_path|
18
+ run_cmd!("helm", "dependency", "update", "--skip-refresh", chart_path.join(dep_path.first))
19
+ end
20
+
21
+ dep_list.scan(%r{(https?://.+?)\t}) do |dep_path|
22
+ run_cmd!("helm", "repo", "add", Digest::MD5.hexdigest(dep_path.first), dep_path.first)
23
+ end
24
+
25
+ run_cmd!("helm", "dependency", "update", "--skip-refresh", chart_path)
26
+
27
+ FileUtils.rmtree(snapshots_path)
28
+
29
+ run_cmd!(
30
+ "helm", "template", chart_path, "--values", values_path, "--output-dir", snapshots_path
31
+ )
32
+
33
+ snapshots_path.glob(["**/*yaml", "**/*.yml"]).each do |path|
34
+ content = path.read
35
+ content.gsub!(/\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\.\d+/, "2022-01-01 00:00:00.000") or next
36
+ path.write(content)
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ attr_accessor :chart_path, :snapshots_path, :values_path
43
+
44
+ def run_cmd!(...)
45
+ Helmsnap.run_cmd!(...)
46
+ end
47
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Helmsnap::Runner
4
+ def self.call(...)
5
+ new(...).call
6
+ end
7
+
8
+ def initialize(args)
9
+ self.args = args.dup
10
+ end
11
+
12
+ def call
13
+ parser = Helmsnap::ArgsParser.new(args)
14
+ options = parser.get_options!
15
+
16
+ cmd, *rest = args
17
+
18
+ if cmd.nil?
19
+ parser.print_help!("Command not provided.")
20
+ end
21
+
22
+ if rest.size.positive?
23
+ parser.print_help!("Too many arguments.")
24
+ end
25
+
26
+ case cmd
27
+ when "generate"
28
+ Helmsnap::Generate.call(**options.to_h)
29
+ when "check"
30
+ Helmsnap::Check.call(**options.to_h)
31
+ else
32
+ parser.print_help!("Unknown command: #{cmd}.")
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ attr_accessor :args
39
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Helmsnap
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/helmsnap.rb CHANGED
@@ -1,7 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "helmsnap/version"
3
+ require "digest"
4
+ require "fileutils"
5
+ require "open3"
6
+ require "optparse"
7
+ require "pathname"
8
+ require "shellwords"
9
+ require "tmpdir"
4
10
 
5
11
  module Helmsnap
12
+ require_relative "helmsnap/args_parser"
13
+ require_relative "helmsnap/check"
14
+ require_relative "helmsnap/command"
15
+ require_relative "helmsnap/generate"
16
+ require_relative "helmsnap/runner"
17
+ require_relative "helmsnap/version"
18
+
6
19
  class Error < StandardError; end
20
+
21
+ def self.run_cmd!(*cmd_parts)
22
+ cmd = Shellwords.join(cmd_parts)
23
+ Helmsnap::Command.call(cmd)
24
+ end
7
25
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: helmsnap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuri Smirnov
@@ -9,7 +9,21 @@ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
11
  date: 2021-11-27 00:00:00.000000000 Z
12
- dependencies: []
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rubocop-config-umbrellio
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  description:
14
28
  email:
15
29
  - tycooon@yandex.ru
@@ -26,9 +40,15 @@ files:
26
40
  - README.md
27
41
  - Rakefile
28
42
  - bin/console
43
+ - bin/setup
29
44
  - exe/helmsnap
30
45
  - helmsnap.gemspec
31
46
  - lib/helmsnap.rb
47
+ - lib/helmsnap/args_parser.rb
48
+ - lib/helmsnap/check.rb
49
+ - lib/helmsnap/command.rb
50
+ - lib/helmsnap/generate.rb
51
+ - lib/helmsnap/runner.rb
32
52
  - lib/helmsnap/version.rb
33
53
  homepage: https://github.com/tycooon/helmsnap
34
54
  licenses:
@@ -44,7 +64,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
44
64
  requirements:
45
65
  - - ">="
46
66
  - !ruby/object:Gem::Version
47
- version: 2.6.0
67
+ version: 2.7.0
48
68
  required_rubygems_version: !ruby/object:Gem::Requirement
49
69
  requirements:
50
70
  - - ">="