mirror of
https://github.com/danog/dart-sass.git
synced 2024-11-27 12:44:42 +01:00
24635614df
[skip ci]
218 lines
8.7 KiB
Markdown
218 lines
8.7 KiB
Markdown
Want to contribute? Great! First, read this page.
|
|
|
|
* [Before You Contribute](#before-you-contribute)
|
|
* [The Small Print](#the-small-print)
|
|
* [Development Dependencies](#development-dependencies)
|
|
* [Writing Code](#writing-code)
|
|
* [Changing the Language](#changing-the-language)
|
|
* [Changing the Node API](#changing-the-node-api)
|
|
* [Synchronizing](#synchronizing)
|
|
* [File Headers](#file-headers)
|
|
|
|
## Before You Contribute
|
|
|
|
Before we can use your code, you must sign the
|
|
[Google Individual Contributor License Agreement][cla] (CLA), which you can do
|
|
online. The CLA is necessary mainly because you own the copyright to your
|
|
changes, even after your contribution becomes part of our codebase, so we need
|
|
your permission to use and distribute your code. We also need to be sure of
|
|
various other things—for instance that you'll tell us if you know that your code
|
|
infringes on other people's patents. You don't have to sign the CLA until after
|
|
you've submitted your code for review and a member has approved it, but you must
|
|
do it before we can put your code into our codebase.
|
|
|
|
[cla]: https://cla.developers.google.com/about/google-individual
|
|
|
|
Before you start working on a larger contribution, you should get in touch with
|
|
us first through the issue tracker with your idea so that we can help out and
|
|
possibly guide you. Coordinating up front makes it much easier to avoid
|
|
frustration later on.
|
|
|
|
### The Small Print
|
|
|
|
Contributions made by corporations are covered by a different agreement than the
|
|
one above, the
|
|
[Software Grant and Corporate Contributor License Agreement][corporate cla].
|
|
|
|
[corporate cla]: https://developers.google.com/open-source/cla/corporate
|
|
|
|
## Development Dependencies
|
|
|
|
1. [Install the Dart SDK][]. If you download an archive manually rather than
|
|
using an installer, make sure the SDK's `bin` directory is on your `PATH`.
|
|
|
|
2. In this repository, run `pub get`. This will install all of the Dart
|
|
dependencies.
|
|
|
|
3. [Install Node.js][]. This is only necessary if you're making changes to Dart
|
|
Sass's Node API.
|
|
|
|
[Install the Dart SDK]: https://www.dartlang.org/install
|
|
[Install Node.js]: https://nodejs.org/en/download/
|
|
|
|
## Writing Code
|
|
|
|
Dart Sass follows the standard [Dart style guide][] wherever possible, including
|
|
using the [Dart formatter][] on all code. We also try to have no
|
|
[Dart analyzer][] warnings or hints, although if one sneaks in for a few
|
|
revisions that's not a big deal.
|
|
|
|
[Dart style guide]: https://www.dartlang.org/guides/language/effective-dart
|
|
[Dart formatter]: https://github.com/dart-lang/dart_style#readme
|
|
[Dart analyzer]: https://www.dartlang.org/tools/analyzer
|
|
|
|
Before you send a pull request, we recommend you run the following steps:
|
|
|
|
* `pub run grinder` will reformat your code using the Dart formatter to make
|
|
sure it's nice and neat, and [run the synchronizer](#synchronizing) on
|
|
asynchronous files.
|
|
|
|
* `dartanalyzer lib test` will run Dart's static analyzer to ensure that there
|
|
aren't any obvious bugs in your code. If you're using a Dart-enabled IDE, you
|
|
can also just check that there aren't any warnings in there.
|
|
|
|
* `pub run test -x node` will run the tests for the Dart VM API. These are a
|
|
good sanity check, but they aren't comprehensive; Travis CI will also run
|
|
Node.js API tests and Sass language tests, all of which must pass before your
|
|
pull request is merged. See [Changing the Language](#changing-the-language)
|
|
and [Changing the Node API](#changing-the-node-api) for more details.
|
|
|
|
### Changing the Language
|
|
|
|
If you're making a change to the Sass language, either to fix a bug or add a
|
|
feature, you'll need to write tests in the [sass-spec][] repository. This
|
|
repository contains language tests that are shared among the main Sass
|
|
implementations. Any new feature should be thoroughly tested there, and any bug
|
|
should have a regression test added.
|
|
|
|
[sass-spec]: http://github.com/sass/sass-spec
|
|
|
|
To create a new spec:
|
|
|
|
* [Fork sass-spec](https://help.github.com/articles/fork-a-repo/).
|
|
|
|
* Install [Ruby][] and [Bundler][].
|
|
|
|
* ```sh
|
|
# Replace $USER with your GitHub username.
|
|
git clone https://github.com/$USER/sass-spec
|
|
cd sass-spec
|
|
bundle install
|
|
```
|
|
|
|
* For each test case you want to add:
|
|
|
|
* Create a directory within `sass-spec/spec/` for your test. Don't worry too
|
|
much about finding exactly the right place, we'll sort that out during code
|
|
review.
|
|
|
|
* Create an `input.scss` or `input.sass` file that exercises your language
|
|
change.
|
|
|
|
* If you're testing successful output, create an `expected_output.css` file
|
|
with the output that should be produced. If you're testing an error, instead
|
|
create an `error` file with the expected error message.
|
|
|
|
* If you're adding a new language feature, it probably won't be supported by
|
|
Ruby Sass or LibSass yet. You can indicate this and keep tests passing by
|
|
adding an `options.yml` file like this to the directory containing your
|
|
tests:
|
|
|
|
```yaml
|
|
---
|
|
:todo:
|
|
- ruby-sass
|
|
- libsass
|
|
```
|
|
|
|
If you're fixing a bug, you'll only need to do this if the bug also appears
|
|
in other Sass implementations.
|
|
|
|
* Make sure all the language tests, including the new ones, are passing by
|
|
running this within `sass-spec/`:
|
|
|
|
```sh
|
|
# Replace .. with the path to dart-sass if it's not the parent directory.
|
|
bundle exec sass-spec.rb --dart ..
|
|
```
|
|
|
|
* You can also run specs within a single directory:
|
|
|
|
```sh
|
|
bundle exec sass-spec.rb --dart .. spec/my/new/feature
|
|
```
|
|
|
|
* If you pass the `--interactive` flag, `sass-spec.rb` will stop each time a
|
|
spec fails and ask you what to do about the failure.
|
|
|
|
* Once you've added specs and they're passing for Dart Sass, create a pull
|
|
request for [sass-spec][] with `[skip dart-sass]` at the end of the
|
|
message. This tells sass-spec not to run tests against the old version of Dart
|
|
Sass, since it doesn't have your changes yet.
|
|
|
|
* Finally, create a pull request for Dart Sass with a link to the sass-spec pull
|
|
request at the end of the message. This tells Dart Sass to test against your
|
|
new sass-spec tests.
|
|
|
|
[Ruby]: https://www.ruby-lang.org/en/
|
|
[Bundler]: http://bundler.io/
|
|
|
|
### Changing the Node API
|
|
|
|
Most of Dart Sass's code is shared between Dart and Node.js, but the API that's
|
|
exported by the [`sass`][npm] npm package is Node-specific. It's defined using
|
|
Dart's [JS interop package][], and it's tested by compiling the Dart package to
|
|
JS and loading that JS using JS interop to best simulate the conditions under
|
|
which it will be used in the real world.
|
|
|
|
[npm]: https://www.npmjs.com/package/sass
|
|
[JS interop]: https://pub.dartlang.org/packages/js
|
|
|
|
The tests for the Node API live in `test/node_api`. Before running them, and any
|
|
time you make a change to Dart Sass, run `pub run grinder before_test` to
|
|
compile the Dart code to JavaScript (note that you don't need to recompile if
|
|
you've only changed the test code). To run Node tests, just run
|
|
`pub run test -t node`.
|
|
|
|
### Synchronizing
|
|
|
|
Dart Sass supports two modes of operation: synchronous ([`compile()`][] and
|
|
[`compileString()`][]), which requires all importers and custom functions to be
|
|
synchronous themselves, and asynchronous ([`compileAsync()`][] and
|
|
[`compileStringAsync()`][]), which allows importers and custom functions to be
|
|
asynchronous. These modes use essentially identical logic, but because Dart
|
|
represents synchronous and asynchronous computations in fundamentally different
|
|
ways they can't share code.
|
|
|
|
[`compile()`]: https://www.dartdocs.org/documentation/sass/latest/sass/compile.html
|
|
[`compileString()`]: https://www.dartdocs.org/documentation/sass/latest/sass/compileString.html
|
|
[`compileAsync()`]: https://www.dartdocs.org/documentation/sass/latest/sass/compileAsync.html
|
|
[`compileStringAsync()`]: https://www.dartdocs.org/documentation/sass/latest/sass/compileStringAsync.html
|
|
|
|
To avoid colossal amounts of duplicated code, we have a few files that are
|
|
written in an asynchronous style originally and then compiled to their
|
|
synchronous equivalents using `tool/synchronize.dart`. In particular:
|
|
|
|
* `lib/src/visitor/async_evaluate.dart` is compiled to
|
|
`lib/src/visitor/evaluate.dart`.
|
|
* `lib/src/async_environment.dart` is compiled to `lib/src/environment.dart`.
|
|
|
|
When contributing code to these files, you should make manual changes only to
|
|
the asynchronous versions and run `pub run grinder` to compile them to their
|
|
synchronous equivalents.
|
|
|
|
Note that the `lib/src/callable/async_built_in.dart` and
|
|
`lib/src/callable/built_in.dart` files are *not* automatically synchronized;
|
|
they're so small and would require so many special cases that they're not worth
|
|
automating.
|
|
|
|
### File Headers
|
|
|
|
All files in the project must start with the following header.
|
|
|
|
```dart
|
|
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
```
|