pragmater 9.3.0 → 10.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.