pragmater 9.3.0 → 10.2.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.
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "optparse"
4
+
5
+ module Pragmater
6
+ module CLI
7
+ # Assembles and parses all Command Line Interface (CLI) options.
8
+ class Parser
9
+ CLIENT = OptionParser.new nil, 40, " "
10
+ SECTIONS = [Parsers::Core, Parsers::Flag].freeze # Order is important.
11
+
12
+ def initialize sections: SECTIONS, client: CLIENT, container: Container
13
+ @sections = sections
14
+ @client = client
15
+ @configuration = container[:configuration].dup
16
+ end
17
+
18
+ def call arguments = []
19
+ sections.each { |section| section.call configuration, client: }
20
+ client.parse arguments
21
+ configuration.freeze
22
+ end
23
+
24
+ def to_s = client.to_s
25
+
26
+ private
27
+
28
+ attr_reader :sections, :client, :configuration
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "refinements/structs"
4
+
5
+ module Pragmater
6
+ module CLI
7
+ module Parsers
8
+ # Handles parsing of Command Line Interface (CLI) core options.
9
+ class Core
10
+ using Refinements::Structs
11
+
12
+ def self.call(...) = new(...).call
13
+
14
+ def initialize configuration = Container[:configuration],
15
+ client: Parser::CLIENT,
16
+ container: Container
17
+ @configuration = configuration
18
+ @client = client
19
+ @container = container
20
+ end
21
+
22
+ def call arguments = []
23
+ client.banner = specification.labeled_summary
24
+ client.separator "\nUSAGE:\n"
25
+ collate
26
+ client.parse arguments
27
+ configuration
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :configuration, :client, :container
33
+
34
+ def collate = private_methods.sort.grep(/add_/).each { |method| __send__ method }
35
+
36
+ def add_config
37
+ client.on "-c",
38
+ "--config ACTION",
39
+ %i[edit view],
40
+ "Manage gem configuration: edit or view." do |action|
41
+ configuration.merge! action_config: action
42
+ end
43
+ end
44
+
45
+ def add_insert
46
+ client.on "-i", "--insert [PATH]", %(Insert pragmas. Default: "#{root_dir}".) do |path|
47
+ configuration.merge! action_insert: true, root_dir: path || root_dir
48
+ end
49
+ end
50
+
51
+ def add_remove
52
+ client.on "-r", "--remove [PATH]", %(Remove pragmas. Default: "#{root_dir}".) do |path|
53
+ configuration.merge! action_remove: true, root_dir: path || root_dir
54
+ end
55
+ end
56
+
57
+ def add_version
58
+ client.on "-v", "--version", "Show gem version." do
59
+ configuration.merge! action_version: true
60
+ end
61
+ end
62
+
63
+ def add_help
64
+ client.on "-h", "--help", "Show this message." do
65
+ configuration.merge! action_help: true
66
+ end
67
+ end
68
+
69
+ def root_dir = configuration.root_dir
70
+
71
+ def specification = container[__method__]
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "refinements/structs"
4
+
5
+ module Pragmater
6
+ module CLI
7
+ module Parsers
8
+ # Parses common command line flags.
9
+ class Flag
10
+ using Refinements::Structs
11
+
12
+ def self.call(...) = new(...).call
13
+
14
+ def initialize configuration = Container[:configuration], client: Parser::CLIENT
15
+ @configuration = configuration
16
+ @client = client
17
+ end
18
+
19
+ def call arguments = []
20
+ client.separator "\nOPTIONS:\n"
21
+ collate
22
+ client.parse arguments
23
+ configuration
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :configuration, :client
29
+
30
+ def collate = private_methods.sort.grep(/add_/).each { |method| __send__ method }
31
+
32
+ def add_comments
33
+ client.on "--comments a,b,c", Array, "Add pragma comments. Default: []." do |comments|
34
+ configuration.merge! comments:
35
+ end
36
+ end
37
+
38
+ def add_includes
39
+ client.on "--includes a,b,c", Array, "Add include patterns. Default: []." do |includes|
40
+ configuration.merge! includes:
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -2,61 +2,44 @@
2
2
 
