reviewer 0.1.0 → 0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: df101aff2f6774a051ec434d758d2a1b9f81366a5c6747ba524dfb711ada5d46
4
- data.tar.gz: 76646cdd12c3ee0c280cbf1dec32745555a18f4a892fc8f10322f6795cf9a22b
3
+ metadata.gz: a5df0f3247eb105862f40b5092bb3c3b25fa20e87e155cb283fc2fd278933987
4
+ data.tar.gz: 06716646a5f980c5d67f89abc4ab4938977c2dd2691101d8cdd924f4481599cf
5
5
  SHA512:
6
- metadata.gz: 28dbb56742a1ddee23e17ff5792bf66bd53cb38d9ebf8e3d00c9a343b92ee6ace22ff19568e123bc01e865d16126dbf4004d12826c0e3b28754a7541e909c3d1
7
- data.tar.gz: b4ee814b4c07a1501000193ba593ca5a5ee06d41954b7bb397174947da26b01c22a45edc56482229b325ff7396ec29ce9c9e8759edf4caaa5dca0405ce16e959
6
+ metadata.gz: 57ca3df253ec35a5544f9a2145733c535688f8be8f0ed6820973563f758563e08a6f3aa729e8743be49945d931cc63a27a21a75e4512d2f9855f1ecad055a9ac
7
+ data.tar.gz: 5b06953f74f63aff8410b27470a37044d764b87b07289554d0ddc3581575d8a6849603a78f656d392273ac6e4d3d358acd91a84cae49a7d49fd427800536d5cb
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  ## [Unreleased]
2
2
 
3
+ - TODO: Add Runner to handle timing, logging, and exit status
4
+ - TODO: Add Targets to handle targeting specific files
5
+ - TODO: Add support for Targets in Tool/Command generator
6
+
7
+ ## [0.1.1] - 2021-04-17
8
+
9
+ It doesn't work just yet, but it's filling out. Primarily, this enables it to parse the configuration file and turn each tool's settings into a runnable command string for install, prepare, review, and format.
10
+
11
+ - Added Configuration Management
12
+ - Added command-line framework with option parsing
13
+ - Created configuration loading bits
14
+ - Built pieces to generate complete command strings
15
+
3
16
  ## [0.1.0] - 2021-04-16
4
17
 
5
18
  - Initial release
data/Gemfile.lock ADDED
@@ -0,0 +1,36 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ reviewer (0.1.1)
5
+ activesupport
6
+ slop
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activesupport (6.1.3.1)
12
+ concurrent-ruby (~> 1.0, >= 1.0.2)
13
+ i18n (>= 1.6, < 2)
14
+ minitest (>= 5.1)
15
+ tzinfo (~> 2.0)
16
+ zeitwerk (~> 2.3)
17
+ concurrent-ruby (1.1.8)
18
+ i18n (1.8.10)
19
+ concurrent-ruby (~> 1.0)
20
+ minitest (5.14.4)
21
+ rake (13.0.3)
22
+ slop (4.8.2)
23
+ tzinfo (2.0.4)
24
+ concurrent-ruby (~> 1.0)
25
+ zeitwerk (2.4.2)
26
+
27
+ PLATFORMS
28
+ x86_64-darwin-19
29
+
30
+ DEPENDENCIES
31
+ minitest (~> 5.0)
32
+ rake (~> 13.0)
33
+ reviewer!
34
+
35
+ BUNDLED WITH
36
+ 2.2.16
data/bin/review ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/reviewer'
4
+
5
+ Reviewer.review
data/lib/reviewer.rb CHANGED
@@ -1,8 +1,42 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "reviewer/arguments"
4
+ require_relative "reviewer/configuration"
5
+ require_relative "reviewer/loader"
6
+ require_relative "reviewer/tool"
7
+ require_relative "reviewer/tools"
3
8
  require_relative "reviewer/version"
4
9
 
5
10
  module Reviewer
6
11
  class Error < StandardError; end
7
- # Your code goes here...
12
+
13
+ class << self
14
+ attr_writer :configuration
15
+ end
16
+
17
+ def self.review
18
+ options = Arguments.new
19
+ # TODO: Make it actually run the tools.
20
+ puts "Running with the following options:"
21
+ pp options
22
+ end
23
+
24
+ def self.format
25
+ options = Arguments.new
26
+ # TODO: Make it actually run the tools.
27
+ puts "Running with the following options:"
28
+ pp options
29
+ end
30
+
31
+ def self.configuration
32
+ @configuration ||= Configuration.new
33
+ end
34
+
35
+ def self.reset
36
+ @configuration = Configuration.new
37
+ end
38
+
39
+ def self.configure
40
+ yield(configuration)
41
+ end
8
42
  end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'slop'
