Skip to content

Instantly share code, notes, and snippets.

@zzak
Last active December 17, 2015 00:11
Show Gist options
  • Save zzak/c007d8cb1d4e4b180528 to your computer and use it in GitHub Desktop.
Save zzak/c007d8cb1d4e4b180528 to your computer and use it in GitHub Desktop.
contributing to ruby

Contributing to Ruby

Ruby has a vast and friendly community with hundreds of people contributing to a thriving open-source ecosystem. This guide is designed to cover ways for participating in the development of MRI.

There are plenty of ways for you to help, even if you’re not ready to write code or documentation, you can help by reporting issues, testing patches, and trying out beta releases with your applications.

How To Report

If you’ve encounted a bug in Ruby you should report it to the redmine issue tracker available at bugs.ruby-lang.org. Please do not report security vulnerabilities here, there is a separate channel for them.

There’s a few simple steps you should follow, in order to receive feedback on your ticket.

  • If you haven’t already, sign up for an account on the bug tracker.

  • Try the latest version. If you aren’t already using the latest version, try installing a newer stable release. See Downloading Ruby.

  • Look to see if anyone already reported your issue, try searching on redmine for your problem.

  • If you can’t find a ticket addressing your issue, create a new one.

  • Choose the target version, usually current. Bugs will be first fixed in the current release and then backported.

  • Fill in the Ruby version you’re using when experiencing this issue (ruby -v).

  • Attach any logs or reproducible programs to provide additional information, reproducible scripts should be as small as possible.

  • Briefly describe your problem, should be within 2-3 sentences to ensure a quick response.

  • Pick a category, such as core for common problems, or lib for a standard library.

  • Check the Maintainers list and assign the ticket if there is an active maintainer for the library or feature.

  • If the ticket doesn’t have any replies after 10 days, you can send a reminder.

  • Please reply to feedback requests. If a bug report doesn’t get any feedback, it’ll eventually get rejected.

Reporting Security Issues

Security vulnerabilities receive special treatment due to the nature of potential backlash. There is a private mailing list, that all security issues should be reported to and will be handled discretely. Email the security@ruby-lang.org (the PGP public key) list and the problem will be published after fixes have been released.

Resolve Existing Issues

As a next step beyond reporting issues, you can help the core team resolve existing issues. If you check the Everyone’s Issues list in GitHub Issues, you’ll find lots of issues already requiring attention. What can you do for these? Quite a bit, actually:

When a bug report goes for a while without any feedback, it goes to the bug graveyard which is unfortunate. If you check the issues list you’ll find lots of delinquent bugs already requiring attention.

You can help by verifying the existing tickets, try to reproduce the reported issue on your own and comment if you still experience the bug. Some issues lack attention because of too much ambiguity, to help you can narrow down the problem and provide more specific details or instructions to reproduce the bug. You might also try contributing a failing test in the form of a patch, which we will cover later in this guide.

It may also help to try out patches other contributors have submitted to redmine, if gone without notice. In this case the patch command is your friend, see man patch for more information. Basically this would go something like this:

cd path/to/ruby/trunk
patch -p0 < path/to/patch

You will then be prompted to apply the patch with the associated files. After building ruby again, you should try to run the tests and verify if the change actually worked or fixed the bug. It’s important to provide valuable feedback on the patch that can help reach the overal goal, try to answer some of these questions:

  • What do you like about this change?

  • What would you do differently?

  • Are there any other edge cases not tested?

  • Is there any documentation that would be affected by this change?

If you can answer some or all of these questions, you’re on the right track. If your comment simply says “+1”, then odds are that other reviewers aren’t going to take it too seriously. Show that you took the time to review the patch.

How To Request Features

If there’s a new feature that you want to see added to Ruby, you’ll need to write a convincing proposal and patch to implement the feature.

For new features in MRI, use the ‘Feature’ tracker on ruby-trunk. For non MRI dependent features, that would apply to all Ruby implementations such as JRuby and Rubinius, use the CommonRuby tracker.

When writing a proposal, be sure to check for previous discussions on the topic and have a solid use case. You will need to be persuasive and convince Matz on your new feature. You should also consider the potential compatibility issues that this new feature might raise.

Consider making your feature into a gem, and if there are enough people who benefit from your feature it could help persuade ruby-core. Although feature requests can seem like an alluring way to contribute to Ruby, unfortunately often these discussions can lead nowhere and exhaust time and energy that could be better spent attending the glaring bug list. Choose your battles.

A good template for feature proposal should look something like this:

Abstract

Summary of your feature

Background

Describe current behavior and why it is problem. Related work, such as solutions in other language helps us to understand the problem.

Proposal

Describe your proposal in details

Details

If it has complicated feature, describe it

Usecase

Usecase of your proposal

Discussion

Discuss about this proposal. For example, list of Pros. and Cons. is nice for fair discussion.

Limitation

Limitation of your proposal

Another alternative proposal

If there are alternative proposals, show them.

See also

Links to the other related resources

Backport Requests

When a new version of Ruby is released it starts at patch level 0 (p0), and bugs will be fixed first on trunk, or edge. If its determined that a bug exists in a previous version of Ruby that is still in the bug fix stage of maintenence, then a patch will be backported. After the maintenance stage of a particular Ruby version ends, it goes into “security fix only” mode which means only security related vulnerabilities will be backported. Versions in End-of-life (EOL) will not receive any updates and it is recommended you upgrade as soon as possible.

