Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standardize repo name to erb_lint #360

Merged
merged 10 commits into from
Sep 6, 2024
42 changes: 21 additions & 21 deletions README.md
george-ma marked this conversation as resolved.
Show resolved Hide resolved
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

george-ma marked this conversation as resolved.
Show resolved Hide resolved
$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"
george-ma marked this conversation as resolved.
Show resolved Hide resolved

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)
george-ma marked this conversation as resolved.
Show resolved Hide resolved
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
Loading