This describes Dart-specific guidance for checking code into //piper/third_party/dart.
IMPORTANT: Read go/thirdparty first. For Dart-specific questions, email emailremoved@.
General policies
Preserving licenses
Third-party licenses must be preserved on generated code. There are several
build rules to support Dart in google3. The dart_application
rule compiles
Dart to JavaScript. This rule automatically includes the text of any LICENSE
file included in its (or its dependencies') srcs lists in the resulting
JavaScript.
Do not approve CLs unless you are the last third-party-* reviewer
When multiple reviewers are auto-assigned to a brand-new //piper/third_party
package, only the last reviewer to LGTM should 'g4 approve
' the CL. Other
reviewers should LGTM and then defer to the remaining auto-assigned reviewers.
Adding code to google3
All new packages must be approved by someone in emailremoved@. For all
changes that involve an OWNERS
file (which should include all new packages)
third-party-removed will be added to reviewers automatically. Approval is not
required from anyone other than the OWNERS
for updates.
Criteria for importing packages
Code imported to google3 is expected to meet a similar quality bar to code written directly in google3, although no particular extensive code review is required. The third-party-removed members may request that a package not be imported if it appears risky. Imported code must:
- Have tests that can run and pass in google3.
- Avoid antipatterns like debug
print
statements. - Not have obvious signs of quality issues.
- Be compatible with the current Dart SDK.
We strongly prefer that:
- The package uses code reviews for contributions.
- The code does not need patches to work in google3.
- The package has recent updates.
- The author is willing to accept contributions from googlers.
- The package demonstrates appropriate use of
semver
Packages which don't meet these criteria may be refused by the Dart reviewer. For exceptions see temporary unsupported packages.
NOTE: If a package is Flutter owned, you will see "Flutter Team" as the author on the pub listing. If it is Dart owned, you will see "Dart Team". These packages are easier to bring into Google because we own and maintain them.
We require that there are at least 2 OWNERS
for every package. These owners
are responsible for syncing new versions of the package, including working with
teams to update internal code using the package when there are breaking changes.
If you are not comfortable taking responsibility for usage outside of your
project you can make the package private in blaze and request that other
projects wishing to add a dependency add some representation in OWNERS
.
Requirements for maintaining packages
We do not allow packages to go "stale" in google3, as packages are updated and published they should be rolled into google3. It is the responsibility of the OWNERS to roll packages, and in cases of breaking changes help teams to migrate. The latest version published on pub is the authoritative version. It is allowed to have package versions in google3 that are newer than the latest published package. This is especially useful for testing and validating the code against a large code base before publishing. A package is stale if it is 1 major or feature (minor) version behind, or if it is 2 patch versions behind.
We do not allow forking packages. A package may have google3 specific patches in
exception cases to allow for differences in the google3 environment (for
instance differences in the working directory when tests are running). Copybara
patch files
are strongly preferred for managing google3 changes. If a copybara patch is not
feasible the change must be documented in the local_modifications
field of the
METADATA
file. We do not allow patches for things like reverting breaking
changes indefinitely.
Maintaining packages often means being able to submit code to upstream repo (since forking is not allowed). We strongly recommend that the OWNERS of the package become collaborators in the upstream repo as well. Most repo owners are delighted to partner up with a Googler or two, so reach out! Their emails are typically available on the pub page of the project.
Temporary Unsupported Packages
Packages that do not meet the google3 quality bar may be useful and viable after some contributions are made to improve the code health. For instance a team may decide to contribute tests. In order to allow experimentation and give teams a chance to evaluate whether an upstream contribution is worth pursuing, a package may be brought in with a 6 month window to either raise the quality of the package or delete it from google3.
Unsupported packages may not block Dart SDK or other third party package rolls. We won't roll back a CL that breaks an unsupported package.
Process:
- Restrict the blaze visibility of the package to only the team with representation in the OWNERS file. Add a note next to the visibility list that the package is unsupported and may be removed if it can't be improved.
- In the CL description include the statement "This package does not meet the google3 quality bar, it will be improved or removed by <date>".
- File a bug against a component appropriate for the project which will use the new package and CC emailremoved@. Assign to go/bugjuggler with a 5 month delay. After 5 months the bug should be assigned to the author bringing in the package. Reference this bug in the CL bug field.
- At anytime during the 6 month window if the package can be brought up to google3 standards it may "graduate" to a community supported package.
- After the 6 month period the package can be reviewed again, if it does not meet the quality bar it must be removed without exception.
After graduating to a community supported package, the visibility restriction may be lifted at the discretion of the teams with representation in OWNERS.
Process for importing packages
WARNING: The process for bringing a new Flutter plugin is different as it contains native code in addition to Dart code. Please see go/new-flutter-plugin instead of following instructions below.
- Dart source code must be placed in
//third_party/dart/<packagename>
where <packagename> matches the package name on http://linkremoved/. The resolution forpackage:
URIs relies on this directory name. - The layout of code within
//third_party/dart/<packagename>
must be identical to the pub package layout. - Every new package should be added in a separate CL (see go/pristinecopy)
Pull in the code using one of the following tools.
Copybara (preferred tool):
Follow Copybara's Getting Started (go/copybara/userdoc/getting_started.md) if you have not used Copybara before, which basically boils down to:
alias copybara='/path/to/.../copybara'
Then migrate new commits from GitHub to google3:
copybara third_party/dart/<package>/copy.bara.sky
GitHub:
blaze build //dart/tools:pullfromgit && blaze-bin/dart/tools/pullfromgit --package=<package> --version=<version> [--new_package]
Pub:
Please use only if GitHub source is not available or not tagged. SecOps prefers a GitHub source to a pub.dev source.
blaze build //dart/tools:pullfrompub && blaze-bin/dart/tools/pullfrompub --package=<package> --version=<version> [--new_package]
After pulling in the code:
Check LICENSE and ensure we can use the code. See go/thirdpartylicenses for details.
Fix inconsistencies between the public package and go/thirdparty rules. For example, if a package has a license in
LICENSE.txt
, which goes against the rule listed that the file must be namedLICENSE
, rename it.mv LICENSE.txt LICENSE g4 add LICENSE; g4 revert LICENSE.txt
Do not fix other problems, even if this means unit tests do not pass. The first commit should be the version of the code as it was downloaded (go/pristinecopy).
Create a
BUILD
file.Add a
dart_library
target that includes all srcs inlib/
, and alicense
attribute indicating the LICENSE file.dart_library( name = "lzma", srcs = glob(["lib/**/*"]), license_files = ["LICENSE"], deps = [...], )
If the package uses any platform restricted imports (
io
,ui
,html
,js
,mirrors
) add arequired_libs
argument. See go/dart-required-libsEnsure the
licenses
BUILD extension has the correct value(s).Add tests with
dart_vm_test
,dart_browser_test
, orflutter_test_suite
so the unit tests run in our Presubmit queues. Sometimes this would require modifying the source, which should not be done (per go/pristinecopy). If that is the case, add a TODO and fix in a subsequent CL.Run
buildifier -a -v
Create an
OWNERS
file with at least 2 full time googlers who are willing to commit to maintaining the package.
Updating an existing package from Git or Pub
General guidance
It (probably) won't be in google3 unless someone is using it, and it is your responsibility to ensure that the update does not break any tests. See Step-By-Step Instructions below.
Don't use
NO_SQ=
org4 submit -f
to submit a CL with broken tests. If a presubmit reveals a small number of already failing tests unrelated to your CL, or fails due to flaky tests, you may useSKIP_CLIENT_TESTS=
with a brief description of why it is needed.In contrast to new packages, batching together multiple package updates is allowed when packages are coupled.
Step-by-step instructions
We’ll use the "args" package as an example
- Review the
CHANGELOG
to familiarize yourself with any changes that could break existing code. - Make any necessary preemptive changes. go/using-rosie is your friend. Don’t
forget
replace_string
! Create a client:
mkclient -f dart_update
Take a look at the
pullfromgit.py
andpullfrompub.py
utilities:dart/tools/pullfromgit.py --helpshort
or
dart/tools/pullfrompub.py --helpshort
Use
pullfromgit.py
orpullfrompub.py
to automatically update the source:dart/tools/pullfromgit.py --package=args --version=0.12.2+2
or:
dart/tools/pullfrompub.py --package=args --version=0.12.2+2
Repeat for any other packages.
If
dependencies
ordev_dependencies
have been added or removed inpubspec.yaml
, mirror those changes inBUILD
.Make sure you're not breaking anything by checking (in order):
- Unit tests (if present):
blaze test //third_party/dart/args/...
(Optional) dart_lang & dart_lang.presubmit Presubmit queues:
presubmit -c $CL -p dart_lang,dart_lang.presubmit
The next step (global presubmit) will also run these tests, but they run much faster here than during global. If you believe the changes may cause breakages, it may be worth completing this step.
Global presubmit. See http://linkremoved/ for details:
presubmit --train -c $CL -p all
- Unit tests (if present):
If your change breaks targets in google3:
- Generate a new patch CL with the fixes (see go/using-rosie).
- Run a global presubmit to verify your fix is good.
Send it out to the appropriate owners:
For small CLs, click the "suggest reviewers" dropdown on the right hand side of the Reviewers field. If you prefer the command-line:
g4 findreviewers -c $CL
For large CLs, see go/rosie. Rosie will shard your CL, run tests (if requested), select appropriate reviewers and auto-submit your CLs for you.
Create and mail the CL. If unfamiliar, see one of:
g4 help {change, mail, submit}
- Developer Workflow Codelab.
- g4 commands.
Examples
- changelist ...230
What about third_party/dart_src
?
third_party/dart_src
was created to support internal development of packages
that do not adhere to the conventions of Dart pub packages. Parts of these
directories are published as pub packages and synced to open source repos after
transforming the code.
NOTE: Code that is developed in third_party/dart_src
should not have a version
in third_party/dart
. Please adhere to the one version policy, see
go/oneversion.
Dependencies on third_party/dart_src
packages
If your internal application has a dependency on code in third_party/dart_src
,
that is fine. Just depend on the BUILD
files you need and write your Dart
import statements like any other internal Dart file.
Example: import 'package:third_party.dart_src.foo.bar.baz/qux.dart';
If your project has a dependency on any code in third_party/dart_src
,
and you intend to publish your code as open source, let's talk. Please see
below.
Developing new public packages
The common case for most packages is to be located in third_party/dart
. Place
your code in third_party/dart_src
if:
- Internal development is demonstrably hindered by the need to adhere to Dart pub package conventions.
- Code that is open source will have dependencies on code in
third_party/dart_src
.
We are developing a simple and maintainable process for syncing code between
third_party/dart_src
and open source repos like GitHub. Tooling is under
development to automate this process using go/copybara.