scss_lint-auto_correct 1.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ecfcbc916da720f957affb069abd0cb138469b9e
4
+ data.tar.gz: 681f8344e431b2ed948a72efa3446ee1b954a4ea
5
+ SHA512:
6
+ metadata.gz: b26b98b6112520ff69a4e95547e9bb6211c5f1446481f982e8aab95d3e316281ab3be3a3315af687572cc4d488334e06d0adbdf09dc40edfcc341b283777b188
7
+ data.tar.gz: 4d28006157b8d380470eef8d1205f573c9840524b90dbcf44399e58aafedb4b5d39a211d613d9bc4ca242eeea6ee0e7636d9efca0903fbb16a501ca8a65b5127
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015, 2017 Dorian Marié, Troels Knak-Nielsen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH << File.expand_path("../../lib", __FILE__)
3
+
4
+ require "scss_lint/auto_correct"
5
+ require "scss_lint/auto_correct/cli"
6
+
7
+ # logger = SCSSLint::Logger.new(STDOUT)
8
+ exit SCSSLint::AutoCorrect::CLI.new.run(ARGV)
@@ -0,0 +1,148 @@
1
+ module SCSSLint::AutoCorrect
2
+ class CLI
3
+ attr_accessor :correctors, :paths, :options, :writer, :config
4
+
5
+ def initialize
6
+ @paths = []
7
+ @options = {}
8
+ @writer = FilesystemWriter.new
9
+ @correctors = Correctors.all
10
+ end
11
+
12
+ def parse_args!(argv)
13
+ @paths = []
14
+ @options = {}
15
+ argv.each do |arg|
16
+ if arg[0..1] == "--"
17
+ @options[arg[2..-1].to_sym] = true
18
+ elsif arg[0] == "-"
19
+ @options[arg[1..-1].to_sym] = true
20
+ elsif File.directory?(arg)
21
+ Dir["#{arg.chomp('/')}/**/*.scss"].each do |f|
22
+ @paths << f
23
+ end
24
+ else
25
+ @paths << arg
26
+ end
27
+ end
28
+ end
29
+
30
+ def option?(*names)
31
+ names.each do |name|
32
+ return true if @options[name.to_sym]
33
+ end
34
+ false
35
+ end
36
+
37
+ def run(argv)
38
+ parse_args! argv
39
+ load_config!
40
+ if option? :help, :h
41
+ print_help
42
+ return 0
43
+ end
44
+ if option? :list
45
+ print_list
46
+ return 0
47
+ end
48
+ if @paths.empty?
49
+ puts "Nothing to process"
50
+ return 1
51
+ end
52
+ process_all @paths
53
+ 0
54
+ end
55
+
56
+ def print_help
57
+ puts "Fix your messy code"
58
+ puts "USAGE: scss-lint-auto-correct [OPTIONS] PATH [PATH ...]"
59
+ puts "OPTIONS are:"
60
+ puts " --help, -h"
61
+ puts " --verbose, -v"
62
+ puts " --dry"
63
+ puts " --list"
64
+ puts "Only apply specific correctors, using any combination of:"
65
+ @correctors.each do |c|
66
+ puts " --#{c.short_name}"
67
+ end
68
+ puts "Disable specific correctors, using any combination of:"
69
+ @correctors.each do |c|
70
+ puts " --no-#{c.short_name}"
71
+ end
72
+ end
73
+
74
+ def print_list
75
+ puts "Configured correctors:"
76
+ @correctors.each do |c|
77
+ puts " #{c.short_name}: #{c.description}"
78
+ end
79
+ end
80
+
81
+ def load_config!
82
+ config_file = relevant_configuration_file
83
+ @config = config_file ? SCSSLint::Config.load(config_file) : SCSSLint::Config.default
84
+ end
85
+
86
+ def relevant_configuration_file
87
+ if File.exist?(SCSSLint::Config::FILE_NAME)
88
+ SCSSLint::Config::FILE_NAME
89
+ elsif File.exist?(SCSSLint::Config.user_file)
90
+ SCSSLint::Config.user_file
91
+ end
92
+ end
93
+
94
+ def process_all(paths)
95
+ paths.each do |path|
96
+ process_file path
97
+ end
98
+ end
99
+
100
+ def process_file(path)
101
+ puts "Processing file #{path}" if option? :verbose, :v
102
+ before = File.read(path)
103
+ after = invoke_correctors(before)
104
+
105
+ write_file(path, after) if before != after
106
+ end
107
+
108
+ def write_file(path, contents)
109
+ puts "Writing file #{path}" if option? :verbose, :v
110
+ writer.write_file(path, contents)
111
+ end
112
+
113
+ def selected_correctors
114
+ selected = []
115
+ unselected = []
116
+ @correctors.each do |c|
117
+ selected << c if option? c.short_name
118
+ unselected << c if option? "no-#{c.short_name}"
119
+ end
120
+ all = selected.any? ? selected : @correctors
121
+ all - unselected
122
+ end
123
+
124
+ def invoke_correctors(contents)
125
+ @correctors.each do |corrector|
126
+ config = corrector.config_name ? @config.options['linters'].fetch(corrector.config_name) : {}
127
+ contents = corrector.new(config).call(contents)
128
+ end
129
+ contents
130
+ end
131
+
132
+ class FilesystemWriter
133
+ def write_file(path, contents)
134
+ File.open(path, "w+") { |f| f.write contents }
135
+ end
136
+ end
137
+
138
+ class DummyWriter
139
+ def files
140
+ @files ||= []
141
+ end
142
+
143
+ def write_file(path, contents)
144
+ files << { path: path, contents: contents }
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,28 @@
1
+ module SCSSLint::AutoCorrect::Correctors
2
+ class Base
3
+ def self.config_name
4
+ end
5
+
6
+ def self.short_name
7
+ self.name.split("::").last.
8
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
9
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
10
+ tr('_', '-').
11
+ downcase
12
+ end
13
+
14
+ def self.priority
15
+ 10
16
+ end
17
+
18
+ attr_reader :config
19
+
20
+ def initialize(config = {})
21
+ @config = config
22
+ end
23
+
24
+ def enabled?
25
+ @config["enabled"] != false
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,11 @@
1
+ module SCSSLint::AutoCorrect::Correctors
2
+ class DoubleQuoting < Base
3
+ def call(contents)
4
+ contents.gsub("'", '"')
5
+ end
6
+
7
+ def self.description
8
+ "Use double quotes, rather than single quotes"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module SCSSLint::AutoCorrect::Correctors
2
+ class DowncaseColors < Base
3
+ def call(contents)
4
+ contents.gsub(/#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/) { |m| m.downcase }
5
+ end
6
+
7
+ def self.description
8
+ "Downcase hex color values"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module SCSSLint::AutoCorrect::Correctors
2
+ class FormatNewlines < Base
3
+ def call(contents)
4
+ contents.gsub(/}\n( *[\.a-zA-Z0-9=\-:&\[\]]+) {/m) do
5
+ "}\n\n#{Regexp.last_match[1]} {"
6
+ end
7
+ end
8
+
9
+ def self.description
10
+ ""
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module SCSSLint::AutoCorrect::Correctors
2
+ class LinesEndWithSemicolons < Base
3
+ def call(contents)
4
+ # if a line ends with a letter, it means it should end with a semicolon
5
+ # (and it contains a : but no comments (// and *) and some buggy expressions (&))
6
+ contents.gsub(/^[^\/*&]+:[^\/*&]+[A-Za-z0-9-]$/, '\0;')
7
+ end
8
+
9
+ def self.description
10
+ "Ensure lines end with a semicolon, when they should"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ module SCSSLint::AutoCorrect::Correctors
2
+ class NewlinesForEachSelector < Base
3
+ def call(contents)
4
+ contents.gsub(/([a-zA-Z0-9\[\]=~* ]+,){2,}.+{/) do |m|
5
+ selectors = m.split(",")
6
+ first = selectors.first.rstrip
7
+ rest = selectors[1..-1].map { |s| " " * first.count(" ") + s.strip }
8
+ ([first] + rest).join(",\n")
9
+ end
10
+ end
11
+
12
+ def self.description
13
+ "Ensure each selector goes on its own line"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module SCSSLint::AutoCorrect::Correctors
2
+ class NoSpacesBeforeSemicolons < Base
3
+ def call(contents)
4
+ contents.gsub(/ +;/, ';')
5
+ end
6
+
7
+ def self.description
8
+ "Remove spaces before semicolons"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module SCSSLint::AutoCorrect::Correctors
2
+ class ShortVersionsOfNumbers < Base
3
+ def call(contents)
4
+ # do not match 1.04 or v1.0.0 or LICENSE-2.0
5
+ # (this is pure dark magic)
6
+ contents.gsub(/([^-v[0-9]?\.?)])([0-9])\.0+([^0-9])/, '\1\2\3')
7
+ end
8
+
9
+ def self.description
10
+ ""
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ module SCSSLint::AutoCorrect::Correctors
2
+ class ShorterVersionsOfColors < Base
3
+ def call(contents)
4
+ contents.gsub(/#(([A-Za-z0-9])\2){3}/) { |m| "##{m[1]}#{m[3]}#{m[5]}" }
5
+ end
6
+
7
+ def self.description
8
+ "Shortens hex color codes to 3 letters, when possible"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module SCSSLint::AutoCorrect::Correctors
2
+ class SpacingBeforeSelectors < Base
3
+ def call(contents)
4
+ contents.gsub(/[a-zA-Z0-9%\[\]=*~]+ +{/) { |m| m.gsub(/ +/, ' ') }
5
+ end
6
+
7
+ def self.description
8
+ "Removes any extra whitespace before selector opening brace"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,26 @@
1
+ module SCSSLint::AutoCorrect::Correctors
2
+ class UseHexInsteadOfColorKeywords < Base
3
+ def call(contents)
4
+ colors = self.class.data
5
+ regexp = Regexp.new("^([^\/]+ )(#{colors.keys.join('|')})([\) ;].*)$")
6
+
7
+ contents.gsub(regexp) do
8
+ Regexp.last_match[1] + colors[Regexp.last_match[2]] + Regexp.last_match[3]
9
+ end
10
+ end
11
+
12
+ def self.data
13
+ return @data if @data
14
+ colors_file = File.expand_path(File.join(File.dirname(__FILE__), "color-keywords.csv"))
15
+ @data = Hash[File.read(colors_file).lines.map { |l| l.gsub("\n", '').split(',') }]
16
+ end
17
+
18
+ def self.description
19
+ "Replace named colors with their hex values"
20
+ end
21
+
22
+ def self.priority
23
+ 5
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ module SCSSLint::AutoCorrect::Correctors
2
+ class VariableNames < Base
3
+ def call(contents)
4
+ contents.gsub(/\$[a-z_-]+/) { |m| m.gsub('_', '-') }
5
+ end
6
+
7
+ def self.description
8
+ "Use dashes instead of underscores in variable names"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ module SCSSLint::AutoCorrect
2
+ module Correctors
3
+ def self.all
4
+ ObjectSpace.
5
+ each_object(Class).
6
+ select { |klass| klass < Base }.
7
+ sort_by(&:priority)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,4 @@
1
+ # Defines the gem version.
2
+ module SCSSLint::AutoCorrect
3
+ VERSION = '1.0.0'.freeze
4
+ end
@@ -0,0 +1,10 @@
1
+ require "scss_lint"
2
+
3
+ module SCSSLint
4
+ module AutoCorrect
5
+ end
6
+ end
7
+
8
+ Dir[File.expand_path('..', __FILE__) + "/**/*.rb"].sort_by(&:length).each do |path|
9
+ require path
10
+ end
@@ -0,0 +1,3 @@
1
+ .lorem {
2
+ color: #FF0000;
3
+ }
@@ -0,0 +1,25 @@
1
+ require "minitest/mock"
2
+ require "minitest/autorun"
3
+ require "minitest/pride"
4
+
5
+ $LOAD_PATH << File.expand_path("../../lib", __FILE__)
6
+
7
+ Dir[File.expand_path('../../lib', __FILE__) + "/**/*.rb"].sort_by(&:length).each do |path|
8
+ require path
9
+ end
10
+
11
+ module Minitest
12
+ class Test
13
+ # Set is `let`'s wacky cousin
14
+ def set(key, value)
15
+ @_memoized ||= {}
16
+ @_memoized[key.to_s] = value
17
+ value
18
+ end
19
+
20
+ def load_file(filename, type: "t")
21
+ path = File.join(File.dirname(__FILE__), "fixtures", filename)
22
+ File.open(path, "r#{type}").read
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,43 @@
1
+ require_relative "../test_helper"
2
+
3
+ class CliTest < Minitest::Test
4
+ describe "SCSSLint::AutoCorrect::CLI" do
5
+ let(:cli) { SCSSLint::AutoCorrect::CLI }
6
+
7
+ it "basically works" do
8
+ cli.new
9
+ end
10
+
11
+ it "can parse regular args" do
12
+ instance = cli.new
13
+ instance.parse_args! ["foo"]
14
+ assert_equal ["foo"], instance.paths
15
+ end
16
+
17
+ it "can parse regular options" do
18
+ instance = cli.new
19
+ instance.parse_args! ["--verbose"]
20
+ assert_equal [], instance.paths
21
+ assert_equal({ verbose: true }, instance.options)
22
+ end
23
+
24
+ it "allows running a specific correctors only" do
25
+ instance = cli.new
26
+ instance.parse_args! ["--downcase-colors", "--format-newlines"]
27
+ assert_equal 2, instance.selected_correctors.count
28
+ end
29
+
30
+ it "allows skipping a specific corrector" do
31
+ instance = cli.new
32
+ all = instance.selected_correctors.count
33
+ instance.parse_args! ["--no-downcase-colors"]
34
+ assert_equal all - 1, instance.selected_correctors.count
35
+ end
36
+
37
+ it "loads scss-lint config" do
38
+ instance = cli.new
39
+ instance.load_config!
40
+ assert_equal SCSSLint::Config, instance.config.class
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,18 @@
1
+ require_relative "../test_helper"
2
+
3
+ class DowncaseColorsTest < Minitest::Test
4
+ describe "SCSSLint::AutoCorrect::Correctors::DowncaseColors" do
5
+ let(:corrector) { SCSSLint::AutoCorrect::Correctors::DowncaseColors }
6
+
7
+ it "basically works" do
8
+ corrector.new
9
+ end
10
+
11
+ it "process input" do
12
+ input = load_file "has_uppercase_colors.scss"
13
+ output = corrector.new.call input
14
+ refute_includes output, "#FF0000"
15
+ assert_includes output, "#ff0000"
16
+ end
17
+ end
18
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: scss_lint-auto_correct
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Dorian Marié
8
+ - Troels Knak-Nielsen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2017-12-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: scss_lint
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ description: A bunch of scripts for correcting some scss linting errors.
29
+ email:
30
+ - dorian@doma.io
31
+ - troels@knak-nielsen.dk
32
+ executables:
33
+ - scss-lint-auto-correct
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - LICENSE
38
+ - bin/scss-lint-auto-correct
39
+ - lib/scss_lint/auto_correct.rb
40
+ - lib/scss_lint/auto_correct/cli.rb
41
+ - lib/scss_lint/auto_correct/correctors.rb
42
+ - lib/scss_lint/auto_correct/correctors/base.rb
43
+ - lib/scss_lint/auto_correct/correctors/double_quoting.rb
44
+ - lib/scss_lint/auto_correct/correctors/downcase_colors.rb
45
+ - lib/scss_lint/auto_correct/correctors/format_newlines.rb
46
+ - lib/scss_lint/auto_correct/correctors/lines_end_with_semicolons.rb
47
+ - lib/scss_lint/auto_correct/correctors/newlines_for_each_selector.rb
48
+ - lib/scss_lint/auto_correct/correctors/no_spaces_before_semicolons.rb
49
+ - lib/scss_lint/auto_correct/correctors/short_versions_of_numbers.rb
50
+ - lib/scss_lint/auto_correct/correctors/shorter_versions_of_colors.rb
51
+ - lib/scss_lint/auto_correct/correctors/spacing_before_selectors.rb
52
+ - lib/scss_lint/auto_correct/correctors/use_hex_instead_of_color_keywords.rb
53
+ - lib/scss_lint/auto_correct/correctors/variable_names.rb
54
+ - lib/scss_lint/auto_correct/version.rb
55
+ - test/fixtures/has_uppercase_colors.scss
56
+ - test/test_helper.rb
57
+ - test/unit/cli_test.rb
58
+ - test/unit/downcase_colors_test.rb
59
+ homepage: https://github.com/Dorian/scss-lint-auto-correct
60
+ licenses:
61
+ - MIT
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '2'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project:
79
+ rubygems_version: 2.5.1
80
+ signing_key:
81
+ specification_version: 4
82
+ summary: Auto corrections for SCSS lint tool
83
+ test_files:
84
+ - test/fixtures/has_uppercase_colors.scss
85
+ - test/test_helper.rb
86
+ - test/unit/cli_test.rb
87
+ - test/unit/downcase_colors_test.rb