pragmater 7.2.0 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 17f31f5ee7db80b11e49894b0db270e17c1fcdedb97fd9fb19bfebc04af238c2
4
- data.tar.gz: fe4b1203fb590733575f72ccc569481617b978a7949dd13605582fb7a52b7bfe
3
+ metadata.gz: 9860e7c1b0f3f18bb0170616c5168e917809d02942c952516db131f272f69aee
4
+ data.tar.gz: 78c2157d4b06c08c3ff5cf6c3bcf026b54110bfc620b1fcfbab44f0c7ecdb88b
5
5
  SHA512:
6
- metadata.gz: 5e5f6b2b569226308f251b080d7e51df7352f23dfa33be98afef5424982566d9a8e55f234c052752554ba2e1f8c10740b22859ed39de06a8fd03d096e1dcd15c
7
- data.tar.gz: 5961184d11177ccea0a041783b6df77e4cced27a5088c63325915ed75fc20748e2ea0c59a05d0071d4d8786154905e83fda922788a67c6386b6241d4025e7177
6
+ metadata.gz: f62054458f1caa6a4083f25e5c03cf3b770eea28a4ef6fd12c3efc849d6f5ca01060b40ccb6a28d7c79c24ff9b1d502d2bfc7decbdd6f8c70bcc634f83f172f6
7
+ data.tar.gz: 6255ed2a79628616738f42bb25a01de99dbe3bebe0b8af9115e39318e62e050fabd0d26df6193499db315b870b0fed8b04f2b21947353dbab057cc4b2ac625b4
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -21,14 +21,14 @@ Examples:
21
21
  ----
22
22
 
23
23
  With https://www.ruby-lang.org/en/news/2015/12/25/ruby-2-3-0-released[Ruby 2.3.0], frozen strings
24
- are supported via a pragma. This gem provides an easy way to add pragmas to single or multiple Ruby
25
- source files in order to benefit from improved memory and concurrency performance.
24
+ are supported via a pragma. This gem provides an easy way to insert or remove pragmas to single or
25
+ multiple Ruby source files in order to benefit from improved memory and concurrency performance.
26
26
 
27
27
  toc::[]
28
28
 
29
29
  == Features
30
30
 
31
- * Supports adding a pragma or multiple pragmas to single or multiple source files.
31
+ * Supports inserting a pragma or multiple pragmas to single or multiple source files.
32
32
  * Supports removing pragma(s) from single or multiple source files.
33
33
  * Supports file list filtering. Defaults to any file.
34
34
  * Ensures duplicate pragmas never exist.
@@ -76,33 +76,39 @@ bin/console
76
76
 
77
77
  === Command Line Interface (CLI)
78
78
 
79
- From the command line, type: `+pragmater help+`
79
+ From the command line, type: `pragmater --help`
80
80
 
81
81
  ....
82
- pragmater -a, [--add=PATH] # Add comments to source file(s).
83
- pragmater -c, [--config] # Manage gem configuration.
84
- pragmater -h, [--help=COMMAND] # Show this message or get help for a command.
85
- pragmater -r, [--remove=PATH] # Remove comments from source file(s).
86
- pragmater -v, [--version] # Show gem version.
87
- ....
82
+ Pragmater - A command line interface for managing/formatting source file pragma comments.
88
83
 
89
- Both the `+--add+` and `+--remove+` commands support options for specifying pragmas and/or included
90
- files (viewable by running `+pragmater --help --add+` or `+pragmater --help --remove+`):
84
+ USAGE:
85
+ -v, --version Show gem version.
86
+ -h, --help Show this message.
87
+ -c, --config [options] Manage gem configuration.
88
+ -i, --insert [PATH] Insert pragam comments into files.
89
+ -r, --remove [options] Remove pragam comments from files.
91
90
 
92
- ....
93
- -c, [--comments=one two three] # Define desired comments
94
- -i, [--includes=one two three] # Include specific files and/or directories
91
+ OPTIONS:
92
+
93
+ Insert/Remove:
94
+ --comments a,b,c Add pragma comments.
95
+ --includes a,b,c Add console support.
96
+
97
+ Configuration:
98
+ --edit Edit configuration.
99
+ --info Print configuration.
95
100
  ....
