Skip to content

Commit

Permalink
Standardize repo name to erb_lint (#360)
Browse files Browse the repository at this point in the history
* Deprecate old binstub, add the renamed binstub

* Rename instances of erb-lint to erb_lint

* Deprecate `erb-lint` mentions in the Cli to `erb_lint`

* Warn message grammatical fixes

* Make remaining README refactors to erb_lint

* Add rainbow require

* Reword deprecation message and add test to check that it warns

* Update erblint warning message

* Fix binstubs

* Deprecate .erb-linters in favour of .erb_linters

---------

Co-authored-by: Jenny Shen <jenny.shen@shopify.com>
  • Loading branch information
george-ma and jenshenny authored Sep 6, 2024
1 parent b17760d commit c502d90
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 39 deletions.
42 changes: 21 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ERB Lint [![Build Status](https://github.com/Shopify/erb-lint/workflows/Tests/badge.svg)](https://github.com/Shopify/erb-lint/actions)
# ERB Lint [![Build Status](https://github.com/Shopify/erb_lint/workflows/Tests/badge.svg)](https://github.com/Shopify/erb_lint/actions)

`erb-lint` is a tool to help lint your ERB or HTML files using the included linters or by writing your own.
`erb_lint` is a tool to help lint your ERB or HTML files using the included linters or by writing your own.

## Requirements

Expand All @@ -22,7 +22,7 @@ gem 'erb_lint', require: false

## Configuration

Create a `.erb-lint.yml` file in your project, with the following structure:
Create a `.erb_lint.yml` file in your project, with the following structure:

```yaml
---
Expand All @@ -44,10 +44,10 @@ See below for linter-specific configuration options.
This gem provides a command-line interface which can be run like so:
1. Run `erblint [options]` if the gem is installed standalone.
2. Run `bundle exec erblint [options]` if the gem is installed as a Gemfile dependency for your app.
1. Run `erb_lint [options]` if the gem is installed standalone.
2. Run `bundle exec erb_lint [options]` if the gem is installed as a Gemfile dependency for your app.

For example, `erblint --lint-all --enable-all-linters` will run all available
For example, `erb_lint --lint-all --enable-all-linters` will run all available
linters on all ERB files in the current directory or its descendants (`**/*.html{+*,}.erb`).

If you want to change the glob & exclude that is used, you can configure it by adding it to your config file as follows:
Expand Down Expand Up @@ -221,8 +221,8 @@ Linter-Specific Option | Description

### Rubocop

Runs RuboCop on all ruby statements found in ERB templates. The RuboCop configuration that `erb-lint` uses can inherit from
the configuration that the rest of your application uses. `erb-lint` can be configured independently however, as it will often
Runs RuboCop on all ruby statements found in ERB templates. The RuboCop configuration that `erb_lint` uses can inherit from
the configuration that the rest of your application uses. `erb_lint` can be configured independently however, as it will often
be necessary to disable specific RuboCop rules that do not apply to ERB files.

**Note**: Each ruby statement (between ERB tags `<% ... %>`) is parsed and analyzed independently of each other. Any rule that requires a broader context can trigger false positives (e.g. `Lint/UselessAssignment` will complaint for an assignment even if used in a subsequent ERB tag).
Expand Down Expand Up @@ -523,11 +523,11 @@ Good ✅

## Custom Linters

`erb-lint` allows you to create custom linters specific to your project. It will load linters from the `.erb-linters` directory in the root of your
`erb_lint` allows you to create custom linters specific to your project. It will load linters from the `.erb_linters` directory in the root of your
repository. See the [linters directory](lib/erb_lint/linters) for examples of how to write linters.

```ruby
# .erb-linters/custom_linter.rb
# .erb_linters/custom_linter.rb
module ERBLint
module Linters
Expand All @@ -552,7 +552,7 @@ module ERBLint
end
```

By default, this linter would be disabled. You can enable it by adding an entry to `.erb-lint.yml`:
By default, this linter would be disabled. You can enable it by adding an entry to `.erb_lint.yml`:

```yaml
---
Expand All @@ -562,10 +562,10 @@ linters:
custom_message: We suggest you change this file.
```

Test your linter by running `erblint`'s command-line interface:
Test your linter by running `erb_lint`'s command-line interface:

```bash
bundle exec erblint --enable-linters custom_linter --lint-all
bundle exec erb_lint --enable-linters custom_linter --lint-all
```

Running this on a random project might yield this output:
Expand All @@ -582,7 +582,7 @@ Errors were found in ERB files
To write a linter that can autocorrect offenses it detects, simply add an
`autocorrect` method that returns a callable. The callable is called with an instance of
[`RuboCop::Cop::Corrector`](http://www.rubydoc.info/github/bbatsov/RuboCop/RuboCop/Cop/Corrector)
as argument, and therefore erb-lint correctors work exactly as RuboCop correctors do.
as argument, and therefore erb_lint correctors work exactly as RuboCop correctors do.

```ruby
def autocorrect(_processed_source, offense)
Expand All @@ -599,7 +599,7 @@ You can change the output format of ERB Lint by specifying formatters with the `
### Multiline (default)

```sh
$ erblint
$ erb_lint
Linting 8 files with 12 linters...
Remove multiple trailing newline at the end of the file.
Expand All @@ -614,7 +614,7 @@ In file: app/views/subscriptions/index.html.erb:38
### Compact

```sh
erblint --format compact
erb_lint --format compact
Linting 8 files with 12 linters...
app/views/users/show.html.erb:95:0: Remove multiple trailing newline at the end of the file.
app/views/users/_graph.html.erb:27:37: Extra space detected where there should be no space
Expand All @@ -624,9 +624,9 @@ app/views/users/_graph.html.erb:27:37: Extra space detected where there should b
### JUnit

```sh
erblint --format junit
erb_lint --format junit
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="erblint" tests="2" failures="2">
<testsuite name="erb_lint" tests="2" failures="2">
<properties>
<property name="erb_lint_version" value="%{erb_lint_version}"/>
<property name="ruby_engine" value="%{ruby_engine}"/>
Expand Down Expand Up @@ -684,7 +684,7 @@ Quality](https://docs.gitlab.com/ee/ci/testing/code_quality.html#implement-a-cus
The cache is currently opt-in - to turn it on, use the `--cache` option:
```sh
erblint --cache ./app
erb_lint --cache ./app
Cache mode is on
Linting 413 files with 15 linters...
File names pruned from the cache will be logged
Expand All @@ -693,9 +693,9 @@ No errors were found in ERB files
```
Cached lint results are stored in the `.erb-lint-cache` directory by default, though a custom directory can be provided
via the `--cache-dir` option. Cache filenames are computed with a hash of information about the file and `erb-lint` settings.
via the `--cache-dir` option. Cache filenames are computed with a hash of information about the file and `erb_lint` settings.
These files store instance attributes of the `CachedOffense` object, which only contain the `Offense` attributes
necessary to restore the results of running `erb-lint` for output. The cache also automatically prunes outdated files each time it's run.
necessary to restore the results of running `erb_lint` for output. The cache also automatically prunes outdated files each time it's run.
You can also use the `--clear-cache` option to delete the cache file directory.
Expand Down
2 changes: 1 addition & 1 deletion erb_lint.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Gem::Specification.new do |s|
s.email = ["ruby@shopify.com"]
s.summary = "ERB lint tool"
s.description = "ERB Linter tool."
s.homepage = "https://github.com/Shopify/erb-lint"
s.homepage = "https://github.com/Shopify/erb_lint"
s.license = "MIT"

s.files = Dir["lib/**/*.rb", "exe/*"]
Expand Down
10 changes: 10 additions & 0 deletions exe/erb_lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

lib_path = File.expand_path("#{__dir__}/../lib")
$LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path)

require "erb_lint/cli"

cli = ERBLint::CLI.new
exit(cli.run)
9 changes: 5 additions & 4 deletions exe/erblint
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

$LOAD_PATH.unshift("#{__dir__}/../lib")
lib_path = File.expand_path("#{__dir__}/../lib")
$LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path)

require "erb_lint/cli"
require "rainbow"

cli = ERBLint::CLI.new
exit(cli.run)
warn(Rainbow("Calling `erblint` is deprecated, please call the renamed executable `erb_lint` instead.").yellow)
exec(File.join(__dir__, "erb_lint"), *ARGV)
12 changes: 10 additions & 2 deletions lib/erb_lint/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ module ERBLint
class CLI
include Utils::SeverityLevels

DEFAULT_CONFIG_FILENAME = ".erb-lint.yml"
DEPRECATED_CONFIG_FILENAME = ".erb-lint.yml"
DEFAULT_CONFIG_FILENAME = ".erb_lint.yml"
DEFAULT_LINT_ALL_GLOB = "**/*.html{+*,}.erb"

class ExitWithFailure < RuntimeError; end
Expand Down Expand Up @@ -87,7 +88,7 @@ def run(args = ARGV)
rescue => e
@stats.exceptions += 1
puts "Exception occurred when processing: #{relative_filename(filename)}"
puts "If this file cannot be processed by erb-lint, " \
puts "If this file cannot be processed by erb_lint, " \
"you can exclude it in your configuration file."
puts e.message
puts Rainbow(e.backtrace.join("\n")).red
Expand Down Expand Up @@ -215,6 +216,13 @@ def load_config
if File.exist?(config_filename)
config = RunnerConfig.new(file_loader.yaml(config_filename), file_loader)
@config = RunnerConfig.default_for(config)
elsif File.exist?(DEPRECATED_CONFIG_FILENAME)
deprecation_message = "The config file has been renamed to `#{DEFAULT_CONFIG_FILENAME}` and " \
"`#{DEPRECATED_CONFIG_FILENAME}` is deprecated. " \
"Please rename your config file to `#{DEFAULT_CONFIG_FILENAME}`."
warn(Rainbow(deprecation_message).yellow)
config = RunnerConfig.new(file_loader.yaml(DEPRECATED_CONFIG_FILENAME), file_loader)
@config = RunnerConfig.default_for(config)
else
warn(Rainbow("#{config_filename} not found: using default config").yellow)
@config = RunnerConfig.default
Expand Down
12 changes: 11 additions & 1 deletion lib/erb_lint/linter_registry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
module ERBLint
# Stores all linters available to the application.
module LinterRegistry
CUSTOM_LINTERS_DIR = ".erb-linters"
DEPRECATED_CUSTOM_LINTERS_DIR = ".erb-linters"
CUSTOM_LINTERS_DIR = ".erb_linters"
@loaded_linters = []

class << self
Expand All @@ -28,6 +29,15 @@ def linters

def load_custom_linters(directory = CUSTOM_LINTERS_DIR)
ruby_files = Dir.glob(File.expand_path(File.join(directory, "**", "*.rb")))

deprecated_ruby_files = Dir.glob(File.expand_path(File.join(DEPRECATED_CUSTOM_LINTERS_DIR, "**", "*.rb")))
if deprecated_ruby_files.any?
deprecation_message = "The '#{DEPRECATED_CUSTOM_LINTERS_DIR}' directory for custom linters is deprecated. " \
"Please rename it to '#{CUSTOM_LINTERS_DIR}'"
warn(Rainbow(deprecation_message).yellow)
ruby_files.concat(deprecated_ruby_files)
end

ruby_files.each { |file| require file }
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/erb_lint/runner_config_resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def resolve_inheritance(hash, file_loader)

def resolve_inheritance_from_gems(hash, gems)
(gems || {}).each_pair do |gem_name, config_path|
raise(ArgumentError, "can't inherit configuration from the erb-lint gem") if gem_name == "erb-lint"
raise(ArgumentError, "can't inherit configuration from the erb_lint gem") if gem_name == "erb_lint"

hash["inherit_from"] = Array(hash["inherit_from"])
Array(config_path).reverse_each do |path|
Expand Down
22 changes: 19 additions & 3 deletions spec/erb_lint/cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,22 @@ def run(processed_source)
end
end

context "with deprecated config file" do
let(:deprecated_config_filename) { ".erb-lint.yml" }
let(:config_file_content) { "---\nEnableDefaultLinters: true\n" }

before do
FileUtils.mkdir_p(File.dirname(deprecated_config_filename))
File.write(deprecated_config_filename, config_file_content)
end

it "shows a warning but loads the deprecated config file" do
expect { subject }.to(output(/`#{Regexp.escape(deprecated_config_filename)}` is deprecated/).to_stderr)
config = cli.instance_variable_get(:@config)
expect(config).to(be_an_instance_of(ERBLint::RunnerConfig))
end
end

context "with --disable-inline-configs" do
module ERBLint
module Linters
Expand Down Expand Up @@ -227,7 +243,7 @@ def run(processed_source)

context "without --config" do
context "when default config does not exist" do
it { expect { subject }.to(output(/\.erb-lint\.yml not found: using default config/).to_stderr) }
it { expect { subject }.to(output(/\.erb_lint\.yml not found: using default config/).to_stderr) }
end
end

Expand Down Expand Up @@ -444,7 +460,7 @@ def run(processed_source)

context "without --config" do
context "when default config does not exist" do
it { expect { subject }.to(output(/\.erb-lint\.yml not found: using default config/).to_stderr) }
it { expect { subject }.to(output(/\.erb_lint\.yml not found: using default config/).to_stderr) }
end
end

Expand Down Expand Up @@ -603,7 +619,7 @@ def run(processed_source)

context "without --config" do
context "when default config does not exist" do
it { expect { subject }.to(output(/\.erb-lint\.yml not found: using default config/).to_stderr) }
it { expect { subject }.to(output(/\.erb_lint\.yml not found: using default config/).to_stderr) }
end
end

Expand Down
9 changes: 9 additions & 0 deletions spec/erb_lint/linter_registry_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,14 @@ class FakeLinter < ERBLint::Linter
.with(File.join(custom_directory, "custom_linter.rb")).once)
described_class.load_custom_linters(custom_directory)
end

it "warns when using the deprecated custom linters directory" do
stub_const("ERBLint::LinterRegistry::DEPRECATED_CUSTOM_LINTERS_DIR", custom_directory)

expected_warning = Rainbow("The '#{custom_directory}' directory for custom linters is deprecated. " \
"Please rename it to '.erb_linters'").yellow
expect(described_class).to(receive(:warn).with(expected_warning).once)
described_class.load_custom_linters
end
end
end
12 changes: 6 additions & 6 deletions spec/erb_lint/runner_config_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ class MySchema < ERBLint::LinterConfig
after { FileUtils.rm_rf(tmp_root) }

it "inherits from a gem and loads the config" do
create_file("#{gem_root}/gemone/config/erb-lint.yml", <<-YAML.strip_indent)
create_file("#{gem_root}/gemone/config/erb_lint.yml", <<-YAML.strip_indent)
MyCustomLinter:
my_option: custom value
YAML
Expand All @@ -238,7 +238,7 @@ class MySchema < ERBLint::LinterConfig
runner_config = described_class.new(
{
"inherit_gem" => {
"gemone" => "config/erb-lint.yml",
"gemone" => "config/erb_lint.yml",
},
},
ERBLint::FileLoader.new(Dir.pwd),
Expand All @@ -248,7 +248,7 @@ class MySchema < ERBLint::LinterConfig
end

it "inherits from a gem and merges the config" do
create_file("#{gem_root}/gemone/config/erb-lint.yml", <<-YAML.strip_indent)
create_file("#{gem_root}/gemone/config/erb_lint.yml", <<-YAML.strip_indent)
MyCustomLinter1:
a: value to be overwritten
b: value for b
Expand All @@ -264,7 +264,7 @@ class MySchema < ERBLint::LinterConfig
runner_config = described_class.new(
{
"inherit_gem" => {
"gemone" => "config/erb-lint.yml",
"gemone" => "config/erb_lint.yml",
},
"MyCustomLinter1" => {
"a" => "value for a",
Expand Down Expand Up @@ -332,7 +332,7 @@ class MySchema < ERBLint::LinterConfig
end

it "inherits from a gem if file load is not provided" do
create_file("#{gem_root}/gemone/config/erb-lint.yml", <<-YAML.strip_indent)
create_file("#{gem_root}/gemone/config/erb_lint.yml", <<-YAML.strip_indent)
MyCustomLinter:
my_option: custom value
YAML
Expand All @@ -346,7 +346,7 @@ class MySchema < ERBLint::LinterConfig

runner_config = described_class.new(
"inherit_gem" => {
"gemone" => "config/erb-lint.yml",
"gemone" => "config/erb_lint.yml",
},
)

Expand Down

0 comments on commit c502d90

Please sign in to comment.