gene_system 0.3.2 → 0.4.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69b1b6ad105f91562009bfa99f1a2cc3a3dfd0391a54a4e58b65296cc452e581
4
- data.tar.gz: de398efc98b4de7eb7f3b8a8661790f5ca9f89cf55165abc89a7ec0b97b3986c
3
+ metadata.gz: 559379df624aadc40f65cb1c3c9ab01f152fbbbaa238e1b5e2f71fcb97d84874
4
+ data.tar.gz: a0dbf8ab2cba60a31d8022601922660d93c87d8e6bf3c0a2653c344ce9e6aeed
5
5
  SHA512:
6
- metadata.gz: b3936aa6de8f87fec7fbabfa7574e7ab15a0252a7f653efb163bf78a341eb0451766b32db7e2b3616583589116f863e1e7747331f8cc3e6a5af0aa965c01e6bb
7
- data.tar.gz: 524c443a8ee2425184e70072336e4d99f6b3716f14864c723164ecc7d422a1fcab722edb0b212741be7cf71964245699b80990e6eb8ec77311c9b5850f8f3533
6
+ metadata.gz: 79a46d8e6cfbe40d422ba6fdb8c7de1575dd52a94664c4550e4cfc54f5f9be72a0d541137e0dee65cbc535ea98a02a8d5f57e698f0ca3e23e5c9b5531815a83d
7
+ data.tar.gz: f052a0aea8250f8ec4e6a412c0a4af883f315ef2a2e6a85021cbcded1adfab4165a9efdc3c92d95d0c98b56ae64ff053a0e2ed289d0342c0a783e4ecab338ae9
data/Gemfile CHANGED
@@ -1,10 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- git_source(:biggerconcept) do |repo_name|
4
- username = ENV['BIGGERCONCEPT_CI_USER']
5
- password = ENV['BIGGERCONCEPT_CI_PASSWORD']
6
- git_host = ENV['BIGGERCONCEPT_GIT_HOSTpro']
7
- "https://#{username}:#{password}@#{git_host}/#{repo_name}"
8
- end
9
-
10
3
  gemspec
data/Gemfile.lock CHANGED
@@ -1,18 +1,20 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gene_system (0.3.2)
4
+ gene_system (0.4.0)
5
5
  hashie
6
6
  highline (~> 2.0)
7
7
  jsonnet
8
8
  logger (~> 1.4)
9
9
  os
10
10
  ruby-handlebars (~> 0.4)
11
+ thor (~> 1.0)
12
+ tty-prompt
11
13
 
12
14
  GEM
13
15
  remote: https://rubygems.org/
14
16
  specs:
15
- addressable (2.7.0)
17
+ addressable (2.8.0)
16
18
  public_suffix (>= 2.0.2, < 5.0)
17
19
  ast (2.4.2)
18
20
  axiom-types (0.1.1)
@@ -21,15 +23,14 @@ GEM
21
23
  thread_safe (~> 0.3, >= 0.3.1)
22
24
  bump (0.10.0)
23
25
  byebug (11.1.3)
24
- codeclimate-engine-rb (0.4.1)
25
- virtus (~> 1.0)
26
+ codeclimate-engine-rb (0.4.2)
26
27
  coderay (1.1.3)
27
28
  coercible (1.0.0)
28
29
  descendants_tracker (~> 0.0.1)
29
30
  descendants_tracker (0.0.4)
30
31
  thread_safe (~> 0.3, >= 0.3.1)
31
32
  diff-lcs (1.4.4)
32
- docile (1.3.5)
33
+ docile (1.4.0)
33
34
  doxie (4.0.0)
34
35
  equalizer (0.0.11)
35
36
  erubis (2.7.0)
@@ -42,7 +43,7 @@ GEM
42
43
  path_expander (~> 1.0)
43
44
  ruby_parser (~> 3.1, > 3.1.0)
44
45
  sexp_processor (~> 4.8)
45
- hashie (4.1.0)
46
+ hashie (5.0.0)
46
47
  highline (2.0.3)
