pragmater 9.2.0 → 10.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.
@@ -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 = "Pragmater - #{specification.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 { "Pragmater #{specification.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,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry-container"
4
+ require "logger"
5
+ require "pastel"
6
+
7
+ module Pragmater
8
+ # Provides a global gem container for injection into other objects.
9
+ module Container
10
+ extend Dry::Container::Mixin
11
+
12
+ SPEC_PATH = "#{__dir__}/../../pragmater.gemspec".freeze
13
+
14
+ register(:configuration) { Configuration::Loader.call }
15
+ register(:specification) { Gem::Specification.load SPEC_PATH }
16
+ register(:colorizer) { Pastel.new enabled: $stdout.tty? }
17
+ register(:kernel) { Kernel }
18
+
19
+ register :log_colors do
20
+ {
21
+ "DEBUG" => self[:colorizer].white.detach,
22
+ "INFO" => self[:colorizer].green.detach,
23
+ "WARN" => self[:colorizer].yellow.detach,
24
+ "ERROR" => self[:colorizer].red.detach,
25
+ "FATAL" => self[:colorizer].white.bold.on_red.detach,
26
+ "ANY" => self[:colorizer].white.bold.detach
27
+ }
28
+ end
29
+
30
+ register :logger do
31
+ Logger.new $stdout,
32
+ level: Logger.const_get(ENV.fetch("LOG_LEVEL", "INFO")),
33
+ formatter: (
34
+ lambda do |severity, _at, _name, message|
35
+ self[:log_colors][severity].call "#{message}\n"
36
+ end
37
+ )
38
+ end
39
+ end
40
+ 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,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "pragmater"
5
+ spec.version = "10.1.0"
6
+ spec.platform = Gem::Platform::RUBY
7
+ spec.authors = ["Brooke Kuhlmann"]
8
+ spec.email = ["brooke@alchemists.io"]
9
+ spec.homepage = "https://www.alchemists.io/projects/pragmater"
10
+ spec.summary = "A command line interface for managing/formatting source file pragma comments."
11
+ spec.license = "Hippocratic-3.0"
12
+
13
+ spec.metadata = {
14
+ "bug_tracker_uri" => "https://github.com/bkuhlmann/pragmater/issues",
15
+ "changelog_uri" => "https://www.alchemists.io/projects/pragmater/versions",
16
+ "documentation_uri" => "https://www.alchemists.io/projects/pragmater",
17
+ "label" => "Pragmater",
18
+ "rubygems_mfa_required" => "true",
19
+ "source_code_uri" => "https://github.com/bkuhlmann/pragmater"
20
+ }
21
+
22
+ spec.signing_key = Gem.default_key_path
23
+ spec.cert_chain = [Gem.default_cert_path]
24
+
25
+ spec.required_ruby_version = "~> 3.1"
26
+ spec.add_dependency "dry-container", "~> 0.9"
27
+ spec.add_dependency "pastel", "~> 0.8"
28
+ spec.add_dependency "refinements", "~> 9.1"
29
+ spec.add_dependency "runcom", "~> 8.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
+ spec.require_paths = ["lib"]
37
+ end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,12 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pragmater
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.2.0
4
+ version: 10.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brooke Kuhlmann
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain:
11
11
  - |
12
12
  -----BEGIN CERTIFICATE-----
@@ -28,36 +28,78 @@ cert_chain:
28
28
  lkHilIrX69jq8wMPpBhlaw2mRmeSL50Wv5u6xVBvOHhXFSP1crXM95vfLhLyRYod
29
29
  W2A=
30
30
  -----END CERTIFICATE-----
31
- date: 2021-10-09 00:00:00.000000000 Z
31
+ date: 2022-01-23 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.4'
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.4'
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.0'
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '8.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: zeitwerk
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '2.5'
54
96
  type: :runtime
55
97
  prerelease: false
56
98
  version_requirements: !ruby/object:Gem::Requirement
57
99
  requirements:
58
100
  - - "~>"
59
101
  - !ruby/object:Gem::Version
60
- version: '7.0'
102
+ version: '2.5'
61
103
  description:
62
104
  email:
63
105
  - brooke@alchemists.io
@@ -70,34 +112,38 @@ extra_rdoc_files:
70
112
  files:
71
113
  - LICENSE.adoc
72
114
  - README.adoc
73
- - bin/pragmater
115
+ - exe/pragmater
74
116
  - lib/pragmater.rb
117
+ - lib/pragmater/cli/actions/config.rb
118
+ - lib/pragmater/cli/actions/run.rb
75
119
  - 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
120
+ - lib/pragmater/cli/parser.rb
121
+ - lib/pragmater/cli/parsers/core.rb
122
+ - lib/pragmater/cli/parsers/flag.rb
82
123
  - lib/pragmater/cli/shell.rb
83
- - lib/pragmater/context.rb
124
+ - lib/pragmater/configuration/content.rb
125
+ - lib/pragmater/configuration/defaults.yml
126
+ - lib/pragmater/configuration/loader.rb
127
+ - lib/pragmater/container.rb
84
128
  - lib/pragmater/formatters/general.rb
85
129
  - lib/pragmater/formatters/main.rb
86
130
  - lib/pragmater/formatters/shebang.rb
87
- - lib/pragmater/identity.rb
88
131
  - lib/pragmater/parsers/comments.rb
89
132
  - lib/pragmater/parsers/file.rb
90
133
  - lib/pragmater/processors/handler.rb
91
134
  - lib/pragmater/processors/inserter.rb
92
135
  - lib/pragmater/processors/remover.rb
93
136
  - lib/pragmater/runner.rb
137
+ - pragmater.gemspec
94
138
  homepage: https://www.alchemists.io/projects/pragmater
95
139
  licenses:
96
- - Apache-2.0
140
+ - Hippocratic-3.0
97
141
  metadata:
98
142
  bug_tracker_uri: https://github.com/bkuhlmann/pragmater/issues
99
- changelog_uri: https://www.alchemists.io/projects/pragmater/changes.html
143
+ changelog_uri: https://www.alchemists.io/projects/pragmater/versions
100
144
  documentation_uri: https://www.alchemists.io/projects/pragmater
145
+ label: Pragmater
146
+ rubygems_mfa_required: 'true'
101
147
  source_code_uri: https://github.com/bkuhlmann/pragmater
102
148
  post_install_message:
103
149
  rdoc_options: []
@@ -107,14 +153,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
107
153
  requirements:
108
154
  - - "~>"
109
155
  - !ruby/object:Gem::Version
110
- version: '3.0'
156
+ version: '3.1'
111
157
  required_rubygems_version: !ruby/object:Gem::Requirement
112
158
  requirements:
113
159
  - - ">="
114
160
  - !ruby/object:Gem::Version
115
161
  version: '0'
116
162
  requirements: []
117
- rubygems_version: 3.2.28
163
+ rubygems_version: 3.3.5
118
164
  signing_key:
119
165
  specification_version: 4
120
166
  summary: A command line interface for managing/formatting source file pragma comments.