pragmater 7.0.0 → 8.1.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.
@@ -1,9 +1,10 @@
1
1
  #! /usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
+ # TODO: Remove once the Pattern Matching feature is fully supported.
5
+ Warning[:experimental] = false
6
+
4
7
  require "pragmater"
5
- require "pragmater/cli"
6
- require "pragmater/identity"
7
8
 
8
- Process.setproctitle Pragmater::Identity.version_label
9
- Pragmater::CLI.start
9
+ Process.setproctitle Pragmater::Identity::VERSION_LABEL
10
+ Pragmater::CLI::Shell.new.call ARGV
@@ -1,8 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "pragmater/identity"
4
- require "pragmater/formatter"
5
- require "pragmater/commenter"
6
- require "pragmater/writer"
4
+ require "pragmater/formatters/general"
5
+ require "pragmater/formatters/shebang"
6
+ require "pragmater/formatters/main"
7
+ require "pragmater/parsers/comments"
8
+ require "pragmater/parsers/file"
9
+ require "pragmater/processors/inserter"
10
+ require "pragmater/processors/remover"
11
+ require "pragmater/processors/handler"
12
+ require "pragmater/context"
7
13
  require "pragmater/runner"
8
- require "pragmater/cli"
14
+ require "pragmater/cli/options/configuration"
15
+ require "pragmater/cli/options/insert_remove"
16
+ require "pragmater/cli/options/core"
17
+ require "pragmater/cli/options/assembler"
18
+ require "pragmater/cli/options/merger"
19
+ require "pragmater/cli/helper"
20
+ require "pragmater/cli/shell"
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+ require "open3"
5
+ require "logger"
6
+
7
+ module Pragmater
8
+ module CLI
9
+ # A simple delegator for common shell functionality.
10
+ class Helper
11
+ extend Forwardable
12
+
13
+ LOGGER = Logger.new STDOUT,
14
+ formatter: (
15
+ proc do |_severity, _datetime, _program_name, message|
16
+ "#{message}\n"
17
+ end
18
+ )
19
+
20
+ delegate %i[info error fatal debug unknown] => :logger
21
+
22
+ def initialize commander: Open3, logger: LOGGER
23
+ @commander = commander
24
+ @logger = logger
25
+ end
26
+
27
+ def run command
28
+ commander.capture3 command
29
+ end
30
+
31
+ def warn message
32
+ logger.warn message
33
+ end
34
+
35
+ private
36
+
37
+ attr_reader :commander, :logger
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "optparse"
4
+ require "forwardable"
5
+
6
+ module Pragmater
7
+ module CLI
8
+ module Options
9
+ # Coalesces all options and arguments into a single hash for further processing.
10
+ class Assembler
11
+ extend Forwardable
12
+
13
+ PARSER = OptionParser.new nil, 40, " "
14
+ SECTIONS = [Core, InsertRemove, Configuration].freeze
15
+
16
+ EXCEPTIONS = [
17
+ OptionParser::InvalidOption,
18
+ OptionParser::MissingArgument,
19
+ OptionParser::InvalidArgument
20
+ ].freeze
21
+
22
+ delegate %i[to_s] => :parser
23
+
24
+ def initialize sections: SECTIONS, parser: PARSER, exceptions: EXCEPTIONS
25
+ @sections = sections
26
+ @parser = parser
27
+ @options = {}
28
+ @exceptions = exceptions
29
+ end
30
+
31
+ def call arguments = []
32
+ sections.each { |section| section.new(options, parser: parser).call }
33
+ parser.parse! arguments
34
+ options
35
+ rescue *EXCEPTIONS
36
+ {}
37
+ end
38
+
39
+ private
40
+
41
+ attr_reader :parser, :sections, :options, :exceptions
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pragmater
4
+ module CLI
5
+ module Options
6
+ # Defines gem configuration options.
7
+ class Configuration
8
+ def initialize values, parser: OptionParser.new
9
+ @parser = parser
10
+ @values = values
11
+ end
12
+
13
+ def call
14
+ parser.separator "\nConfiguration:\n"
15
+ private_methods.grep(/add_/).each(&method(:__send__))
16
+ parser
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :parser, :values
22
+
23
+ def add_edit
24
+ parser.on "--edit", "Edit configuration." do
25
+ values[:edit] = true
26
+ end
27
+ end
28
+
29
+ def add_info
30
+ parser.on "--info", "Print configuration." do
31
+ values[:info] = true
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pragmater
4
+ module CLI
5
+ module Options
6
+ # Defines gem primary options.
7
+ class Core
8
+ def initialize values, parser: OptionParser.new
9
+ @values = values
10
+ @parser = parser
11
+ end
12
+
13
+ def call
14
+ parser.banner = "#{Identity::LABEL} - #{Identity::SUMMARY}"
15
+ parser.separator "\nUSAGE:\n"
16
+ private_methods.grep(/add_/).each(&method(:__send__))
17
+ parser
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :values, :parser
23
+
24
+ def add_configuration
25
+ parser.on "-c", "--config [options]", "Manage gem configuration." do
26
+ values[:config] = true
27
+ end
28
+ end
29
+
30
+ def add_insert
31
+ parser.on "-i", "--insert [PATH]", "Insert pragam comments into files." do |path|
32
+ values[:insert] = path || "."
33
+ end
34
+ end
35
+
36
+ def add_remove
37
+ parser.on "-r", "--remove [options]", "Remove pragam comments from files." do |path|
38
+ values[:remove] = path || "."
39
+ end
40
+ end
41
+
42
+ def add_version
43
+ parser.on "-v", "--version", "Show gem version." do
44
+ values[:version] = Identity::VERSION
45
+ end
46
+ end
47
+
48
+ def add_help
49
+ parser.on "-h", "--help", "Show this message." do
50
+ values[:help] = true
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,6 @@
1
+ :insert:
2
+ :comments: []
3
+ :includes: []
4
+ :remove:
5
+ :comments: []
6
+ :includes: []
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pragmater
4
+ module CLI
5
+ module Options
6
+ # Defines gem insert and remove options.
7
+ class InsertRemove
8
+ def initialize values, parser: OptionParser.new
9
+ @values = values
10
+ @parser = parser
11
+ end
12
+
13
+ def call
14
+ parser.separator "\nOPTIONS:\n"
15
+ parser.separator "\nInsert/Remove:\n"
16
+ private_methods.grep(/add_/).each(&method(:__send__))
17
+ parser
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :values, :parser
23
+
24
+ def add_comments
25
+ parser.on "--comments a,b,c", Array, "Add pragma comments." do |comments|
26
+ values[:comments] = comments
27
+ end
28
+ end
29
+
30
+ def add_includes
31
+ parser.on "--includes a,b,c", Array, "Add console support." do |includes|
32
+ values[:includes] = includes
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+ require "pathname"
5
+ require "runcom"
6
+
7
+ module Pragmater
8
+ module CLI
9
+ module Options
10
+ # Merges arguments with configuration for fully assembled configuration for use by shell.
11
+ class Merger
12
+ DEFAULTS = YAML.load_file(Pathname(__dir__).join("defaults.yml")).freeze
13
+ CONFIGURATION = Runcom::Config.new "#{Identity::NAME}/configuration.yml", defaults: DEFAULTS
14
+
15
+ def initialize configuration = CONFIGURATION, assembler = Assembler.new
16
+ @configuration = configuration
17
+ @assembler = assembler
18
+ end
19
+
20
+ def call arguments = []
21
+ assembler.call(arguments).then do |options|
22
+ case options
23
+ in insert: path, **settings then build_insert_options path, settings
24
+ in remove: path, **settings then build_remove_options path, settings
25
+ else options
26
+ end
27
+ end
28
+ end
29
+
30
+ def configuration_path
31
+ configuration.current
32
+ end
33
+
34
+ def usage
35
+ assembler.to_s
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :configuration, :assembler
41
+
42
+ def build_insert_options path, options
43
+ {insert: path, **configuration.to_h.fetch(:insert).merge(options)}
44
+ end
45
+
46
+ def build_remove_options path, options
47
+ {remove: path, **configuration.to_h.fetch(:remove).merge(options)}
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pragmater
4
+ module CLI
5
+ # The command line interface for this gem.
6
+ class Shell
7
+ def initialize merger: Options::Merger.new, runner: Runner, helper: Helper.new
8
+ @merger = merger
9
+ @runner = runner
10
+ @helper = helper
11
+ end
12
+
13
+ def call arguments = []
14
+ case merger.call arguments
15
+ in insert: path, **options then insert_pragmas options, path
16
+ in remove: path, **options then remove_pragmas options, path
17
+ in config:, edit:, **remainder then edit_configuration
18
+ in config:, info:, **remainder then print_configuration
19
+ in version:, **remainder then print_version
20
+ in help:, **remainder then print_usage
21
+ else print_usage
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :merger, :runner, :helper
28
+
29
+ def insert_pragmas options, path
30
+ runner.for(**options.merge(action: :insert, root_dir: path))
31
+ .call
32
+ .map { |file| helper.info "Processed: #{file}." }
33
+ end
34
+
35
+ def remove_pragmas options, path
36
+ runner.for(**options.merge(action: :remove, root_dir: path))
37
+ .call
38
+ .map { |file| helper.info "Processed: #{file}." }
39
+ end
40
+
41
+ def edit_configuration
42
+ helper.run "#{ENV["EDITOR"]} #{merger.configuration_path}"
43
+ end
44
+
45
+ def print_configuration
46
+ merger.configuration_path.then do |path|
47
+ return helper.info "No configuration found." unless path
48
+
49
+ helper.info "#{path}\n"
50
+ helper.info path.read
51
+ end
52
+ end
53
+
54
+ def print_version
55
+ helper.info Identity::VERSION_LABEL
56
+ end
57
+
58
+ def print_usage
59
+ helper.info merger.usage
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pragmater
4
+ # Provides context for runner.
5
+ Context = Struct.new :action, :root_dir, :comments, :includes, keyword_init: true do
6
+ def initialize *arguments
7
+ super
8
+
9
+ self[:root_dir] ||= "."
10
+ self[:comments] = Array comments
11
+ self[:includes] = Array includes
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pragmater
4
+ module Formatters
5
+ # Formats general pragmas in a consistent manner.
6
+ class General
7
+ PATTERN = /
8
+ \A # Start of line.
9
+ \# # Start of comment.
10
+ \s? # Space - optional.
11
+ \w+ # Key - One or more word characters only.
12
+ : # Delimiter.
13
+ \s? # Space - optional.
14
+ [\w-]+ # Value - One or more word or dash characters.
15
+ \Z # End of line.
16
+ /x.freeze
17
+
18
+ def initialize string, pattern: PATTERN
19
+ @string = string
20
+ @pattern = pattern
21
+ end
22
+
23
+ def call
24
+ return string unless string.match? pattern
25
+
26
+ string.split(":").then { |key, value| "# #{key.gsub(/\#\s?/, "")}: #{value.strip}" }
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :string, :pattern
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pragmater
4
+ module Formatters
5
+ # Formats all pragmas in a consistent manner.
6
+ class Main
7
+ FORMATTERS = [General, Shebang].freeze
8
+ PATTERN = FORMATTERS.map { |formatter| formatter::PATTERN }
9
+ .then { |patterns| Regexp.union(*patterns) }
10
+ .freeze
11
+
12
+ def initialize string, formatters: FORMATTERS
13
+ @string = string
14
+ @formatters = formatters
15
+ end
16
+
17
+ def call
18
+ formatters.reduce(string) { |pragma, formatter| formatter.new(pragma).call }
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :string, :formatters
24
+ end
25
+ end
26
+ end