47
48
  ice_nine (0.11.2)
48
49
  jaro_winkler (1.5.4)
@@ -50,15 +51,17 @@ GEM
50
51
  mini_portile2 (>= 2.2.0)
51
52
  launchy (2.4.3)
52
53
  addressable (~> 2.3)
53
- logger (1.4.3)
54
+ logger (1.4.4)
54
55
  method_source (1.0.0)
55
- mini_portile2 (2.6.1)
56
- nio4r (2.5.7)
57
- os (1.1.1)
58
- parallel (1.20.1)
56
+ mini_portile2 (2.7.1)
57
+ nio4r (2.5.8)
58
+ os (1.1.4)
59
+ parallel (1.21.0)
59
60
  parser (2.5.3.0)
60
61
  ast (~> 2.4.0)
61
62
  parslet (1.8.2)
63
+ pastel (0.8.0)
64
+ tty-color (~> 0.5)
62
65
  path_expander (1.1.0)
63
66
  private_gem (1.1.4)
64
67
  bundler (> 1.7, < 3.0)
@@ -67,10 +70,10 @@ GEM
67
70
  coderay (~> 1.1)
68
71
  method_source (~> 1.0)
69
72
  public_suffix (4.0.6)
70
- puma (4.3.7)
73
+ puma (4.3.10)
71
74
  nio4r (~> 2.0)
72
75
  rainbow (3.0.0)
73
- rake (13.0.3)
76
+ rake (13.0.6)
74
77
  reek (4.8.2)
75
78
  codeclimate-engine-rb (~> 0.4.0)
76
79
  parser (>= 2.5.0.0, < 2.6)
@@ -87,7 +90,7 @@ GEM
87
90
  rspec-mocks (3.10.2)
88
91
  diff-lcs (>= 1.2.0, < 2.0)
89
92
  rspec-support (~> 3.10.0)
90
- rspec-support (3.10.2)
93
+ rspec-support (3.10.3)
91
94
  rubocop (0.68.1)
92
95
  jaro_winkler (~> 1.5.1)
93
96
  parallel (~> 1.10)
@@ -98,8 +101,8 @@ GEM
98
101
  ruby-handlebars (0.4.0)
99
102
  parslet (~> 1.6, >= 1.6.2)
100
103
  ruby-progressbar (1.11.0)
101
- ruby_parser (3.15.1)
102
- sexp_processor (~> 4.9)
104
+ ruby_parser (3.18.1)
105
+ sexp_processor (~> 4.16)
103
106
  rubycritic (3.5.2)
104
107
  flay (~> 2.8)
105
108
  flog (~> 4.4)
@@ -110,7 +113,7 @@ GEM
110
113
  ruby_parser (~> 3.8)
111
114
  tty-which (~> 0.3.0)
112
115
  virtus (~> 1.0)
113
- sexp_processor (4.15.2)
116
+ sexp_processor (4.16.0)
114
117
  simplecov (0.21.2)
115
118
  docile (~> 1.1)
116
119
  simplecov-html (~> 0.11)
@@ -119,6 +122,16 @@ GEM
119
122
  simplecov_json_formatter (0.1.3)
120
123
  thor (1.1.0)
121
124
  thread_safe (0.3.6)
125
+ tty-color (0.6.0)
126
+ tty-cursor (0.7.1)
127
+ tty-prompt (0.23.1)
128
+ pastel (~> 0.8)
129
+ tty-reader (~> 0.8)
130
+ tty-reader (0.9.0)
131
+ tty-cursor (~> 0.7)
132
+ tty-screen (~> 0.8)
133
+ wisper (~> 2.0)
134
+ tty-screen (0.8.1)
122
135
  tty-which (0.3.0)
123
136
  unicode-display_width (1.5.0)
124
137
  virtus (1.0.5)
@@ -126,6 +139,7 @@ GEM
126
139
  coercible (~> 1.0)