If a major security fix is found, or after a certain amount of time since the last patch level release, a new release will be made.

When submitting a backport request, please confirm the bug has been fixed in newer versions and exists in maintenance mode versions. There is a backport tracker for each major version still in maintenance, where you can request a particular revision merged in the affected version of Ruby.

Each major version of Ruby has a release manager that should be assigned to handle backport requests. You can find the list of release managers on the wiki.

Running tests

In order to help resolve existing issues and contributing patches to Ruby, you need to be able to run the test suite.

MRI uses subversion for source control, you can find installation instructions and lots of great info to learn subversion on the svnbook.red-bean.com. For other resources see the ruby-core documentation on ruby-lang.org.

This guide will use git for contributing, the git homepage has installation instructions, with links to documentation for learning more about git. There is a mirror of the subversion repository on github.

Install the prerequisite dependencies for building the MRI interpreter to run tests.

  • C compiler

  • autoconf

  • bison

  • gperf

  • ruby - Ruby itself is prerequisite in order to build Ruby 1.9. It can be 1.8.

You should also have access to development headers for the following libraries:

  • Tcl/Tk

  • NDBM/QDBM

  • GDBM

  • Ncurses (or something)

  • OpenSSL

  • readline/editline(libedit)

  • zlib

  • libffi

  • libyaml

  • libexecinfo (FreeBSD)

Now let’s build MRI:

  • Checkout the MRI source code:

    git clone git://github.com/ruby/ruby.git ruby-trunk
  • Generate the configuration files and build:

    cd ruby-trunk
    autoconf
    mkdir build && cd build # its good practice to build outside of source dir
    mkdir ~/.rubies # we will install to .rubies/ruby-trunk in our home dir
    ../configure --prefix=~/.rubies/ruby-trunk
    make && make install

After adding Ruby to your PATH, you should be ready to run the test suite:

make test

You can also use test-all to run all of the tests with the RUNRUBY interpreter just built. Use TESTS or RUNRUBYOPT to pass parameters, such as:

make test-all TESTS=-v

This is also how you can run a specific test from our build dir:

make test-all TESTS=../test/drb/test_drb.rb

For older versions of Ruby you’ll need to run the build setup again after checking out the associated branch in git, for example if you wanted to checkout 1.9.3:

git clone git://github.com/ruby/ruby.git --branch ruby_1_9_3

Contributing Documentation

If you’re interested in contributing documentation directly to the MRI source, there is a wealth of information available at documenting-ruby.org.

There is also the Ruby Reference Manual in Japanese.

Contributing A Patch

First thing you should do is grab the code, if you haven’t already:

git clone git://github.com/ruby/ruby.git ruby-trunk

Now create a dedicated branch:

cd ruby-trunk
git checkout -b my_new_branch

The name of your branch doesn’t really matter, because it will only exist on your local computer and won’t be part of the official Ruby repository. It will be used to create patches based on the differences between your branch and trunk, or edge Ruby.

Here are some general rules to follow when writing Ruby and C code for MRI:

  • Indent 4 space tabs for C

  • Indent 2 space tabs for Ruby

  • Do not use TABs in ruby codes

  • Use TAB instead of 8 SPs in C. (Emacs’s default style)

  • ANSI C style for 1.9+ for function declarations

  • Follow C90 (not C99) Standard

  • PascalStyle for class/module names.

  • UNDERSCORE_SEPARATED_UPPER_CASE for other constants.

  • Capitalize words.

  • ABBRs should be all upper case.

  • Do as others do

You can use the following template for the ChangeLog entry on your commit:

Thu Jan  1 00:00:00 2004  Your Name  <yourmail@example.com>

        * filename (function): short description of this commit.
          This should include your intention of this change.
          [bug:#number] [mailinglist:number]

        * filename2 (function2): additional description for this file/function.

This follows GNU Coding Standards for Change Logs, some other requirements and tips:

  • Timestamps must be in JST (+09:00), in the style as above.

  • Two whitespaces between the timestamp and your name. Two whitespaces between your name and your mail address.

  • One blank line between the timestamp and the description.

  • Indent the description with TAB. 2nd line should begin with TAB+2SP.

  • Write a entry (*) for each change.

  • Refer to redmine issue or discussion on the mailing list.

  • For GitHub issues, use [GH-#] (such as [Fixes GH-234]

  • One blank line between entries.

  • Do as other committers do.

When you’re ready to commit, copy your ChangeLog entry into the commit message, keeping the same formatting and select your files:

git commit ChangeLog path/to/files

In the likely event that your branch becomes outdated, you will have to update your working branch:

git fetch origin
git rebase remotes/origin/master

Now that you’ve got some code you want to contribute, lets get set up to generate a patch. Start by forking the github mirror, check the github docs on forking if you get stuck here. You will also need a github account here, if you don’t yet have one.

Next copy the writable url for your fork and add it as a git remote, replace “my_username” with your github account name:

git remote add my_fork git@github.com:my_username/ruby.git
# Now we can push our branch to our fork
git push my_fork my_new_branch

In order to generate a patch that you can upload to the bug tracker, we can use the github interface to review our changes just visit github.com/my_username/ruby/compare/trunk…my_new_branch

Next, you can simply add ‘.patch’ to the end of this URL and it will generate the patch for you, save the file to your computer and upload it to the bug tracker. Alternatively you can submit a pull request, but for the best chances to receive feedback add its recommended you add it to redmine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment