gene_system 0.3.2 → 0.4.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: 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(