96
101
 
97
- Example (same options could be used for the `+--remove+` command too):
102
+ Both the `--insert` and `--remove` commands support the same options for specifying pragmas and/or
103
+ included files. Example:
98
104
 
99
105
  [source,bash]
100
106
  ----
101
- pragmater --add --comments "# frozen_string_literal: true" --includes "Gemfile" "Guardfile" "Rakefile" ".gemspec" "config.ru" "bin/**/*" "**/*.rake" "**/*.rb"
107
+ pragmater --insert --comments "# frozen_string_literal: true" --includes "Gemfile" "Guardfile" "Rakefile" ".gemspec" "config.ru" "bin/**/*" "**/*.rake" "**/*.rb"
102
108
  ----
103
109
 
104
- The `--add` and `--remove` commands default to the current working directory so a path isn’t
105
- necessary unless you want to run Pragmater on a directory structure other than your current working
110
+ The `--insert` and `--remove` commands default to the current working directory so a path isn’t
111
+ necessary unless you want to run Pragmater in a directory structure other than your current working
106
112
  directory.
107
113
 
108
114
  === Customization
@@ -116,7 +122,7 @@ The default configuration is as follows:
116
122
 
117
123
  [source,yaml]
118
124
  ----
119
- :add:
125
+ :insert:
120
126
  :comments: []
121
127
  :includes: []
122
128
  :remove:
@@ -128,10 +134,10 @@ Feel free to take the above configuration, modify, and save as your own custom `
128
134
 
129
135
  The `configuration.yml` file can be configured as follows:
130
136
 
131
- * `add`: Defines global/local comments and/or file include lists when adding pragmas. The `comments`
132
- and `includes` options can be either a single string or an array.
137
+ * `insert`: Defines global/local comments and/or file include lists when inserting pragmas. The
138
+ `comments` and `includes` options can be either a single string or an array of strings.
133
139
  * `remove`: Defines global/local comments and/or file include lists when removing pragmas. The
134
- `comments` and `includes` options can be either a single string or an array.
140
+ `comments` and `includes` options can be either a single string or an array of strings.
135
141
 
136
142
  === Available Pragmas
137
143
 
@@ -255,17 +261,7 @@ immutable = -"test"
255
261
  mutable = +"test"
256
262
  ----
257
263
 
258
- Despite Ruby allowing you to do this, it is _not recommended_ to use the above examples as it leads
259
- to hard to read code. Instead use the following:
260
-
261
- [source,ruby]
262
- ----
263
- immutable = "test".freeze
264
- mutable = "test"
265
- ----
266
-
267
- While this requires extra typing, it expresses intent more clearly. There is a slight caveat to this
268
- rule in which the use of `+String#-@+` was http://bit.ly/2DGAjgG[enhanced in Ruby 2.5.0] to
264
+ 💡 The use of `+String#-@+`, specifically, was http://bit.ly/2DGAjgG[enhanced in Ruby 2.5.0] to
269
265
  _deduplicate_ all instances of the same string thus reducing your memory footprint. This can be
270
266
  valuable in situations where you are not using the frozen string comment and need to selectively
271
267
  freeze strings.
@@ -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
9
  Process.setproctitle Pragmater::Identity::VERSION_LABEL