127
140
  descendants_tracker (~> 0.0, >= 0.0.3)
128
141
  equalizer (~> 0.0, >= 0.0.9)
142
+ wisper (2.0.1)
129
143
  yard (0.9.26)
130
144
 
131
145
  PLATFORMS
@@ -147,4 +161,4 @@ DEPENDENCIES
147
161
  yard (~> 0.9)
148
162
 
149
163
  BUNDLED WITH
150
- 2.2.16
164
+ 2.2.27
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # GeneSystem
2
2
 
3
+ [![Ruby](https://github.com/andrewbigger/gene_system/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/andrewbigger/gene_system/actions/workflows/build.yml)
4
+
3
5
  A gem for configuring systems via json or jsonnet manifest.
4
6
 
5
7
  ## Installation
data/bin/gene_system ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib_path = File.expand_path('../lib', __dir__)
4
+ $LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path)
5
+
6
+ require 'pry'
7
+ require 'gene_system/cli'
8
+
9
+ Signal.trap('INT') do
10
+ warn("\n#{caller.join("\n")}: interrupted")
11
+ exit(1)
12
+ end
13
+
14
+ begin
15
+ GeneSystem::CLI.start
16
+ rescue StandardError => e
17
+ puts "ERROR: #{e.message}"
18
+ puts e.backtrace.join("\n")
19
+ exit 1
20
+ end
data/bin/genesystem CHANGED
@@ -1,52 +1,20 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $LOAD_PATH.unshift(__dir__ + '/../lib')
3
+ lib_path = File.expand_path('../lib', __dir__)
4
+ $LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path)
4
5
 
5
- require 'rubygems'
6
- require 'optparse'
7
- require 'highline'
8
-
9
- require 'gene_system'
6
+ require 'pry'
10
7
  require 'gene_system/cli'
11
8
 
12
- USAGE = "GeneSystem system configuration tool
13
-
14
- Usage:\tgenesystem <command> <variables> <opts>
15
- Options:
16
- \s\s\s\s--trace\t\t trace mode on
17
- -h, --help\t\t print usage
18
-
19
- Commands:
20
- new <rel>\t\t creates a new manifest
21
- install <rel>\t\t applies install steps specified in manifest
22
- remove <rel>\t\t applies remove steps specified in manifest
23
- ".freeze
24
-
25
- @trace = false
26
- @overwrite = false
27
-
28
- OptionParser.new do |opts|
29
- opts.banner = USAGE
30
- opts.on('--trace') { @trace = true }
31
-
32
- opts.on_tail('-h', '--help') do
33
- GeneSystem::CLI.print_message_and_exit(USAGE)
34
- end
35
- end.parse!
9
+ Signal.trap('INT') do
10
+ warn("\n#{caller.join("\n")}: interrupted")
11
+ exit(1)
12
+ end
36
13
 
37
14
  begin
38
- raise 'ERROR: no command provided' unless ARGV[0]
39
-
40
- cmd = ARGV.shift
41
- GeneSystem::CLI::Commands.public_send(
42
- cmd.to_sym,
43
- ARGV
44
- )
15
+ GeneSystem::CLI.start
45
16
  rescue StandardError => e
46
- GeneSystem::CLI.print_message(e)
47
- GeneSystem::CLI.print_message(e.backtrace) if @trace
48
- GeneSystem::CLI.print_message("\n")
49
- GeneSystem::CLI.print_message_and_exit(USAGE)
17
+ puts "ERROR: #{e.message}"
18
+ puts e.backtrace.join("\n")
19
+ exit 1
50
20
  end
51
-
52
- exit(0)
data/gene_system.gemspec CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.version = GeneSystem::VERSION
10
10
  spec.authors = ['Andrew Bigger']
11
11
  spec.email = ['andrew.bigger@gmail.com']
12
- spec.summary = 'System configuration tool for applying personal settings to a new machine.'
12
+ spec.summary = 'System configuration tool for applying settings'
13
13
  spec.homepage = 'https://github.com/andrewbigger/gene_system'
