• Stars
    star
    2,104
  • Rank 21,022 (Top 0.5 %)
  • Language
    Ruby
  • License
    Other
  • Created over 5 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

๐ŸŒŸ Ruby Style Guide, with linter & automatic code fixer

Tests Ruby Style Guide Gem Version

The standard gem brings the ethos of StandardJS to Ruby. It's a linter & formatter built on RuboCop and provides an unconfigurable configuration to all of RuboCop's built-in rules as well as those included in rubocop-performance. It also supports plugins built with lint_roller, like standard-rails.

Standard Ruby was created and is maintained by the team at Test Double, because we appreciate the importance of balancing predictable, consistent code with preserving developer autonomy. ๐Ÿ’š

Topics covered in this README:

Wait, did you say unconfigurable configuration?

Yes, Standard is unconfigurable. See, pretty much every developer can agree that automatically identifying and fixing slow, insecure, and error-prone code is a good idea. People also agree it's easier to work in codebases that exhibit a consistent style and format. So, what's the problem? No two developers will ever agree on what all the rules and format should be.

This has resulted in innumerable teams arguing how to configure their linters and formatters over literal decades. Some teams routinely divert time and energy from whatever they're building to reach consensus on where commas should go. Other teams have an overzealous tech lead who sets up everything his favorite way and then imposes his will on others. It's not uncommon to witness passive-aggressive programmers change a contentious rule back-and-forth, resulting in both acrimony and git churn (and acrimony about git churn). Still, most developers give way to whoever cares more, often resulting in an inconsistent configuration that nobody understands and isn't kept up-to-date with changes to their linter and its target language. Whatever the approach, time spent bikeshedding is time wasted.

But you can't configure Standard Ruby. You can take it or leave it. If this seems presumptive, constraining, and brusque: you're right, it usually does feel that way at first. But since 2018, the Ruby community has debated Standard Ruby's ruleset, ultimately landing us on a sensible set of defaults thatโ€”while no one person's favorite way to format Rubyโ€”seems to be good enough for most of the ways people use Ruby, most of the time.

If you adopt Standard Ruby, what's in it for you? Time saved that would've been spent arguing over how to set things up. Also, seamless upgrades: we stay on top of each new RuboCop rule and update our configuration on a monthly release cadence. But the best part of adopting Standard as your linter and formatter? You'll spend a whole lot less time thinking about linters and formatters.

So please, give Standard Ruby a try. If you're like these folks, you'll soon realize that the value of a linter is in using one at all and not in the particulars of how it's configured.

Usage

Install

Getting started is as easy as gem install standard or throwing it in your project's Gemfile:

gem "standard", group: [:development, :test]

Running Standard

Once installed, you can either run it as a CLI or as a Rake task.

The CLI is called standardrb to distinguish it from StandardJS:

$ standardrb

And the Rake task can be run if your Rakefile includes require "standard/rake". This will load the standard task, allowing you to run:

$ rake standard

Either way, Standard will inspect any Ruby files found in the current directory tree. If any errors are found, it'll report them. If your code is standard-compliant, it will get out of your way by quietly exiting code 0.

Fixing errors

A majority of Standard's rules can be safely fixed automatically.

# CLI
$ standardrb --fix

# Rake
$ rake standard:fix

Because we're confident Standard's fixes won't change the behavior of our code, we typically run with fix enabled all the time because it saves us from having to look at and think about problems the computer can solve for us.

Applying unsafe fixes

There are a number of other rules that can be automatically remedied, but not without the risk of changing your code's behavior. While we wouldn't recommend running it all the time, if the CLI suggests that additional errors can be fixed unsafely, here's how to do that:

# CLI
$ standardrb --fix-unsafely

# Rake
$ rake standard:fix_unsafely

So long as your code is checked into source control, there's no mortal harm in running with unsafe fixes enabled. If the changes look good to you and your tests pass, then it's probably less error prone than manually editing everything by hand.

Integrating Standard into your workflow

Because code formatting is so integral to programming productivity and linter violations risk becoming bugs if released into production, tools like Standard Ruby are only as useful as their integration into code editors and continuous integration systems.

Editor support

We've added a number of editing guides for getting started:

If you'd like to help by creating a guide, please draft one in an issue and we'll get it added!

Language Server Protocol support

If you don't see your preferred editor above, Standard Ruby also ships with a built-in language server that many modern editors can support natively, even without a Standard-specific plugin.

You can run the server by supplying the --lsp flag:

standardrb --lsp

If your editor offers LSP support, it probably has a place to configure the above command and will subsequently manage the server process for you.

