Skip to content

Latest commit

 

History

History
252 lines (191 loc) · 8.78 KB

CONTRIBUTING.md

File metadata and controls

252 lines (191 loc) · 8.78 KB

Contributing to Artichoke

👋 Hi and welcome to Artichoke. Thanks for taking the time to contribute! 💪💎🙌

Artichoke aspires to be an MRI Ruby-compatible implementation of the Ruby programming language. There is lots to do.

If Artichoke does not run Ruby source code in the same way that MRI does, it is a bug and we would appreciate if you filed an issue so we can fix it.

If you would like to contribute code 👩‍💻👨‍💻, find an issue that looks interesting and leave a comment that you're beginning to investigate. If there is no issue, please file one before beginning to work on a PR. Good first issues are labeled E-easy.

Discussion

If you'd like to engage in a discussion outside of GitHub, you can join Artichoke's public Discord server.

Implementation Philosophy

Setup

Artichoke includes Rust, Ruby, C, and Text sources. Developing on Artichoke requires configuring several dependencies.

Rust Toolchain

Artichoke depends on Rust and several compiler plugins for linting and formatting. The specific version of Rust that Artichoke requires is specified in the toolchain file.

Toolchain requirements are documented in BUILD.md.

C Toolchain

Some Artichoke dependencies, like the mruby sys module and the onig crate, build C static libraries and require a C compiler.

Toolchain requirements are documented in BUILD.md.

Ruby

Artichoke requires a recent Ruby and bundler for development tasks. The .ruby-version file in this repository specifies the preferred Ruby toolchain.

Ruby is not required to build Artichoke.

If you use RVM, you can install Ruby dependencies by running:

rvm install "$(cat .ruby-version)"
gem install bundler

If you use rbenv and ruby-build, you can install Ruby dependencies by running:

rbenv install "$(cat .ruby-version)"
gem install bundler
rbenv rehash

The Gemfile in Artichoke specifies several dev dependencies. You can install these dependencies by running:

bundle install

Artichoke uses rake as a task runner. You can see the available tasks by running:

$ bundle exec rake --tasks
rake build                         # Build Rust workspace
rake build:all                     # Build Rust workspace and sub-workspaces
rake bundle:audit:check            # Checks the Gemfile.lock for insecure dependencies
rake bundle:audit:update           # Updates the bundler-audit vulnerability database
rake deps:firstparty               # List first-party crate dependencies
rake deps:thirdparty               # List third-party crate dependencies
rake doc                           # Generate Rust API documentation
rake doc:open                      # Generate Rust API documentation and open it in a web browser
rake fmt                           # Format sources
rake fmt:c                         # Format .c and .h sources with clang-format
rake fmt:rust                      # Format Rust sources with rustfmt
rake fmt:text                      # Format text, YAML, and Markdown sources with prettier
rake format                        # Format sources
rake format:c                      # Format .c and .h sources with clang-format
rake format:rust                   # Format Rust sources with rustfmt
rake format:text                   # Format text, YAML, and Markdown sources with prettier
rake lint                          # Lint sources
rake lint:clippy                   # Lint Rust sources with Clippy
rake lint:clippy:restriction       # Lint Rust sources with Clippy restriction pass (unenforced lints)
rake lint:rubocop                  # Run RuboCop
rake lint:rubocop:autocorrect      # Autocorrect RuboCop offenses (only when it's safe)
rake lint:rubocop:autocorrect_all  # Autocorrect RuboCop offenses (safe and unsafe)
rake release:markdown_link_check   # Check for broken links in markdown files
rake sanitizer:leak                # Run Artichoke with LeakSanitizer
rake spec                          # Run enforced ruby/spec suite
rake test                          # Run Artichoke unit tests
rake test:all                      # Run all tests
rake test:fuzz                     # Run fuzz tests (Fuzz the interpreter for crashes with arbitrary input)
rake test:ui                       # Run ui tests (check exact stdout/stderr of Artichoke binaries)
rake test:unit                     # Run unit tests
rake toolchain:sync                # Sync Rust toolchain to all sources
rake toolchain:sync:ci             # Sync the root rust-toolchain version to CI jobs
rake toolchain:sync:manifests      # Sync the root rust-toolchain version to all crate manifests

To lint Ruby sources, Artichoke uses RuboCop. RuboCop runs as part of the lint task. To run RuboCop by itself, invoke the lint:rubocop task.

$ bundle exec rake lint
$ bundle exec rake lint:rubocop

Node.js

Node.js is an optional dependency that is used for formatting text sources with prettier.

Node.js is only required for formatting if modifying the following filetypes:

  • c
  • h
  • html
  • json
  • md
  • toml
  • yaml
  • yml

You will need to install Node.js. On macOS, you can install Node.js with Homebrew:

brew install node

Code Quality

Linting

Once you configure a development environment, run the following to lint and format sources:

bundle exec rake

Merges will be blocked by CI if there are lint errors.

Testing

A PR must have new or existing tests for it to be merged. The Rust book chapter on testing is a good place to start. If you'd like to see some examples in Artichoke, take a look at:

To run tests:

bundle exec rake test

If you are only working on one crate, it can speed up iteration time to only build and run tests for that crate:

cargo test -p artichoke-backend

cargo test accepts a filter argument that will limit test execution to tests that substring match. For example, to run all of the Ruby/Rust Boolean conversion tests:

cargo test -p artichoke-backend convert::boolean

Tests are run for every PR. All builds must pass before merging a PR.

Updating Dependencies

Rust Toolchain

Upgrades to the Rust toolchain should happen in a dedicated PR that addresses any changes to ructc warnings and clippy lints. See artichoke/artichoke#482 for an example.

Rust Crates

Version specifiers in Cargo.toml are NPM caret-style by default. A version specifier of 4.1.2 means 4.1.2 <= version < 5.0.0.

To see what crates are outdated, you can use cargo-outdated.

If you need to pull in an updated version of a crate for a bugfix or a new feature, update the version number in Cargo.toml. See artichoke/artichoke#548 for an example.

Regular dependency bumps are handled by @dependabot.