14
14
  spec.license = 'MIT'
15
15
 
@@ -24,6 +24,8 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency 'logger', '~> 1.4'
25
25
  spec.add_dependency 'os'
26
26
  spec.add_dependency 'ruby-handlebars', '~> 0.4'
27
+ spec.add_dependency 'thor', '~> 1.0'
28
+ spec.add_dependency 'tty-prompt'
27
29
 
28
30
  spec.add_development_dependency 'bump', '~> 0.6'
29
31
  spec.add_development_dependency 'byebug', '~> 11.0'
@@ -1,76 +1,64 @@
1
- require 'gene_system/cli/commands'
1
+ require 'thor'
2
+ require 'gene_system'
3
+ require 'gene_system/commands'
2
4
 
3
5
  require 'hashie'
4
6
 
5
7
  module GeneSystem
6
8
  # Command line interface helpers and actions
7
- module CLI
8
- # CLI Helpers
9
- class <<self
10
- ##
11
- # Creates logger for printing messages
12
- #
13
- # Sets the formatter to output only the provided message to the
14
- # specified IO
15
- #
16
- # @param [IO] out - default: STDOUT
17
- #
18
- # @return [Logger]
19
- #
20
- def logger(out = STDOUT)
21
- @logger ||= Logger.new(out)
22
- @logger.formatter = proc do |_sev, _time, _prog, msg|
23
- "#{msg}\n"
24
- end
9
+ class CLI < Thor
10
+ package_name 'GeneSystem'
25
11
 
26
- @logger
27
- end
12
+ desc 'version', 'Print gem version'
28
13
 
29
- ##
30
- # Prints command line message to STDOUT
31
- #
32
- # For use when printing info messages for a user to STDOUT
33
- #
34
- # @param [String] message - message to be printed
35
- #
36
- def print_message(message)
37
- logger.info(message)
38
- end
14
+ def version
15
+ cmd = GeneSystem::Commands::PrintVersion.new(options)
16
+ cmd.run
17
+ end
18
+
19
+ desc 'new', 'Create new manifest'
20
+
21
+ method_option(
22
+ :out,
23
+ type: :string,
24
+ desc: 'Path to folder for manifest'
25
+ )
26
+
27
+ method_option(
28
+ :name,
29
+ type: :string,
30
+ desc: 'Name of manifest (i.e. manifest.json)'
31
+ )
32
+
33
+ def new
34
+ cmd = GeneSystem::Commands::CreateManifest.new(options)
35
+ cmd.run
36
+ end
37
+
38
+ desc 'install', 'Applies install instructions from given manifest'
39
+
40
+ method_option(
41
+ :manifest,
42
+ type: :string,
43
+ desc: 'Path to manifest (i.e. manifest.json)'
44
+ )
45
+
46
+ def install
47
+ cmd = GeneSystem::Commands::InstallManifest.new(options)
48
+ cmd.run
49
+ end
39
50
 
40
- ##
41
- # Prints warning to STDOUT
42
- #
43
- # For use when printing warn messages to STDOUT
44
- #
45
- # @param [String] message - message to be printed
46
- #
47
- def print_warning(message)
48
- logger.warn(message)
49
- end
51
+ desc 'remove', 'Applies remove instructions from given manifest'
50
52
 
51
- ##
52
- # Prints error to STDERR
53
- #
54
- # For indicating fatal message to user
55
- #
56
- # @param [String] message - message to be printed
57
- #
58
- def print_error(message)
59
- logger(STDERR).error(message)
60
- end
53
+ method_option(
54
+ :manifest,
55
+ type: :string,
56
+ desc: 'Path to manifest (i.e. manifest.json)'
57
+ )
61
58
 
62
- ##
63
- # Prints a message and then exits with given status code
64
- #
65
- # This will terminate the program with the given status code
66
- #
67
- # @param [String] message - message to be printed
68
- # @param [Integer] exit_code - exit status (default: 1)
69
- #
70
- def print_message_and_exit(message, exit_code = 1)
71
- print_message(message)
72
- exit(exit_code)
73
- end
59
+ def remove
60
+ cmd = GeneSystem::Commands::RemoveManifest.new(options)
61
+ cmd.run
74
62
  end