3
3
  module Pragmater
4
4
  module CLI
5
- # The command line interface for this gem.
5
+ # The main Command Line Interface (CLI) object.
6
6
  class Shell
7
- def initialize merger: Options::Merger.new, runner: Runner, helper: Helper.new
8
- @merger = merger
9
- @runner = runner
10
- @helper = helper
7
+ ACTIONS = {config: Actions::Config.new, run: Actions::Run.new}.freeze
8
+
9
+ def initialize parser: Parser.new, actions: ACTIONS, container: Container
10
+ @parser = parser
11
+ @actions = actions
12
+ @container = container
11
13
  end
12
14
 
13
15
  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
- else print_usage
21
- end
16
+ perform parser.call(arguments)
17
+ rescue OptionParser::ParseError => error
18
+ logger.error { error.message }
22
19
  end
23
20
 
24
21
  private
25
22
 
26
- attr_reader :merger, :runner, :helper
23
+ attr_reader :parser, :actions, :container
27
24
 
28
- def insert_pragmas options, path
29
- runner.for(**options.merge(action: :insert, root_dir: path))
30
- .call
31
- .map { |file| helper.info "Processed: #{file}." }
32
- end
33
-
34
- def remove_pragmas options, path
35
- runner.for(**options.merge(action: :remove, root_dir: path))
36
- .call
37
- .map { |file| helper.info "Processed: #{file}." }
25
+ def perform configuration
26
+ case configuration
27
+ in action_config: Symbol => action then config action
28
+ in {action_insert: true} | {action_remove: true} then run configuration
29
+ in action_version: true then logger.info { specification.labeled_version }
30
+ else usage
31
+ end
38
32
  end
39
33
 
40
- def edit_configuration
41
- helper.run "#{ENV["EDITOR"]} #{merger.configuration_path}"
42
- end
34
+ def config(action) = actions.fetch(__method__).call(action)
43
35
 
44
- def print_configuration
45
- merger.configuration_path.then do |path|
46
- return helper.info "No configuration found." unless path
36
+ def run(configuration) = actions.fetch(__method__).call(configuration)
47
37
 
48
- helper.info "#{path}\n"
49
- helper.info path.read
50
- end
51
- end
38
+ def usage = logger.unknown(parser.to_s)
52
39
 
53
- def print_version
54
- helper.info Identity::VERSION_LABEL
55
- end
40
+ def specification = container[__method__]
56
41
 
57
- def print_usage
58
- helper.info merger.usage
59
- end
42
+ def logger = container[__method__]
60
43
  end
61
44
  end
62
45
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pragmater
4
+ module Configuration
5
+ # Defines the content of the configuration for use throughout the gem.
6
+ Content = Struct.new(
7
+ :action_config,
8
+ :action_help,
9
+ :action_insert,
10
+ :action_remove,
11
+ :action_version,
12
+ :comments,
13
+ :includes,
14
+ :root_dir,
15
+ keyword_init: true
16
+ ) do
17
+ def initialize *arguments
18
+ super
19
+ freeze
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ :comments: []
2
+ :includes: []
3
+ :root_dir: "."
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
4
+ require "refinements/hashes"
5
+ require "refinements/structs"
6
+ require "runcom"
7
+ require "yaml"
8
+
9
+ module Pragmater
10
+ module Configuration
11
+ # Represents the fully assembled Command Line Interface (CLI) configuration.
12
+ class Loader
13
+ using Refinements::Hashes
14
+ using Refinements::Structs
15
+
16
+ DEFAULTS = YAML.load_file(Pathname(__dir__).join("defaults.yml")).freeze
17
+ CLIENT = Runcom::Config.new "pragmater/configuration.yml", defaults: DEFAULTS
18
+
19
+ def self.call = new.call
20
+
21
+ def self.with_defaults = new(client: DEFAULTS)
22
+
23
+ def initialize content: Content.new, client: CLIENT
24
+ @content = content
25
+ @client = client
26
+ end
27
+
28
+ def call = content.merge(**client.to_h.flatten_keys)
29
+
30
+ private
31
+
32
+ attr_reader :content, :client
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry-container"
4
+ require "logger"
5
+ require "pastel"
6
+ require "spek"
7
+
8
+ module Pragmater
9
+ # Provides a global gem container for injection into other objects.
10
+ module Container
11
+ extend Dry::Container::Mixin
12
+
13
+ register(:configuration) { Configuration::Loader.call }
14
+ register(:specification) { Spek::Loader.call "#{__dir__}/../../pragmater.gemspec" }
15
+ register(:colorizer) { Pastel.new enabled: $stdout.tty? }
16
+ register(:kernel) { Kernel }
17
+
18
+ register :log_colors do
19
+ {
20
+ "DEBUG" => self[:colorizer].white.detach,
21
+ "INFO" => self[:colorizer].green.detach,
22
+ "WARN" => self[:colorizer].yellow.detach,
23
+ "ERROR" => self[:colorizer].red.detach,
24
+ "FATAL" => self[:colorizer].white.bold.on_red.detach,
25
+ "ANY" => self[:colorizer].white.bold.detach
26
+ }
27
+ end
28
+
29
+ register :logger do
30
+ Logger.new $stdout,
31
+ level: Logger.const_get(ENV.fetch("LOG_LEVEL", "INFO")),
32
+ formatter: (
33
+ lambda do |severity, _at, _name, message|
34
+ self[:log_colors][severity].call "#{message}\n"
35
+ end
36
+ )
37
+ end
38
+ end
39
+ end
@@ -5,6 +5,7 @@ module Pragmater
5
5
  # Formats all pragmas in a consistent manner.
6
6
  class Main
7
7
  FORMATTERS = [General, Shebang].freeze
8
+
8
9
  PATTERN = FORMATTERS.map { |formatter| formatter::PATTERN }
9
10
  .then { |patterns| Regexp.union(*patterns) }
10
11
  .freeze
@@ -14,9 +15,7 @@ module Pragmater
14
15
  @formatters = formatters
15
16
  end
16
17
 
17
- def call
18
- formatters.reduce(string) { |pragma, formatter| formatter.new(pragma).call }
19
- end
18
+ def call = formatters.reduce(string) { |pragma, formatter| formatter.new(pragma).call }
20
19
 
21
20
  private
22
21
 
@@ -10,21 +10,15 @@ module Pragmater
10
10
  @newer = format newer
11
11
  end
12
12
 
13
- def insert
14
- older.union newer
15
- end
13
+ def insert = older.union(newer)
16
14
 
17
- def remove
18
- older - older.intersection(newer)
19
- end
15
+ def remove = older - older.intersection(newer)
20
16
 
21
17
  private
22
18
 
23
19
  attr_reader :formatter, :older, :newer
24
20
 
25
- def format pragmas
26
- Array(pragmas).map { |pragma| formatter.new(pragma).call }
27
- end
21
+ def format(pragmas) = Array(pragmas).map { |pragma| formatter.new(pragma).call }
28
22
  end
29
23
  end
30
24
  end
@@ -10,9 +10,7 @@ module Pragmater
10
10
  @processors = processors
11
11
  end
12
12
 
13
- def call action, comments, body
14
- processors.fetch(action).new(comments, body).call
15
- end
13
+ def call(action, comments, body) = processors.fetch(action).new(comments, body).call
16
14
 
17
15
  private
18
16
 
@@ -7,23 +7,31 @@ module Pragmater
7
7
  class Runner
8
8
  using Refinements::Pathnames
9
9
 
10
- def self.for **attributes
11
- new Context[attributes]
12
- end
13
-
14
- def initialize context, parser: Parsers::File.new
15
- @context = context
10
+ def initialize parser: Parsers::File.new, container: Container
16
11
  @parser = parser
12
+ @container = container
17
13
  end
18
14
 
19
- def call
20
- Pathname(context.root_dir).files("{#{context.includes.join ","}}").map do |path|
21
- path.write parser.call(path, context.comments, action: context.action).join
15
+ def call configuration = Configuration::Loader.call
16
+ Pathname(configuration.root_dir).files("{#{configuration.includes.join ","}}").map do |path|
17
+ yield path if block_given?
18
+
19
+ case configuration
20
+ in action_insert: true then write path, configuration, :insert
21
+ in action_remove: true then write path, configuration, :remove
22
+ else logger.error { "Unknown run action. Use insert or remove." }
23
+ end
22
24
  end