4
+
5
+ # Handles option parsing for bin/review
6
+ module Reviewer
7
+ class Arguments
8
+ attr_accessor :options
9
+
10
+ def initialize(options = ARGV)
11
+ @options = Slop.parse options do |opts|
12
+ opts.array '-f', '--files', 'a list of comma-separated files or paths', delimiter: ',', default: []
13
+ opts.array '-t', '--tags', 'a list of comma-separated tags', delimiter: ',', default: []
14
+
15
+ opts.on '-v', '--version', 'print the version' do
16
+ puts VERSION
17
+ exit
18
+ end
19
+
20
+ opts.on '-h', '--help', 'print the help' do
21
+ puts opts
22
+ exit
23
+ end
24
+ end
25
+ end
26
+
27
+ def files
28
+ options[:files]
29
+ end
30
+
31
+ def tags
32
+ options[:tags]
33
+ end
34
+
35
+ def arguments
36
+ options.arguments
37
+ end
38
+
39
+ def keywords
40
+ # TODO: Filter arguments to only for allowed keywords to be defined later.
41
+ arguments
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Reviewer
4
+ class Configuration
5
+ DEFAULT_CONFIGURATION_PATH = Dir.pwd.freeze
6
+ DEFAULT_CONFIGURATION_FILE = '.reviewer.yml'.freeze
7
+
8
+ attr_accessor :file
9
+
10
+ def initialize
11
+ @file = "#{DEFAULT_CONFIGURATION_PATH}/#{DEFAULT_CONFIGURATION_FILE}"
12
+ end
13
+
14
+ def tools
15
+ @tools ||= Loader.new.to_h
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+ require "active_support/core_ext/hash/indifferent_access"
5
+
6
+ # Provides a collection of the configured tools
7
+ module Reviewer
8
+ class Loader
9
+ class MissingConfigurationError < StandardError; end
10
+ class InvalidConfigurationError < StandardError; end
11
+
12
+ attr_reader :configuration
13
+
14
+ def initialize
15
+ @configuration = HashWithIndifferentAccess.new(configuration_hash)
16
+ end
17
+
18
+ def to_h
19
+ configuration
20
+ end
21
+
22
+ private
23
+
24
+ def configuration_hash
25
+ @configuration_hash ||= YAML.load_file(Reviewer.configuration.file)
26
+ rescue Errno::ENOENT
27
+ raise MissingConfigurationError, "Tools configuration file couldn't be found - #{Reviewer.configuration.file}"
28
+ rescue Psych::SyntaxError => e
29
+ raise InvalidConfigurationError, "Tools configuration file has a syntax error - #{e.message}"
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/string"
4
+ require_relative "tool/command"
5
+ require_relative "tool/env"
6
+ require_relative "tool/flags"
7
+ require_relative "tool/settings"
8
+ require_relative "tool/verbosity"
9
+
10
+ # Provides an instance of a specific tool
11
+ module Reviewer
12
+ class Tool
13
+ attr_reader :settings
14
+
15
+ def initialize(tool)
16
+ @settings = Settings.new(tool)
17
+ end
18
+
19
+ def installation_command(verbosity_level = :no_silence)
20
+ command_string(:install, verbosity_level: verbosity_level)
21
+ end
22
+
23
+ def preparation_command(verbosity_level = :no_silence)
24
+ command_string(:prepare, verbosity_level: verbosity_level)
25
+ end
26
+
27
+ def review_command(verbosity_level = :total_silence)
28
+ command_string(:review, verbosity_level: verbosity_level)
29
+ end
30
+
31
+ def format_command(verbosity_level = :no_silence)
32
+ command_string(:format, verbosity_level: verbosity_level)
33
+ end
34
+
35
+
36
+ private
37
+
38
+ def command_string(command_type, verbosity_level: :no_silence)
39
+ cmd = Command.new(command_type, tool_settings: settings, verbosity_level: verbosity_level)
40
+
41
+ cmd.to_s
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Assembles tool tool_settings into a usable command string
4
+ module Reviewer
5
+ class Tool
6
+ class Command
7
+ class InvalidTypeError < StandardError; end
8
+ class NotConfiguredError < StandardError; end
9
+
10
+ TYPES = %i[install prepare review format].freeze
11
+
12
+ attr_reader :command_type, :tool_settings, :verbosity_level
13
+
14
+ def initialize(command_type, tool_settings:, verbosity_level: nil)
15
+ @command_type = command_type
16
+ @tool_settings = tool_settings
17
+ @verbosity_level = verbosity_level
18
+
19
+ verify_command_type!
20
+ end
21
+
22
+ def to_s
23
+ to_a
24
+ .map(&:strip)
25
+ .join(' ')
26
+ .strip
27
+ end
28
+
29
+ def to_a
30
+ [
31
+ env,
32
+ body,
33
+ flags,
34
+ verbosity
35
+ ].compact
36
+ end
37
+
38
+ def env
39
+ Env.new(tool_settings.env).to_s
40
+ end
41
+
42
+ def body
43
+ tool_settings.commands.fetch(command_type)
44
+ end
45
+
46
+ def flags
47
+ # :review commands are the only commands that use flags (except the :quiet_flag)
48
+ return nil unless review?
49
+
50
+ Flags.new(tool_settings.flags).to_s
51
+ end
52
+
53
+ def verbosity
54
+ Verbosity.new(tool_settings.quiet_flag, level: verbosity_level).to_s
55
+ end
56
+
57
+
58
+ private
59
+
60
+ def review?
61
+ command_type == :review
62
+ end
63
+
64
+ def valid_command?
65
+ TYPES.include?(command_type)
66
+ end
67
+
68
+ def command_defined?
69
+ tool_settings.commands.key?(command_type)
70
+ end
71
+
72
+ def verify_command_type!
73
+ raise InvalidTypeError, "'#{body}' is not a supported command type. (Make sure it's not a typo.)" unless valid_command?
74
+ raise NotConfiguredError, "The '#{body}' command is not configured for #{tool_settings.name}. (Make sure it's not a typo.)" unless command_defined?
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Assembles tool environment variables into a single string or array
4
+ module Reviewer
5
+ class Tool
6
+ class Env
7
+ attr_reader :env_pairs
8
+
9
+ def initialize(env_pairs)
10
+ @env_pairs = env_pairs
11
+ end
12
+
13
+ def to_s
14
+ to_a.compact.join(' ')
15
+ end
16
+
17
+ def to_a
18
+ env = []
19
+ env_pairs.each { |key, value| env << env(key, value) }
20
+ env
21
+ end
22
+
23
+
24
+ private
25
+
26
+ def env(key, value)
27
+ return nil if key.to_s.blank? || value.to_s.blank?
28
+
29
+ value = needs_quotes?(value) ? "'#{value}'" : value
30
+
31
+ "#{key.to_s.strip.upcase}=#{value.to_s.strip};"
32
+ end
33
+
34
+ def needs_quotes?(value)
35
+ value.is_a?(String) && value.include?(' ')
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Assembles tool flag settings into a single string or array
4
+ module Reviewer
5
+ class Tool
6
+ class Flags
7
+ attr_reader :flag_pairs
8
+
9
+ def initialize(flag_pairs)
10
+ @flag_pairs = flag_pairs
11
+ end
12
+
13
+ def to_s
14
+ to_a.join(' ')
15
+ end
16
+
17
+ def to_a
18
+ flags = []
19
+ flag_pairs.each { |key, value| flags << flag(key, value) }
20
+ flags
21
+ end
22
+
23
+
24
+ private
25
+
26
+ def flag(key, value)
27
+ dash = key.to_s.size == 1 ? '-' : '--'
28
+
29
+ value = needs_quotes?(value) ? "'#{value}'" : value
30
+
31
+ "#{dash}#{key} #{value}".strip
32
+ end
33
+
34
+ def needs_quotes?(value)
35
+ value.is_a?(String) && value.include?(' ')
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Converts/casts tool configuration values and provides default values if not set
4
+ module Reviewer
5
+ class Tool
6
+ class Settings
7
+ class MissingReviewCommandError < StandardError; end
8
+
9
+ attr_reader :tool, :config
10
+
11
+ def initialize(tool, config: nil)
12
+ @tool = tool
13
+ @config = config || Reviewer.configuration.tools.fetch(tool.to_sym) { {} }
14
+
15
+ # Ideally, folks would fill out everything, but realistically, the 'review' command is the only required value.
16
+ # If the key is missing, or maybe there was a typo, fail right away.
17
+ raise MissingReviewCommandError, "'#{name}' does not have a 'review' key under 'commands' in your tools configuration" unless commands.key?(:review)
18
+ end
19
+
20
+ def disabled?
21
+ config.fetch(:disabled) { false }
22
+ end
23
+
24
+ def enabled?
25
+ !disabled?
26
+ end
27
+
28
+ def key
29
+ tool.to_sym
30
+ end
31
+
32
+ def name
33
+ config.fetch(:name) { tool.to_s.titleize }
34
+ end
35
+
36
+ def description
37
+ config.fetch(:description) { "(No description provided for '#{name}')" }
38
+ end
39
+
40
+ def tags
41
+ config.fetch(:tags) { [] }
42
+ end
43
+
44
+ def links
45
+ config.fetch(:links) { {} }
46
+ end
47
+
48
+ def env
49
+ config.fetch(:env) { {} }
50
+ end
51
+
52
+ def flags
53
+ config.fetch(:flags) { {} }
54
+ end
55
+
56
+ def commands
57
+ config.fetch(:commands) { {} }
58
+ end
59
+
60
+ def max_exit_status
61
+ commands.fetch(:max_exit_status) { 0 }
62
+ end
63
+
64
+ def quiet_flag
65
+ commands.fetch(:quiet_flag) { '' }
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Assembles tool settings and provided context for silencing output
4
+ module Reviewer
5
+ class Tool
6
+ class Verbosity
7
+ class InvalidLevelError < StandardError; end
8
+ # :total_silence = Use the quiet flag and send everything to dev/null.
9
+ # For some tools "quiet" means "less noisy" rather than truly silent.
10
+ # So in those cases, dev/null handles lingering noise.
11
+ # :tool_silence = Just the quiet flag
12
+ # :no_silence = Let the output scroll for eternity
13
+ LEVELS = %i[total_silence tool_silence no_silence].freeze
14
+ SEND_TO_DEV_NULL = "> /dev/null".freeze
15
+
16
+ attr_reader :flag, :level
17
+
18
+ def initialize(flag, level: :total_silence)
19
+ @flag = flag
20
+
21
+ raise InvalidLevelError, "Invalid Verbosity Level: '#{level}'" unless LEVELS.include?(level)
22
+
23
+ @level = level
24
+ end
25
+
26
+ def to_s
27
+ to_a.join(' ').strip
28
+ end
29
+
30
+ def to_a
31
+ case level
32
+ when :total_silence then [flag, SEND_TO_DEV_NULL].compact
33
+ when :tool_silence then [flag].compact
34
+ when :no_silence then []
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Provides a collection of the configured tools
4
+ module Reviewer
5
+ module Tools
6
+ def self.all
7
+ []
8
+ end
9
+
10
+ def self.enabled
11
+ []
12
+ end
13
+
14
+ def self.disabled
15
+ []
16
+ end
17
+ end
18
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Reviewer
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
data/reviewer.gemspec CHANGED
@@ -28,7 +28,8 @@ Gem::Specification.new do |spec|
28
28
  spec.require_paths = ["lib"]