75
63
  end
76
64
  end
@@ -0,0 +1,54 @@
1
+ module GeneSystem
2
+ module Commands
3
+ # Create manifest command
4
+ class CreateManifest
5
+ ##
6
+ # Default name of gene system manifest
7
+ #
8
+ DEFAULT_MANIFEST_NAME = 'manifest.json'.freeze
9
+
10
+ def initialize(options)
11
+ @options = options
12
+ @prompt = TTY::Prompt.new
13
+ end
14
+
15
+ ##
16
+ # Creates a new, blank manifest with at the specified
17
+ # destination with the specified name.
18
+ #
19
+ # If the options are not provided the user will be prompted
20
+ # for the manifest name and location.
21
+ #
22
+ # If the output location is not a directory then a
23
+ # RuntimeError will be raised.
24
+ #
25
+ # When successfully rendered a success message will be
26
+ # printed to STDOUT.
27
+ #
28
+ def run
29
+ manifest_name = @options.name
30
+ manifest_name ||= @prompt.ask(
31
+ 'Please enter the name of the manifest',
32
+ default: DEFAULT_MANIFEST_NAME
33
+ )
34
+
35
+ output_location = @options.out
36
+ output_location ||= @prompt.ask(
37
+ 'Please specify output location',
38
+ default: Dir.pwd
39
+ )
40
+
41
+ unless File.directory?(output_location)
42
+ raise 'output location must be a folder'
43
+ end
44
+
45
+ GeneSystem::Generators.render_empty_manifest(
46
+ manifest_name,
47
+ output_location
48
+ )
49
+
50
+ puts "✔ Manifest successfully created in #{output_location}"
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,86 @@
1
+ module GeneSystem
2
+ module Commands
3
+ # Install manifest command
4
+ class InstallManifest
5
+ ##
6
+ # Default name of gene system manifest
7
+ #
8
+ DEFAULT_MANIFEST_NAME = 'manifest.json'.freeze
9
+
10
+ def initialize(options)
11
+ @options = options
12
+ @prompt = TTY::Prompt.new
13
+ @manifest = nil
14
+ end
15
+
16
+ ##
17
+ # Applies install instructions from a manifest
18
+ # to the host system.
19
+ #
20
+ def run
21
+ manifest_path = @options.manifest
22
+ manifest_path ||= @prompt.ask(
23
+ 'Please enter the path to the configuration manifest',
24
+ default: DEFAULT_MANIFEST_NAME
25
+ )
26
+
27
+ @manifest = GeneSystem::Manifest.new_from_file(manifest_path)
28
+ platform = GeneSystem::Platform.new
29
+
30
+ puts("INSTALL #{@manifest.name_and_version}")
31
+
32
+ @manifest.steps.each do |step|
33
+ next if skip?(step, platform)
34
+
35
+ vars = ask(step.install.prompts)
36
+
37
+ platform.execute_commands(
38
+ step.install.cmd,
39
+ vars
40
+ )
41
+ end
42
+
43
+ puts(
44
+ "✔ Manifest #{@manifest.name_and_version} successfully installed"
45
+ )
46
+ end
47
+
48
+ private
49
+
50
+ ##
51
+ # Asks for user input when given prompts
52
+ #
53
+ # @param prompts [Array]
54
+ #
55
+ # @return Hashie::Mash
56
+ #
57
+ def ask(prompts = [])
58
+ answers = @manifest.variables
59
+ return answers if prompts.nil? || prompts.empty?
60
+
61
+ prompts.each do |prompt|
62
+ resp = @prompt.ask(prompt.prompt)
63
+ answers[prompt.var] = resp
64
+ end
65
+
66
+ answers
67
+ end
68
+
69
+ ##
70
+ # Determines whether to skip a step
71
+ #
72
+ # @param [GeneSystem::Step] step
73
+ # @param [GeneSystem::Platform] platform
74
+ #
75
+ # @return [Boolean]
76
+ #
77
+ def skip?(step, platform)
78
+ return false if step.install.skip.nil?
79
+
80
+ platform.execute_command(
81
+ step.install.skip
82
+ ).zero?
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,17 @@
1
+ module GeneSystem
2
+ module Commands
3
+ # Gem version command
4
+ class PrintVersion
5
+ def initialize(options)
6
+ @options = options
7
+ end
8
+
9
+ ##
10
+ # Prints version to STDOUT
11
+ #
12
+ def run
13
+ puts(GeneSystem::VERSION)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,86 @@
1
+ module GeneSystem
2
+ module Commands
3
+ # Remove manifest command
4
+ class RemoveManifest
5
+ ##
6
+ # Default name of gene system manifest
7
+ #
8
+ DEFAULT_MANIFEST_NAME = 'manifest.json'.freeze
9
+
10
+ def initialize(options)
11
+ @options = options
12
+ @prompt = TTY::Prompt.new
13
+ @manifest = nil
14
+ end
15
+
16
+ ##
17
+ # Applies remove instructions from a manifest
18
+ # to the host system.
19
+ #
20
+ def run
21
+ manifest_path = @options.manifest
22
+ manifest_path ||= @prompt.ask(
23
+ 'Please enter the path to the configuration manifest',
24
+ default: DEFAULT_MANIFEST_NAME
25
+ )
26
+
27
+ @manifest = GeneSystem::Manifest.new_from_file(manifest_path)
28
+ platform = GeneSystem::Platform.new
29
+
30
+ puts("REMOVE #{@manifest.name_and_version}")
31
+
32
+ @manifest.steps.each do |step|
33
+ next if skip?(step, platform)
34
+
35
+ vars = ask(step.remove.prompts)
36
+
37
+ platform.execute_commands(
38
+ step.remove.cmd,
39
+ vars
40
+ )
41
+ end
42
+
43
+ puts(
44
+ "✔ Manifest #{@manifest.name_and_version} successfully removed"
45
+ )
46
+ end
47
+
48
+ private
49
+
50
+ ##
51
+ # Asks for user input when given prompts
52
+ #
53
+ # @param prompts [Array]
54
+ #
55
+ # @return Hashie::Mash
56
+ #
57
+ def ask(prompts = [])
58
+ answers = @manifest.variables
59
+ return answers if prompts.nil?
60
+
61
+ prompts.each do |prompt|
62
+ resp = @prompt.ask(prompt.prompt)
63
+ answers[prompt.var] = resp
64
+ end
65
+
66
+ answers
67
+ end
68
+
69
+ ##
70
+ # Determines whether to skip a step
71
+ #
72
+ # @param [GeneSystem::Step] step
73
+ # @param [GeneSystem::Platform] platform
74
+ #
75
+ # @return [Boolean]
76
+ #
77
+ def skip?(step, platform)
78
+ return false if step.remove.skip.nil?
79
+
80
+ platform.execute_command(
81
+ step.remove.skip
82
+ ).zero?
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,14 @@
1
+ require 'tty-prompt'
2
+ require 'gene_system'
3
+
4
+ COMMANDS = File.join(__dir__, 'commands', '*.rb')
5
+
6
+ Dir[COMMANDS].sort.each do |file|
7
+ require file
8
+ end
9
+
10
+ module GeneSystem
11
+ # Gem command module
12
+ module Commands
13
+ end
14
+ end
@@ -45,7 +45,7 @@ module GeneSystem
45
45
  # @param [String] path
46
46
  #
47
47
  def render_empty_manifest(name, path)
48
- manifest_path = File.join(path, "#{name}.json")
48
+ manifest_path = File.join(path, name)
49
49
 
50
50
  File.open(manifest_path, 'w') do |f|
51
51
  f.write(