23
25
  end
24
26
 
25
27
  private
26
28
 
27
- attr_reader :context, :parser
29
+ attr_reader :parser, :container
30
+
31
+ def write path, configuration, action
32
+ path.write parser.call(path, configuration.comments, action:).join
33
+ end
34
+
35
+ def logger = container[__method__]
28
36
  end
29
37
  end
data/lib/pragmater.rb CHANGED
@@ -1,20 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "pragmater/identity"
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"
13
- require "pragmater/runner"
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"
3
+ require "zeitwerk"
4
+
5
+ Zeitwerk::Loader.for_gem
6
+ .tap { |loader| loader.inflector.inflect "cli" => "CLI" }
7
+ .setup
8
+
9
+ # Main namespace.
10
+ module Pragmater
11
+ end
data/pragmater.gemspec ADDED
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "pragmater"
5
+ spec.version = "10.2.0"
6
+ spec.authors = ["Brooke Kuhlmann"]
7
+ spec.email = ["brooke@alchemists.io"]
8
+ spec.homepage = "https://www.alchemists.io/projects/pragmater"
9
+ spec.summary = "A command line interface for managing/formatting source file pragma comments."
10
+ spec.license = "Hippocratic-3.0"
11
+
12
+ spec.metadata = {
13
+ "bug_tracker_uri" => "https://github.com/bkuhlmann/pragmater/issues",
14
+ "changelog_uri" => "https://www.alchemists.io/projects/pragmater/versions",
15
+ "documentation_uri" => "https://www.alchemists.io/projects/pragmater",
16
+ "label" => "Pragmater",
17
+ "rubygems_mfa_required" => "true",
18
+ "source_code_uri" => "https://github.com/bkuhlmann/pragmater"
19
+ }
20
+
21
+ spec.signing_key = Gem.default_key_path
22
+ spec.cert_chain = [Gem.default_cert_path]
23
+
24
+ spec.required_ruby_version = "~> 3.1"
25
+ spec.add_dependency "dry-container", "~> 0.9"
26
+ spec.add_dependency "pastel", "~> 0.8"
27
+ spec.add_dependency "refinements", "~> 9.1"
28
+ spec.add_dependency "runcom", "~> 8.2"
29
+ spec.add_dependency "spek", "~> 0.0"
30
+ spec.add_dependency "zeitwerk", "~> 2.5"
31
+
32
+ spec.bindir = "exe"
33
+ spec.executables << "pragmater"
34
+ spec.extra_rdoc_files = Dir["README*", "LICENSE*"]
35
+ spec.files = Dir["*.gemspec", "lib/**/*"]
36
+ end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pragmater
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.3.0
4
+ version: 10.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brooke Kuhlmann
@@ -28,36 +28,92 @@ cert_chain:
28
28
  lkHilIrX69jq8wMPpBhlaw2mRmeSL50Wv5u6xVBvOHhXFSP1crXM95vfLhLyRYod
29
29
  W2A=
30
30
  -----END CERTIFICATE-----
31
- date: 2021-11-20 00:00:00.000000000 Z
31
+ date: 2022-02-06 00:00:00.000000000 Z
32
32
  dependencies:
33
+ - !ruby/object:Gem::Dependency
34
+ name: dry-container
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.9'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '0.9'
47
+ - !ruby/object:Gem::Dependency
48
+ name: pastel
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '0.8'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '0.8'
33
61
  - !ruby/object:Gem::Dependency
34
62
  name: refinements
35
63
  requirement: !ruby/object:Gem::Requirement
36
64
  requirements:
37
65
  - - "~>"
38
66
  - !ruby/object:Gem::Version
39
- version: '8.5'
67
+ version: '9.1'
40
68
  type: :runtime
41
69
  prerelease: false
42
70
  version_requirements: !ruby/object:Gem::Requirement
43
71
  requirements:
44
72
  - - "~>"
45
73
  - !ruby/object:Gem::Version