29
29
 
30
30
  # Uncomment to register a new dependency of your gem
31
- # spec.add_dependency "example-gem", "~> 1.0"
31
+ spec.add_dependency "activesupport"
32
+ spec.add_dependency "slop"
32
33
 
33
34
  # For more information and examples about making a new gem, checkout our
34
35
  # guide at: https://bundler.io/guides/creating_gem.html
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reviewer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garrett Dimon
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-04-16 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2021-04-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: slop
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
13
41
  description: Provides a unified approach to managing automated code quality tools.
14
42
  email:
15
43
  - email@garrettdimon.com
@@ -22,12 +50,24 @@ files:
22
50
  - CHANGELOG.md
23
51
  - CODE_OF_CONDUCT.md
24
52
  - Gemfile
53
+ - Gemfile.lock
25
54
  - LICENSE.txt
26
55
  - README.md
27
56
  - Rakefile
28
57
  - bin/console
58
+ - bin/review
29
59
  - bin/setup
30
60
  - lib/reviewer.rb
61
+ - lib/reviewer/arguments.rb
62
+ - lib/reviewer/configuration.rb
63
+ - lib/reviewer/loader.rb
64
+ - lib/reviewer/tool.rb
65
+ - lib/reviewer/tool/command.rb
66
+ - lib/reviewer/tool/env.rb
67
+ - lib/reviewer/tool/flags.rb
68
+ - lib/reviewer/tool/settings.rb
69
+ - lib/reviewer/tool/verbosity.rb
70
+ - lib/reviewer/tools.rb
31
71
  - lib/reviewer/version.rb
32
72
  - reviewer.gemspec
33
73
  homepage: https://github.com/garrettdimon/reviewer