CI support

Various continuous integration and quality-checking tools have been made to support Standard Ruby, as well.

Of course, no special plugin is necessary to run Standard Ruby in a CI environment, as standardrb and rake standard work just fine on their own!

Other tools

These tool integrations are also available:

Ignoring errors

While Standard is very strict in how each formatting and linting rule is configured, it's mercifully flexible when you need to ignore a violation to focus on a higher priority (like, say, keeping the build running). There are a number of ways to ignore any errors, with the right answer depending on the situation.

Ignoring a line with a comment

Individual lines can be ignored with a comment directive at the end of the line. As an example, the line text = 'hi' violates two rules, Lint/UselessAssignment and Style/StringLiterals.

You could ignore one, both, or all errors with the following comments:

# Disable one error but keep Lint/UselessAssignment
text = 'hi' # standard:disable Style/StringLiterals

# Disable both errors explicitly
text = 'hi' # standard:disable Style/StringLiterals, Lint/UselessAssignment

# Disable all errors on the line with "all"
text = "hi" # standard:disable all

Ignoring multiple lines with comments

Similarly to individual lines, you can also disable multiple lines by wrapping them in comments that disable and re-enable them:

# standard:disable Style/StringLiterals, Lint/UselessAssignment
text = "hi"
puts 'bye'
# standard:enable Style/StringLiterals, Lint/UselessAssignment

Ignoring entire files and globs

You can ignore entire files and file patterns by adding them to ignore: in your project's .standard.yml file:

ignore:
  - 'some/file/in/particular.rb'
  - 'a/whole/directory/**/*'

Ignoring specific rules in files and globs

For a given file or glob, you can even ignore only specific rules by nesting an array of the rules you'd like to ignore:

ignore:
  - 'test/**/*':
    - Layout/AlignHash

Ignoring every violation and converting them into a todo list

If you're adopting Standard in a large codebase and you don't want to convert everything all at once, you can work incrementally by generating a "todo" file which will cause Standard to ignore every violation present in each file of the codebase.

This way, you can gradually work through the todo list, removing ignore directives and fixing any associated errors, while also being alerted to any regressions if they're introduced into the project.

Here are the commands you might run to get started:

# Start by clearing any auto-fixable errors:
$ standardrb --fix

# Generate a `.standard_todo.yml' to work from
$ standardrb --generate-todo

Configuring Standard

While the rules aren't configurable, Standard offers a number of options that can be configured as CLI flags and YAML properties.

CLI flags

The easiest way to summarize the available CLI flags is to invoke standardrb -h:

Usage: standardrb [--fix] [--lsp] [-vh] [--format <name>] [--] [FILE]...

Options:

  --fix             Apply automatic fixes that we're confident won't break your code
  --fix-unsafely    Apply even more fixes, including some that may change code behavior
  --no-fix          Do not automatically fix failures
  --format <name>   Format output with any RuboCop formatter (e.g. "json")
  --generate-todo   Create a .standard_todo.yml that lists all the files that contain errors
  --lsp             Start a LSP server listening on STDIN
  -v, --version     Print the version of Standard
  -V, --verbose-version   Print the version of Standard and its dependencies.
  -h, --help        Print this message
  FILE              Files to lint [default: ./]

Standard also forwards most CLI arguments to RuboCop. To see them, run:

  $ rubocop --help

If you run Standard via Rake, you can specify your CLI flags in an environment variable named STANDARDOPTS like so:

$ rake standard STANDARDOPTS="--format progress"

YAML options