46
- version: '8.5'
74
+ version: '9.1'
47
75
  - !ruby/object:Gem::Dependency
48
76
  name: runcom
49
77
  requirement: !ruby/object:Gem::Requirement
50
78
  requirements:
51
79
  - - "~>"
52
80
  - !ruby/object:Gem::Version
53
- version: '7.0'
81
+ version: '8.2'
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '8.2'
89
+ - !ruby/object:Gem::Dependency
90
+ name: spek
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '0.0'
96
+ type: :runtime
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '0.0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: zeitwerk
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '2.5'
54
110
  type: :runtime
55
111
  prerelease: false
56
112
  version_requirements: !ruby/object:Gem::Requirement
57
113
  requirements:
58
114
  - - "~>"
59
115
  - !ruby/object:Gem::Version
60
- version: '7.0'
116
+ version: '2.5'
61
117
  description:
62
118
  email:
63
119
  - brooke@alchemists.io
@@ -72,32 +128,35 @@ files:
72
128
  - README.adoc
73
129
  - exe/pragmater
74
130
  - lib/pragmater.rb
131
+ - lib/pragmater/cli/actions/config.rb
132
+ - lib/pragmater/cli/actions/run.rb
75
133
  - lib/pragmater/cli/helper.rb
76
- - lib/pragmater/cli/options/assembler.rb
77
- - lib/pragmater/cli/options/configuration.rb
78
- - lib/pragmater/cli/options/core.rb
79
- - lib/pragmater/cli/options/defaults.yml
80
- - lib/pragmater/cli/options/insert_remove.rb
81
- - lib/pragmater/cli/options/merger.rb
134
+ - lib/pragmater/cli/parser.rb
135
+ - lib/pragmater/cli/parsers/core.rb
136
+ - lib/pragmater/cli/parsers/flag.rb
82
137
  - lib/pragmater/cli/shell.rb
83
- - lib/pragmater/context.rb
138
+ - lib/pragmater/configuration/content.rb
139
+ - lib/pragmater/configuration/defaults.yml
140
+ - lib/pragmater/configuration/loader.rb
141
+ - lib/pragmater/container.rb
84
142
  - lib/pragmater/formatters/general.rb
85
143
  - lib/pragmater/formatters/main.rb
86
144
  - lib/pragmater/formatters/shebang.rb
87
- - lib/pragmater/identity.rb
88
145
  - lib/pragmater/parsers/comments.rb
89
146
  - lib/pragmater/parsers/file.rb
90
147
  - lib/pragmater/processors/handler.rb
91
148
  - lib/pragmater/processors/inserter.rb
92
149
  - lib/pragmater/processors/remover.rb
93
150
  - lib/pragmater/runner.rb
151
+ - pragmater.gemspec
94
152
  homepage: https://www.alchemists.io/projects/pragmater
95
153
  licenses:
96
- - Apache-2.0
154
+ - Hippocratic-3.0
97
155
  metadata:
98
156
  bug_tracker_uri: https://github.com/bkuhlmann/pragmater/issues
99
- changelog_uri: https://www.alchemists.io/projects/pragmater/changes.html
157
+ changelog_uri: https://www.alchemists.io/projects/pragmater/versions
100
158
  documentation_uri: https://www.alchemists.io/projects/pragmater
159
+ label: Pragmater
101
160
  rubygems_mfa_required: 'true'
102
161
  source_code_uri: https://github.com/bkuhlmann/pragmater
103
162
  post_install_message:
@@ -108,14 +167,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
108
167
  requirements:
109
168
  - - "~>"
110
169
  - !ruby/object:Gem::Version
111
- version: '3.0'
170
+ version: '3.1'
112
171
  required_rubygems_version: !ruby/object:Gem::Requirement
113
172
  requirements:
114
173
  - - ">="
115
174
  - !ruby/object:Gem::Version
116
175
  version: '0'
117
176
  requirements: []
118
- rubygems_version: 3.2.31
177
+ rubygems_version: 3.3.6
119
178
  signing_key:
120
179
  specification_version: 4
121
180
  summary: A command line interface for managing/formatting source file pragma comments.