{"id":13533005,"url":"https://github.com/sds/haml-lint","last_synced_at":"2025-05-13T23:04:19.907Z","repository":{"id":10588881,"uuid":"12800433","full_name":"sds/haml-lint","owner":"sds","description":"Tool for writing clean and consistent HAML","archived":false,"fork":false,"pushed_at":"2025-05-06T00:00:13.000Z","size":1330,"stargazers_count":324,"open_issues_count":8,"forks_count":103,"subscribers_count":47,"default_branch":"main","last_synced_at":"2025-05-10T16:43:00.716Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sds.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"MIT-LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2013-09-13T03:14:56.000Z","updated_at":"2025-05-06T00:00:15.000Z","dependencies_parsed_at":"2024-01-23T01:28:14.049Z","dependency_job_id":"16dc25d2-d052-4c09-949a-a3a27552f10e","html_url":"https://github.com/sds/haml-lint","commit_stats":{"total_commits":720,"total_committers":80,"mean_commits":9.0,"dds":"0.40555555555555556","last_synced_commit":"66fa742010ff24dd0dbf8c53186c17bc0648a3f5"},"previous_names":["brigade/haml-lint"],"tags_count":89,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sds%2Fhaml-lint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sds%2Fhaml-lint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sds%2Fhaml-lint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sds%2Fhaml-lint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sds","download_url":"https://codeload.github.com/sds/haml-lint/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254040486,"owners_count":22004551,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T07:01:15.782Z","updated_at":"2025-05-13T23:04:19.887Z","avatar_url":"https://github.com/sds.png","language":"Ruby","funding_links":[],"categories":["Ruby","Other","Awesome Ruby CLIs"],"sub_categories":["Linting"],"readme":"# HAML-Lint\n\n[![Gem Version](https://badge.fury.io/rb/haml_lint.svg)](http://badge.fury.io/rb/haml_lint)\n[![Build Status](https://github.com/sds/haml-lint/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/sds/haml-lint/actions/workflows/tests.yml?branch=main)\n[![Maintainability](https://api.codeclimate.com/v1/badges/b1f81df6b0922ff5bcdd/maintainability)](https://codeclimate.com/github/sds/haml-lint/maintainability)\n[![Coverage Status](https://coveralls.io/repos/sds/haml-lint/badge.svg)](https://coveralls.io/r/sds/haml-lint)\n[![Inline docs](http://inch-ci.org/github/sds/haml-lint.svg?branch=master)](http://inch-ci.org/github/sds/haml-lint)\n\n`haml-lint` is a tool to help keep your [HAML](http://haml.info) files\nclean and readable. In addition to HAML-specific style and lint checks, it\nintegrates with [RuboCop](https://github.com/rubocop/rubocop) to bring its\npowerful static analysis tools to your HAML documents.\n\nExperimental auto-correct features are also available.\n\nYou can run `haml-lint` manually from the command line, or integrate it into\nyour [SCM hooks](https://github.com/sds/overcommit).\n\n* [Requirements](#requirements)\n* [Installation](#installation)\n* [Usage](#usage)\n* [Autocorrection](#autocorrection)\n* [Configuration](#configuration)\n* [Linters](#linters)\n* [Editor Integration](#editor-integration)\n* [Git Integration](#git-integration)\n* [Rake Integration](#rake-integration)\n* [Documentation](#documentation)\n* [Contributing](#contributing)\n* [Community](#community)\n* [Changelog](#changelog)\n* [License](#license)\n\n## Requirements\n\n * Ruby 3+\n * HAML 5.0+\n\n## Installation\n\n```bash\ngem install haml_lint\n```\n\nIf you'd rather install `haml-lint` using `bundler`, don't `require` it in your `Gemfile`:\n\n```ruby\ngem 'haml_lint', require: false\n```\n\nThen you can still use `haml-lint` from the command line, but its source code won't be auto-loaded inside your application.\n\n## Usage\n\nRun `haml-lint` from the command line by passing in a directory (or multiple\ndirectories) to recursively scan:\n\n```bash\nhaml-lint app/views/\n```\n\nYou can also specify a list of files explicitly:\n\n```bash\nhaml-lint app/**/*.html.haml\n```\n\n`haml-lint` will output any problems with your HAML, including the offending\nfilename and line number.\n\n### File Encoding\n\n`haml-lint` assumes all files are encoded in UTF-8.\n\n### Command Line Flags\n\nCommand Line Flag          | Description\n---------------------------|----------------------------------------------------\n`--auto-gen-config`        | Generate a configuration file acting as a TODO list\n`--auto-gen-exclude-limit` | Number of failures to allow in the TODO list before the entire rule is excluded\n`-c`/`--config`            | Specify which configuration file to use\n`-e`/`--exclude`           | Exclude one or more files from being linted\n`-i`/`--include-linter`    | Specify which linters you specifically want to run\n`-x`/`--exclude-linter`    | Specify which linters you _don't_ want to run\n`-r`/`--reporter`          | Specify which reporter you want to use to generate the output\n`-a`/`--auto-correct`      | Enables auto-correct for safe to auto-correct lints\n`-A`/`--auto-correct-all`  | Enables auto-correct for unsafe and safe to auto-correct lints\n`--auto-correct-only`      | Only run auto-correct (in safe mode by default), uncorrectable linters are not run\n`-p`/`--parallel`          | Run linters in parallel using available CPUs\n`--fail-fast`              | Specify whether to fail after the first file with lint\n`--fail-level`             | Specify the minimum severity (warning or error) for which the lint should fail\n`--[no-]color`             | Whether to output in color\n`--[no-]summary`           | Whether to output a summary in the default reporter\n`--show-linters`           | Show all registered linters\n`--show-reporters`         | Display available reporters\n`-s`/`--stdin FILE`        | Pipe source from STDIN, using FILE in offense when combined with --auto-correct and --stdin\n`--stderr`                 | Write all output to stderr\n`-h`/`--help`              | Show command line flag documentation\n`-v`/`--version`           | Show `haml-lint` version\n`-V`/`--verbose-version`   | Show `haml-lint`, `haml`, and `ruby` version information\n\n## Autocorrection\n\n`haml-lint` can automatically correct some of the errors that it detects. This includes\nrunning RuboCop on the Ruby parts of your HAML templates.\n\n* Run `haml-lint -a` to only do safe corrections (as defined by RuboCop)\n* Run `haml-lint -A` to also do unsafe corrections (as defined by RuboCop)\n\n## Configuration\n\n`haml-lint` will automatically recognize and load any file with the name\n`.haml-lint.yml` as a configuration file. It loads the configuration based on\nthe directory `haml-lint` is being run from, ascending until a configuration\nfile is found. Any configuration loaded is automatically merged with the\ndefault configuration (see `config/default.yml`).\n\nHere's an example configuration file:\n\n```yaml\nlinters:\n  ImplicitDiv:\n    enabled: false\n    severity: error\n\n  LineLength:\n    max: 100\n```\n\nAll linters have an `enabled` option which can be `true` or `false`, which\ncontrols whether the linter is run, along with linter-specific options. The\ndefaults are defined in [`config/default.yml`](config/default.yml).\n\n### Linter Options\n\nOption        | Description\n--------------|----------------------------------------------------------------\n`enabled`     | If `false`, this linter will never be run. This takes precedence over any other option.\n`include`     | List of files or glob patterns to scope this linter to. This narrows down any files specified via the command line.\n`exclude`     | List of files or glob patterns to exclude from this linter. This excludes any files specified via the command line or already filtered via the `include` option.\n`severity`    | The severity of the linter. External tools consuming `haml-lint` output can use this to determine whether to warn or error based on the lints reported.\n\n### Global File Exclusion\n\nThe `exclude` global configuration option allows you to specify a list of files\nor glob patterns to exclude from all linters. This is useful for ignoring\nthird-party code that you don't maintain or care to lint. You can specify a\nsingle string or a list of strings for this option.\n\n### Skipping Frontmatter\n\nSome static blog generators such as [Jekyll](http://jekyllrb.com/) include\nleading frontmatter to the template for their own tracking purposes.\n`haml-lint` allows you to ignore these headers by specifying the\n`skip_frontmatter` option in your `.haml-lint.yml` configuration:\n\n```yaml\nskip_frontmatter: true\n```\n\n### Inheriting from Other Configuration Files\n\nThe `inherits_from` global configuration option allows you to specify an\ninheritance chain for a configuration file. It accepts either a scalar value of\na single file name or a vector of multiple files to inherit from. The inherited\nfiles are resolved in a first in, first out order and with \"last one wins\"\nprecedence. For example:\n\n```yaml\ninherits_from:\n  - .shared_haml-lint.yml\n  - .personal_haml-lint.yml\n```\n\nFirst, the default configuration is loaded. Then the `.shared_haml-lint.yml`\nconfiguration is loaded, followed by `.personal_haml-lint.yml`. Each of these\noverwrite each other in the event of a collision in configuration value. Once\nthe inheritance chain is resolved, the base configuration is loaded and applies\nits rules to overwrite any in the intermediate configuration.\n\nLastly, in order to match your RuboCop configuration style, you can also use the\n`inherit_from` directive, which is an alias for `inherits_from`.\n\n## Linters\n\n### [» Linters Documentation](lib/haml_lint/linter/README.md)\n\n`haml-lint` is an opinionated tool that helps you enforce a consistent style in\nyour HAML files. As an opinionated tool, we've had to make calls about what we\nthink are the \"best\" style conventions, even when there are often reasonable\narguments for more than one possible style. While all of our choices have a\nrational basis, we think that the opinions themselves are less important than\nthe fact that `haml-lint` provides us with an automated and low-cost means of\nenforcing consistency.\n\n### Custom Linters\n\nAdd the following to your configuration file:\n\n```yaml\nrequire:\n  - './relative/path/to/my_first_linter.rb'\n  - 'absolute/path/to/my_second_linter.rb'\n```\n\nThe files that are referenced by this config should have the following structure:\n\n```ruby\nmodule HamlLint\n  # MyFirstLinter is the name of the linter in this example, but it can be anything\n  class Linter::MyFirstLinter \u003c Linter\n    include LinterRegistry\n\n    def visit_tag\n      return unless node.tag_name == 'div'\n      record_lint(node, \"You're not allowed divs!\")\n    end\n  end\nend\n```\n\nFor more information on the different types on HAML node, please look through\nthe HAML parser code: https://github.com/haml/haml/blob/main/lib/haml/parser.rb\n\nKeep in mind that by default your linter will be disabled by default. So you\nwill need to enable it in your configuration file to have it run.\n\n## Disabling Linters within Source Code\n\nOne or more individual linters can be disabled locally in a file by adding\na directive comment. These comments look like the following:\n\n```haml\n-# haml-lint:disable AltText, LineLength\n[...]\n-# haml-lint:enable AltText, LineLength\n```\n\nYou can disable *all* linters for a section with the following:\n\n```haml\n-# haml-lint:disable all\n```\n\n### Directive Scope\n\nA directive will disable the given linters for the scope of the block. This\nscope is inherited by child elements and sibling elements that come after the\ncomment. For example:\n\n```haml\n-# haml-lint:disable AltText\n#content\n  %img#will-not-show-lint-1{ src: \"will-not-show-lint-1.png\" }\n  -# haml-lint:enable AltText\n  %img#will-show-lint-1{ src: \"will-show-lint-1.png\" }\n  .sidebar\n    %img#will-show-lint-2{ src: \"will-show-lint-2.png\" }\n%img#will-not-show-lint-2{ src: \"will-not-show-lint-2.png\" }\n```\n\nThe `#will-not-show-lint-1` image on line 2 will not raise an `AltText` lint\nbecause of the directive on line 1. Since that directive is at the top level of\nthe tree, it applies everywhere.\n\nHowever, on line 4, the directive enables the `AltText` linter for the remainder\nof the `#content` element's content. This means that the `#will-show-lint-1`\nimage on line 5 will raise an `AltText` lint because it is a sibling of the\nenabling directive that appears later in the `#content` element. Likewise, the\n`#will-show-lint-2` image on line 7 will raise an `AltText` lint because it is\na child of a sibling of the enabling directive.\n\nLastly, the `#will-not-show-lint-2` image on line 8 will not raise an `AltText`\nlint because the enabling directive on line 4 exists in a separate element and\nis not a sibling of the it.\n\n### Directive Precedence\n\nIf there are multiple directives for the same linter in an element, the last\ndirective wins. For example:\n\n```haml\n-# haml-lint:enable AltText\n%p Hello, world!\n-# haml-lint:disable AltText\n%img#will-not-show-lint{ src: \"will-not-show-lint.png\" }\n```\n\nThere are two conflicting directives for the `AltText` linter. The first one\nenables it, but the second one disables it. Since the disable directive came\nlater, the `#will-not-show-lint` element will not raise an `AltText` lint.\n\nYou can use this functionality to selectively enable directives within a file by\nfirst using the `haml-lint:disable all` directive to disable all linters in the\nfile, then selectively using `haml-lint:enable` to enable linters one at a time.\n\n## Onboarding Onto a Preexisting Project\n\nAdding a new linter into a project that wasn't previously using one can be\na daunting task. To help ease the pain of starting to use Haml-Lint, you can\ngenerate a configuration file that will exclude all linters from reporting lint\nin files that currently have lint. This gives you something similar to a to-do\nlist where the violations that you had when you started using Haml-Lint are\nlisted for you to whittle away, but ensuring that any views you create going\nforward are properly linted.\n\nTo use this functionality, call Haml-Lint like:\n\n    haml-lint --auto-gen-config\n\nThis will generate a `.haml-lint_todo.yml` file that contains all existing lint\nas exclusions. You can then add `inherits_from: .haml-lint_todo.yml` to your\n`.haml-lint.yml` configuration file to ensure these exclusions are used whenever\nyou call `haml-lint`.\n\nBy default, any rules with more than 15 violations will be disabled in the todo-file.\nYou can increase this limit with the `auto-gen-exclude-limit` option:\n\n    haml-lint --auto-gen-config --auto-gen-exclude-limit 100\n\n\n## Editor Integration\n\n### Vim\n\nIf you use `vim`, you can have `haml-lint` automatically run against your HAML\nfiles after saving by using the\n[Syntastic](https://github.com/vim-syntastic/syntastic) plugin. If you already\nhave the plugin, just add `let g:syntastic_haml_checkers = ['haml_lint']` to\nyour `.vimrc`.\n\n### Vim 8 / Neovim\n\nIf you use `vim` 8+ or `Neovim`, you can have `haml-lint` automatically run against your HAML files as you type by using the [Asynchronous Lint Engine (ALE)](https://github.com/dense-analysis/ale) plugin. ALE will automatically lint your HAML files if it detects `haml-lint` in your `PATH`.\n\n### Sublime Text 3\n\nIf you use `SublimeLinter 3` with `Sublime Text 3` you can install the\n[SublimeLinter-haml-lint](https://github.com/SublimeLinter/SublimeLinter-haml-lint)\nplugin using [Package Control](https://packagecontrol.io).\n\n### Atom\n\nIf you use `atom`, you can install the [linter-haml](https://github.blog/2022-06-08-sunsetting-atom) plugin.\n\n### TextMate 2\n\nIf you use `TextMate 2`, you can install the [Haml-Lint.tmbundle](https://github.com/jjuliano/Haml-Lint.tmbundle) bundle.\n\n### Visual Studio Code\n\nIf you use `Visual Studio Code`, you can install the [Haml Lint](https://marketplace.visualstudio.com/items?itemName=aki77.haml-lint) extension\n\n### RubyMine\n\nIf you use `RubyMine`, you can install the [HamlLint](https://plugins.jetbrains.com/plugin/21585-hamllint) plugin.\n\n## Git Integration\n\nIf you'd like to integrate `haml-lint` into your Git workflow, check out our\nGit hook manager, [overcommit](https://github.com/sds/overcommit).\n\n## Rake Integration\n\nTo execute `haml-lint` via a [Rake](https://github.com/ruby/rake) task, make\nsure you have `rake` included in your gem path (e.g. via `Gemfile`) add the\nfollowing to your `Rakefile`:\n\n```ruby\nrequire 'haml_lint/rake_task'\n\nHamlLint::RakeTask.new\n```\n\nBy default, when you execute `rake haml_lint`, the above configuration is\nequivalent to running `haml-lint .`, which will lint all `.haml` files in the\ncurrent directory and its descendants.\n\nYou can customize your task by writing:\n\n```ruby\nrequire 'haml_lint/rake_task'\n\nHamlLint::RakeTask.new do |t|\n  t.config = 'custom/config.yml'\n  t.files = ['app/views', 'custom/*.haml']\n  t.quiet = true # Don't display output from haml-lint to STDOUT\nend\n```\n\nYou can also use this custom configuration with a set of files specified via\nthe command line:\n\n```\n# Single quotes prevent shell glob expansion\nrake 'haml_lint[app/views, custom/*.haml]'\n```\n\nFiles specified in this manner take precedence over the task's `files`\nattribute.\n\n## Documentation\n\n[Code documentation] is generated with [YARD] and hosted by [RubyDoc.info].\n\n[Code documentation]: https://www.rubydoc.info/github/sds/haml-lint/main\n[YARD]: http://yardoc.org/\n[RubyDoc.info]: https://www.rubydoc.info\n\n## Contributing\n\nWe love getting feedback with or without pull requests. If you do add a new\nfeature, please add tests so that we can avoid breaking it in the future.\n\nSpeaking of tests, we use [Appraisal] to test against both HAML 5 and 6. We use\n`rspec` to write our tests. To run the test suite, execute the following from\nthe root directory of the repository:\n\n```bash\nappraisal bundle install\nappraisal bundle exec rspec\n```\n\nTo run the test suite faster (about 4x), you can skip the RuboCop invocations for testing\nauto-correct with this command:\n```bash\nSTUB_RUBOCOP=true appraisal bundle exec rspec\n```\n\n[Appraisal]: https://github.com/thoughtbot/appraisal\n\n## Community\n\nAll major discussion surrounding HAML-Lint happens on the\n[GitHub issues page](https://github.com/sds/haml-lint/issues).\n\n## Changelog\n\nIf you're interested in seeing the changes and bug fixes between each version\nof `haml-lint`, read the [HAML-Lint Changelog](CHANGELOG.md).\n\n## License\n\nThis project is released under the [MIT license](MIT-LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsds%2Fhaml-lint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsds%2Fhaml-lint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsds%2Fhaml-lint/lists"}