9
- Pragmater::CLI.start
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
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pragmater
4
+ module Formatters
5
+ # Formats shebang pragmas in a consistent manner.
6
+ class Shebang
7
+ PATTERN = %r(\A\#!\s?/.*ruby\Z).freeze
8
+
9
+ def initialize string, pattern: PATTERN
10
+ @string = string
11
+ @pattern = pattern
12
+ end
13
+
14
+ def call
15
+ return string unless string.match? pattern
16
+
17
+ string.split("!").then { |octothorpe, path| "#{octothorpe}! #{path.strip}" }
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :string, :pattern
23
+ end
24
+ end
25
+ end
@@ -5,7 +5,8 @@ module Pragmater
5
5
  module Identity
6
6
  NAME = "pragmater"
7
7
  LABEL = "Pragmater"
8
- VERSION = "7.2.0"
8
+ VERSION = "8.0.0"
9
9
  VERSION_LABEL = "#{LABEL} #{VERSION}"
10
+ SUMMARY = "A command line interface for managing/formatting source file pragma comments."
10
11
  end
11
12
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pragmater
4
+ module Parsers
5
+ # Manages pragma comments.
6
+ class Comments
7
+ def initialize older, newer, formatter: Formatters::Main
8
+ @formatter = formatter
9
+ @older = format older
10
+ @newer = format newer
11
+ end
12
+
13
+ def insert
14
+ older.union newer
15
+ end
16
+
17
+ def remove
18
+ older - older.intersection(newer)
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :formatter, :older, :newer
24
+
25
+ def format pragmas
26
+ Array(pragmas).map { |pragma| formatter.new(pragma).call }
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pragmater
4
+ module Parsers
5
+ # Parses a file into pragma comment and body lines.
6
+ class File
7
+ def initialize pattern: Formatters::Main::PATTERN,
8
+ comments: Comments,
9
+ processor: Processors::Handler.new
10
+ @pattern = pattern
11
+ @comments = comments
12
+ @processor = processor
13
+ end
14
+
15
+ def call path, new_comments, action:
16
+ path.each_line
17
+ .partition { |line| line.match? pattern }
18
+ .then do |old_comments, body|
19
+ processor.call action, wrap_in_new_line(old_comments, new_comments, action), body
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :pattern, :comments, :processor
26
+
27
+ def wrap_in_new_line old_comments, new_comments, action
28
+ comments.new(old_comments, new_comments).public_send(action).map { |line| "#{line}\n" }
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pragmater
4
+ module Processors
5
+ # Handles the insertion or removal of pragma comments.
6
+ class Handler
7
+ DEFAULTS = {
8
+ insert: Inserter,
9
+ remove: Remover
10
+ }.freeze
11
+
12
+ def initialize processors: DEFAULTS
13
+ @processors = processors
14
+ end
15
+
16
+ def call action, comments, body
17
+ processors.fetch(action).new(comments, body).call
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :processors
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pragmater
4
+ module Processors
5
+ # Inserts new pragma comments.
6
+ class Inserter
7
+ def initialize comments, body
8
+ @comments = comments
9
+ @body = body
10
+ end
11
+
12
+ def call
13
+ body.first.then do |first|
14
+ comments.append "\n" unless first == "\n" || body.empty?
15
+ comments + body
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :comments, :body
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pragmater
4
+ module Processors
5
+ # Removes existing pragma comments.
6
+ class Remover
7
+ def initialize comments, body
8
+ @comments = comments
9
+ @body = body
10
+ end
11
+
12
+ def call
13
+ body.first.then do |first_line|
14
+ body.delete_at 0 if first_line == "\n" && comments.empty?
15
+ comments + body
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :comments, :body
22
+ end
23
+ end
24
+ end
@@ -1,32 +1,34 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "pathname"
4
+ require "refinements/pathnames"
5
+
3
6
  module Pragmater
4
7
  # Adds/removes pragma comments for files in given path.
5
8
  class Runner
6
- # rubocop:disable Metrics/ParameterLists
7
- def initialize path = ".", comments: [], includes: [], writer: Writer
8
- @path = Pathname path
9
- @comments = Array comments
10
- @includes = Array includes
11
- @writer = writer
12
- end
13
- # rubocop:enable Metrics/ParameterLists
9
+ using Refinements::Pathnames
14
10
 
15
- def files
16
- return [] unless path.exist? && path.directory? && !includes.empty?
11
+ def self.for **attributes
12
+ new Context[attributes]
13
+ end
17
14
 
18
- Pathname.glob(%(#{path}/{#{includes.join ","}})).select(&:file?)
15
+ def initialize context, parser: Parsers::File.new
16
+ @context = context
17
+ @parser = parser
19
18
  end
20
19
 
21
- def run action:
22
- files.each do |file|
23
- writer.new(file, comments).public_send action
24
- yield file if block_given?
25
- end
20
+ def call
21
+ Pathname(context.root_dir).files("{#{context.includes.join ","}}").map(&method(:write))
26
22
  end
27
23
 
28
24
  private
29
25
 
30
- attr_reader :path, :comments, :includes, :writer
26
+ attr_reader :context, :parser
27
+
28
+ def write path
29
+ path.tap do |a_path|
30
+ a_path.write parser.call(a_path, context.comments, action: context.action).join
31
+ end
32
+ end
31
33
  end
32
34
  end
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: 7.2.0
4
+ version: 8.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brooke Kuhlmann
@@ -28,36 +28,36 @@ cert_chain:
28
28
  2XV8FRa7/JimI07sPLC13eLY3xd/aYTi85Z782KIA4j0G8XEEWAX0ouBhlXPocZv
29
29
  QWc=
30
30
  -----END CERTIFICATE-----
31
- date: 2020-07-23 00:00:00.000000000 Z
31
+ date: 2020-08-25 00:00:00.000000000 Z
32
32
  dependencies:
33
33
  - !ruby/object:Gem::Dependency
34
- name: runcom
34
+ name: refinements
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: '6.0'
39
+ version: '7.7'
40
40
  type: :runtime
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '6.0'
46
+ version: '7.7'
47
47
  - !ruby/object:Gem::Dependency
48
- name: thor
48
+ name: runcom
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '0.20'
53
+ version: '6.0'
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: '0.20'
60
+ version: '6.0'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: bundler-audit
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -72,20 +72,6 @@ dependencies:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '0.6'
75
- - !ruby/object:Gem::Dependency
76
- name: climate_control
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
80
- - !ruby/object:Gem::Version
81
- version: '0.2'
82
- type: :development
83
- prerelease: false
84
- version_requirements: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - "~>"
87
- - !ruby/object:Gem::Version
88
- version: '0.2'
89
75
  - !ruby/object:Gem::Dependency
90
76
  name: gemsmith
91
77
  requirement: !ruby/object:Gem::Requirement
@@ -204,14 +190,14 @@ dependencies:
204
190
  requirements:
205
191
  - - "~>"
206
192
  - !ruby/object:Gem::Version
207
- version: '0.83'
193
+ version: '0.89'
208
194
  type: :development
209
195
  prerelease: false
210
196
  version_requirements: !ruby/object:Gem::Requirement
211
197
  requirements:
212
198
  - - "~>"
213
199
  - !ruby/object:Gem::Version
214
- version: '0.83'
200
+ version: '0.89'
215
201
  - !ruby/object:Gem::Dependency
216
202
  name: rubocop-performance
217
203
  requirement: !ruby/object:Gem::Requirement
@@ -282,12 +268,25 @@ files:
282
268
  - README.adoc
283
269
  - bin/pragmater
284
270
  - lib/pragmater.rb
285
- - lib/pragmater/cli.rb
286
- - lib/pragmater/commenter.rb
287
- - lib/pragmater/formatter.rb
271
+ - lib/pragmater/cli/helper.rb
272
+ - lib/pragmater/cli/options/assembler.rb
273
+ - lib/pragmater/cli/options/configuration.rb
274
+ - lib/pragmater/cli/options/core.rb
275
+ - lib/pragmater/cli/options/defaults.yml
276
+ - lib/pragmater/cli/options/insert_remove.rb
277
+ - lib/pragmater/cli/options/merger.rb
278
+ - lib/pragmater/cli/shell.rb
279
+ - lib/pragmater/context.rb
280
+ - lib/pragmater/formatters/general.rb
281
+ - lib/pragmater/formatters/main.rb
282
+ - lib/pragmater/formatters/shebang.rb
288
283
  - lib/pragmater/identity.rb
284
+ - lib/pragmater/parsers/comments.rb
285
+ - lib/pragmater/parsers/file.rb
286
+ - lib/pragmater/processors/handler.rb
287
+ - lib/pragmater/processors/inserter.rb
288
+ - lib/pragmater/processors/remover.rb
289
289
  - lib/pragmater/runner.rb
290
- - lib/pragmater/writer.rb
291
290
  homepage: https://www.alchemists.io/projects/pragmater
292
291
  licenses:
293
292
  - Apache-2.0
metadata.gz.sig CHANGED
Binary file
@@ -1,124 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "pathname"
4
- require "thor"
5
- require "thor/actions"
6
- require "runcom"
7
-
8
- module Pragmater
9
- # The Command Line Interface (CLI) for the gem.
10
- class CLI < Thor
11
- include Thor::Actions
12
-
13
- package_name Identity::VERSION_LABEL
14
-
15
- # rubocop:disable Metrics/MethodLength
16
- def self.configuration
17
- Runcom::Config.new "#{Identity::NAME}/configuration.yml",
18
- defaults: {
19
- add: {
20
- comments: "",
21
- includes: []
22
- },
23
- remove: {
24
- comments: "",
25
- includes: []
26
- }
27
- }
28
- end
29
- # rubocop:enable Metrics/MethodLength
30
-
31
- def initialize args = [], options = {}, config = {}
32
- super args, options, config
33
- @configuration = self.class.configuration
34
- rescue Runcom::Errors::Base => error
35
- abort error.message
36
- end
37
-
38
- desc "-a, [--add=PATH]", "Add comments to source file(s)."
39
- map %w[-a --add] => :add
40
- method_option :comments,
41
- aliases: "-c",
42
- desc: "Define desired comments",
43
- type: :array,
44
- default: configuration.to_h.dig(:add, :comments)
45
- method_option :includes,
46
- aliases: "-i",
47
- desc: "Include specific files and/or directories",
48
- type: :array,
49
- default: configuration.to_h.dig(:add, :includes)
50
- def add path = "."
51
- settings = configuration.merge(
52
- add: {comments: options.comments, includes: options.includes}
53
- ).to_h
54
-
55
- runner = Runner.new path,
56
- comments: settings.dig(:add, :comments),
57
- includes: settings.dig(:add, :includes)
58
-
59
- runner.run(action: :add) { |file| say_status :info, "Processed: #{file}.", :green }
60
- end
61
-
62
- desc "-r, [--remove=PATH]", "Remove comments from source file(s)."
63
- map %w[-r --remove] => :remove
64
- method_option :comments,
65
- aliases: "-c",
66
- desc: "Define desired comments",
67
- type: :array,
68
- default: configuration.to_h.dig(:remove, :comments)
69
- method_option :includes,
70
- aliases: "-i",
71
- desc: "Include specific files and/or directories",
72
- type: :array,
73
- default: configuration.to_h.dig(:remove, :includes)
74
- def remove path = "."
75
- settings = configuration.merge(
76
- remove: {comments: options.comments, includes: options.includes}
77
- ).to_h
78
-
79
- runner = Runner.new path,
80
- comments: settings.dig(:remove, :comments),
81
- includes: settings.dig(:remove, :includes)
82
-
83
- runner.run(action: :remove) { |file| say_status :info, "Processed: #{file}.", :green }
84
- end
85
-
86
- desc "-c, [--config]", "Manage gem configuration."
87
- map %w[-c --config] => :config
88
- method_option :edit,
89
- aliases: "-e",
90
- desc: "Edit gem configuration.",
91
- type: :boolean,
92
- default: false
93
- method_option :info,
94
- aliases: "-i",
95
- desc: "Print gem configuration.",
96
- type: :boolean,
97
- default: false
98
- def config
99
- path = configuration.current
100
-
101
- if options.edit? then `#{ENV["EDITOR"]} #{path}`
102
- elsif options.info?
103
- path ? say(path) : say("Configuration doesn't exist.")
104
- else help :config
105
- end
106
- end
107
-
108
- desc "-v, [--version]", "Show gem version."
109
- map %w[-v --version] => :version
110
- def version
111
- say Identity::VERSION_LABEL
112
- end
113
-
114
- desc "-h, [--help=COMMAND]", "Show this message or get help for a command."
115
- map %w[-h --help] => :help
116
- def help task = nil
117
- say and super
118
- end
119
-
120
- private
121
-
122
- attr_reader :configuration
123
- end
124
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Pragmater
4
- # Handles pragma comments.
5
- class Commenter
6
- def initialize older, newer, formatter: Formatter
7
- @formatter = formatter
8
- @older = format older
9
- @newer = format newer
10
- end
11
-
12
- def add
13
- older | newer
14
- end
15
-
16
- def remove
17
- older - (older & newer)
18
- end
19
-
20
- private
21
-
22
- attr_reader :older, :newer, :formatter
23
-
24
- def filter comments
25
- Array(comments).select { |comment| comment =~ formatter.valid_formats }
26
- end
27
-
28
- def format comments
29
- filter(comments).map { |comment| formatter.new(comment).format }
30
- end
31
- end
32
- end
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Pragmater
4
- # Formats pragma comments in a consistent manner.
5
- class Formatter
6
- def self.shebang_format
7
- %r(\A\#!\s?/.*ruby\Z)
8
- end
9
-
10
- def self.pragma_format
11
- /
12
- \A # Start of line.
13
- \# # Start of comment.
14
- \s? # Space - optional.
15
- \w+ # Key - 1 or more word characters only.
16
- : # Key and value delimiter.
17
- \s? # Space - optional.
18
- [\w-]+ # Value - 1 or more word or dash characters.
19
- \Z # End of line.
20
- /x
21
- end
22
-
23
- def self.valid_formats
24
- Regexp.union shebang_format, pragma_format
25
- end
26
-
27
- def initialize string
28
- @string = string
29
- end
30
-
31
- def format_shebang
32
- return string unless string.match? self.class.shebang_format
33
-
34
- _, path = string.split "!"
35
- "#! #{path.strip}"
36
- end
37
-
38
- def format_pragma
39
- return string unless string.match? self.class.pragma_format
40
-
41
- key, value = string.split ":"
42
- "# #{key.gsub(/\#\s?/, "")}: #{value.strip}"
43
- end
44
-
45
- def format
46
- klass = self.class
47
-
48
- case string
49
- when klass.shebang_format then format_shebang
50
- when klass.pragma_format then format_pragma
51
- else string
52
- end
53
- end
54
-
55
- private
56
-
57
- attr_reader :string
58
- end
59
- end
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Pragmater
4
- # Writes formatted pragma comments to source file.
5
- # :reek:TooManyInstanceVariables
6
- # :reek:MissingSafeMethod
7
- class Writer
8
- # rubocop:disable Metrics/ParameterLists
9
- def initialize file_path, new_comments, formatter: Formatter, commenter: Commenter
10
- @file_path = file_path
11
- @file_lines = File.readlines file_path
12
- @formatter = formatter
13
- @commenter = commenter
14
- @old_comments = file_comments
15
- @new_comments = new_comments
16
- end
17
- # rubocop:enable Metrics/ParameterLists
18
-
19
- def add
20
- comments = format commenter.new(old_comments, new_comments).add
21
- lines = comments + file_lines_without_comments
22
- insert_spacing! lines, comments
23
- write { lines.join }
24
- end
25
-
26
- def remove
27
- lines = format(commenter.new(old_comments, new_comments).remove) + file_lines_without_comments
28
- remove_spacing! lines
29
- write { lines.join }
30
- end
31
-
32
- private
33
-
34
- attr_reader :file_path, :file_lines, :new_comments, :old_comments, :formatter, :commenter
35
-
36
- def file_comments
37
- file_lines.select { |line| line =~ formatter.valid_formats }
38
- end
39
-
40
- def file_lines_without_comments
41
- file_lines.reject { |line| old_comments.include? line }
42
- end
43
-
44
- # :reek:UtilityFunction
45
- def format lines
46
- lines.map { |line| "#{line}\n" }
47
- end
48
-
49
- # :reek:UtilityFunction
50
- def insert_spacing! lines, comments
51
- comment_count = comments.size
52
-
53
- return if comments.empty?
54
- return if lines.size == 1
55
- return if lines[comment_count] == "\n"
56
-
57
- lines.insert comment_count, "\n"
58
- end
59
-
60
- # :reek:UtilityFunction
61
- def remove_spacing! lines
62
- lines.delete_at 0 if lines.first == "\n"
63
- end
64
-
65
- def write
66
- File.open(file_path, "w") { |file| file.write yield }
67
- end
68
- end
69
- end