In addition to CLI flags, Standard will search for a .standard.yml file (ascending to parent directories if the current working directory doesn't contain one). If you find yourself repeatedly running Standard with the same CLI options, it probably makes more sense to set it once in a YAML file:

fix: true               # default: false
parallel: true          # default: false
format: progress        # default: Standard::Formatter
ruby_version: 3.0       # default: RUBY_VERSION
default_ignores: false  # default: true

ignore:                 # default: []
  - 'vendor/**/*'

plugins:                # default: []
  - standard-rails

extend_config:                # default: []
  - .standard_ext.yml

Configuring ruby_version

One notable YAML setting is ruby_version, which allows you to set the oldest version of Ruby the project needs to support RuboCop's TargetRubyVersion setting explicitly. Because this value is inferred from any .ruby-version, .tool-versions, Gemfile.lock, and *.gemspec files that might be present, most applications won't need to set this.

However, gems and libraries that support older versions of Ruby will want to lock the ruby-version: explicitly in their .standard.yml file to ensure new rules don't break old rubies:

ruby_version: 2.7

Extending Standard

Standard includes two extension mechanisms: plugins and configuration extensions. While neither can change the rules configured out-of-the-box by Standard, they can define, require, and configure additional RuboCop rules.

Both are "first-in-wins", meaning once a rule is configured by a plugin or extension, it can't be changed or reconfigured by a later plugin or extension. This way, each Standard plugin you add becomes a de facto "standard" of its own. Plugins have precedence over extensions as they are loaded first.

Plugins

Adding a plugin to your project is as easy as adding it to your Gemfile and specifying it in .standard.yml in the root of your project. For example, after installing standard-rails, you can configure it by adding it to plugins:

plugins:
  - standard-rails

Each plugin can be passed configuration options by specifying them in a nested hash. For example, standard-rails allows you to configure its rules for a particular version of Rails (though this will usually be detected for you automatically):

plugins:
  - standard-rails:
      target_rails_version: 7.0

You can develop your own plugins, too! Check out the lint_roller gem to learn how. For a simple example, you can look at standard-custom, which is one of the default plugins included by Standard.

Extended config files

Of course, you may want to add more rules without going to the trouble of packaging them in a plugin gem. For cases like this, you can define one or more RuboCop configuration files and then list them in your .standard.yml file under extend_config.

For example, after installing the betterlint gem from our friends at Betterment, we could create a RuboCop config file named .betterlint.yml:

require:
  - rubocop/cop/betterment.rb

Betterment/UnscopedFind:
  Enabled: true

  unauthenticated_models:
    - SystemConfiguration

And then reference it in our .standard.yml:

extend_config:
  - .betterlint.yml

Running Standard's rules via RuboCop

Please note that the following usage is not supported and may break at any time. Use at your own risk and please refrain from opening GitHub issues with respect to loading Standard or its plugins' YAML configurations for use by the rubocop CLI.

If you find that neither plugins or configuration extensions meet your needs or if you have some other reason to run Standard's rules with RuboCop's CLI (e.g., to continue using your favorite IDE/tooling/workflow with RuboCop support) Evil Martians also maintains a regularly updated guide on how to configure RuboCop to load and execute Standard's ruleset.

In short, you can configure this in your .rubocop.yml to load Standard's three default rulesets, just as you would any other gem:

require:
  - standard
  - standard-custom
  - standard-performance
  - rubocop-performance

inherit_gem:
  standard: config/base.yml
  standard-custom: config/base.yml
  standard-performance: config/base.yml

Who uses Standard Ruby?

Here are a few examples of Ruby Standard-compliant teams & projects:

Does your team use Standard? Add your name to the list!

If you really want to show off, you can also add a badge to your project's README, like this one:

Ruby Code Style

[![Ruby Code Style](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/standardrb/standard)

Help, I'm seeing an install error!

This section is really only here to feed Google, but if you see an error like any of the following:

ERROR:  Could not find a valid gem 'standard' (= 0.0.36) in any repository
Could not find gem 'standard (= 0.0.36)' in rubygems repository https://rubygems.org/ or installed locally.
Your bundle is locked to standard (0.0.36) from rubygems repository https://rubygems.org/ or installed locally, but that version can no longer be found in that source. That means the author of standard (0.0.36) has removed it. You'll need to update your bundle to a version other than standard (0.0.36) that hasn't been removed in order to install.

This is because on August 18th, 2023, we yanked versions 0.0.1~0.0.36.1 from RubyGems.org for the reasons discussed in this issue. Because these versions are now over four years old and no longer track supported versions of Ruby or RuboCop, the correct fix for any of the above errors is probably to upgrade to the latest version of Standard Ruby.

If for whatever reason you need to install one of these versions, you can change your Gemfile to point to the corresponding git tag from the source repository:

gem "standard", git: "https://github.com/testdouble/standard.git", tag: "v0.0.36"

Code of Conduct

This project follows Test Double's code of conduct for all community interactions, including (but not limited to) one-on-one communications, public posts/comments, code reviews, pull requests, and GitHub issues. If violations occur, Test Double will take any action they deem appropriate for the infraction, up to and including blocking a user from the organization's repositories.

More Repositories

1

testdouble.js

A minimal test double library for TDD with JavaScript
JavaScript
1,403
star
2

suture

๐Ÿฅ A Ruby gem that helps you refactor your legacy code
Ruby
1,401
star
3

contributing-tests

1,104
star
4

scripty

Because no one should be shell-scripting inside a JSON file.
JavaScript
957
star
5

test-smells

A workbook repository of example test smells and what to do about them.
JavaScript
421
star
6

jasmine-rails

A Jasmine runner for rails projects that's got you covered in both the terminal and the browser
JavaScript
378
star
7

referral

๐Ÿ•ต๏ธโ€โ™€๏ธ Find, filter, and sort your Ruby code's definitions & references
Ruby
343
star
8

cypress-rails

Helps you write Cypress tests of your Rails app
Ruby
312
star
9

good-migrations

Prevent Rails from auto-loading app/ code when running database migrations
Ruby
294
star
10

mocktail

๐Ÿฅƒ Take your Ruby, and make it a double!
Ruby
273
star
11

static-rails

Build & serve static sites (e.g. Jekyll, Hugo) from your Rails app
Ruby
149
star
12

maybe_later

Run code after the current Rack response or Rails action completes
Ruby
132
star
13

time_up

โฑ Create and manage multiple timers to tell where your Ruby code's time is going
Ruby
117
star
14

teenytest

A very simple, zero-config test runner for Node.js
JavaScript
97
star
15

test_data

A fast & reliable system for managing your Rails application's test data
Ruby
95
star
16

put

Ruby
92
star
17

theredoc

Makes your multi-line JavaScript strings look good
JavaScript
79
star
18

quibble

Makes it easy to replace require'd dependencies.
JavaScript
75
star
19

react-decoupler

JavaScript
55
star
20

noncommittal

A gem that ensures test isolation by preventing your Rails tests from committing to the database
Ruby
46
star
21

real-world-testing-video

testdouble/real-world-testing + screencasts
JavaScript
40
star
22

clojurescript.csv

A ClojureScript library for reading and writing CSV
Clojure
37
star
23

testdouble-jest

A testdouble.js extension to add support for Jest module mocking
JavaScript
37
star
24

grunt-markdown-blog

Grunt task for building a blog with markdown posts & underscore templates
CoffeeScript
36
star
25

ought

A dumb assertion library with smart diffs for JavaScript
JavaScript
34
star
26

cypress-capybara

Capybara finders re-implemented as custom Cypress commands
JavaScript
33
star
27

minitest-suite

Re-order your Minitest suite into logical sub-suites/groups
Ruby
32
star
28

rust-ffi-example

An example project that shows how to use FFI between Rust and Unity.
Rust
31
star
29

gem_dating

How old is that anyway?
Ruby
29
star
30

rspec-graphql_response

Verify ruby-graphql responses with a :graphql spec type
Ruby
25
star
31

ecto_resource

A simple module to clear up the boilerplate of CRUD resources in Phoenix context files.
Elixir
21
star
32

java-testing-example

An example project that's configured for JUnit and Mocha
Java
20
star
33

real-world-testing

Workshop for Testing JavaScripts
JavaScript
17
star
34

unusual-spending

A code kata for outside-in TDD in Node.js
JavaScript
16
star
35

webpacker-assets-demo

A demo repo to show how to reference images and styles when using Webpacker instead of Sprockets
Ruby
13
star
36

javascript-testing-tactics

The Missing Manual for writing great JavaScript Testing
13
star
37

magic_email_demo

An exampleย Rails app that implements passwordless authentication by emailing a magic link
Ruby
12
star
38

scheduled-merge

Merge PRs on a specified date using Labels
JavaScript
12
star
39

rust-ffi-complex-example

Follow-up project to shows how to use complex data structures between Unity and Rust.
Rust
12
star
40

todos

JavaScript
11
star
41

grunt-asset-fingerprint

CoffeeScript
9
star
42

covet

Instruct a remote Express app to stub APIs via HTTP requests
CoffeeScript
9
star
43

bored

Gives you ideas of stuff to do when you're bored
Ruby
8
star
44

rails-twitter-oauth-example

An example Rails app that implements log in to Twitter via OAuth
Ruby
8
star
45

javascript-tdd-examples

Yet another little toy repo of javascript tdd examples
JavaScript
8
star
46

baizen

BAI file format parser
Clojure
8
star
47

tiny_type

Fast, easy, and simple runtime type checking for Ruby
Ruby
8
star
48

halfpipe

A Pipedrive client for Ruby that doesn't do half of what you want it to ๐Ÿ›น
Ruby
7
star
49

forewarn

Configure method invocation warnings for deprecated or dangerous methods (e.g. mutable methods in default-frozen String literals in Ruby 3)
Ruby
7
star
50

grunt-jasmine-bundle

A "spec" grunt task for Jasmine that includes a standard pack of helpers (jasmine-given, jasmine-stealth, jasmine-only). Uses minijasminenode.
CoffeeScript
6
star
51

servme

gimme for integration tests
Ruby
6
star
52

intro-to-node

Introduction to Node.js Workshop
JavaScript
6
star
53

standardrb

You're probably in the wrong place. This is an alias for the gem standard, whose binary is standardrb
Ruby
6
star
54

bootboot-example

An example of using boot-boot.
Ruby
5
star
55

testdrivennode

Test Driven Node.js Precompiler for Codemash 2014
JavaScript
5
star
56

railsconf-test-drive-javascript

JavaScript
5
star
57

docunit

Makes sure the code examples in your docs actually work
CoffeeScript
5
star
58

json-to-svg-to-pdf

Converts JSON/CSON input through SVG templates and renders them to PDF using librsvg
JavaScript
5
star
59

imagemagick-macos-font-setup

Sets up user fonts for imagemagick on macOS
Shell
5
star
60

jasmine-before-all

Adds a done-friendly beforeAll global function to Jasmine
JavaScript
5
star
61

good-day

An example ember + active_model_serializers + rails + lineman app
JavaScript
5
star
62

sockem

A wrapper around the ActionCable JS client to ensure eventual delivery for requests
Ruby
5
star
63

satisfaction

Satisfaction tracker for your work!
Ruby
5
star
64

headerify

Browserify plugin to add a comment containing lib name, version, description, and homepage to the top of the bundle
JavaScript
4
star
65

SublimeLinter-contrib-standardrb

SublimeLinter 3 plugin for Ruby, using Standard, a wrapper for Rubocop.
Python
4
star
66

rails-upsert-all-demo

An example app that demos use of Rails 6 `upsert_all` method
Ruby
4
star
67

cobbler

A tool to generate rรฉsumรฉs for Test Double agents.
JavaScript
3
star
68

react-d3-blog-example

Example for Blog Post
JavaScript
3
star
69

supertitle

Converts between subtitles and transcript formats
Ruby
3
star
70

time_traveler_demo

A Rails app that demoes time traveling both Ruby and Postgres in lock-step with one another
Ruby
3
star
71

devops-standards

Standard Auditing Tools for DevSecOps best practices
Python
3
star
72

least

A pager that can dynamically filter log lines
Ruby
3
star
73

defuse

An API to define and use JavaScript in a module-y way. And nothing else.
JavaScript
3
star
74

lockify

Ensure an async function does not run concurrently.
JavaScript
3
star
75

jasmine-matcher-wrapper

A utility to wrap Jasmine 1.x argument matchers for use under Jasmine 2.x
CoffeeScript
3
star
76

testdouble-nock

JavaScript
3
star
77

teenytest-promise

Promise support for asynchronous teenytest tests
JavaScript
3
star
78

npm-tree

Generates a tree of all the node.js modules depended on by a module
CoffeeScript
3
star
79

function-names-at-line

Name the functions found at a particular line number in some JavaScript source
JavaScript
2
star
80

tradecraft

CSS
2
star
81

course-cypress-intro-demo-app

Demo application to supplement Test Double's End-to-end Testing with Cypress intro video course
Ruby
2
star
82

standard-ruby-action

Ruby
2
star
83

rails-training-201

A demo app for Rails 201 students to build on!
Ruby
2
star
84

testdrivennode-frontend

JavaScript
2
star
85

yslow-grader

A little Node.js wrapper for YSlow for PhantomJS
CoffeeScript
2
star
86

ios-learnins

Objective-C
2
star
87

fetcher

Fetches things based on a JSON recipe hosted in a repository
CoffeeScript
2
star
88

backbone-fixins

Boilerplate that strengthens your backbone
JavaScript
2
star
89

ruby_rails_training_github

Ruby
1
star
90

prioritize-api

Elixir
1
star
91

baruco2014-angular

Ruby
1
star
92

oredev2014-angular

JavaScript
1
star
93

double-up

Slack scheduler to set up rotating brunch pairings
Ruby
1
star
94

elm-testdouble

A minimal test double library for TDD with Elm
Elm
1
star
95

doubot

test double's hubot
CoffeeScript
1
star
96

jasmine-example

JavaScript
1
star
97

arg-that

arg-that makes it easier to assert equality on complex objects
Ruby
1
star
98

react-routing-example

Example for screencast on client-side routing in React
CSS
1
star
99

cucumber-peel

Provides a CLI to search a project's step implementations for a given step
Ruby
1
star
100

test_rails_app

A starter Rails application to test your environment setup
Ruby
1
star