[roller] Create a dart module to simplify flutter roller.
Currently flutter runner is doing a lot of work, we are moving dart
functionality to its own module to simplify the flutter roller.
Bug: 36488
Bug: 36497
Change-Id: If8357c3a62da36c431f6fa96e404064590a865ad
diff --git a/recipe_modules/dart_util/__init__.py b/recipe_modules/dart_util/__init__.py
new file mode 100644
index 0000000..1191469
--- /dev/null
+++ b/recipe_modules/dart_util/__init__.py
@@ -0,0 +1,18 @@
+# Copyright 2020 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+DEPS = [
+ 'fuchsia/auto_roller',
+ 'fuchsia/buildbucket_util',
+ 'fuchsia/gerrit',
+ 'fuchsia/git',
+ 'fuchsia/jiri',
+ 'recipe_engine/buildbucket',
+ 'recipe_engine/context',
+ 'recipe_engine/file',
+ 'recipe_engine/path',
+ 'recipe_engine/python',
+ 'recipe_engine/raw_io',
+ 'recipe_engine/step',
+]
diff --git a/recipe_modules/dart_util/api.py b/recipe_modules/dart_util/api.py
new file mode 100644
index 0000000..e623563
--- /dev/null
+++ b/recipe_modules/dart_util/api.py
@@ -0,0 +1,97 @@
+# Copyright 2020 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import collections
+import os
+
+from recipe_engine import recipe_api
+
+# Used to get the remote for dart sdk
+DART_SDK_PROJECT = 'dart/sdk'
+
+COMMIT_MESSAGE = """\
+[roll] Update {deps}
+
+{logs}
+
+Cq-Cl-Tag: roller-builder:{builder}
+Cq-Cl-Tag: roller-bid:{build_id}
+CQ-Do-Not-Cancel-Tryjobs: true"""
+
+
+class DartApi(recipe_api.RecipeApi):
+ """APIs to work with Dart repo and Dart packages."""
+
+ def run_update_3p_packages(self, checkout_root):
+ """Runs update_3p_packages.py in dart 3p repo checkout.
+
+ Args:
+ checkout_root (Path): The root path to the project checkouts.
+ """
+ self.m.python(
+ 'update dart 3p packages',
+ checkout_root.join('scripts', 'dart', 'update_3p_packages.py'),
+ args=['--debug'],
+ )
+
+ def update_3p_packages(self, checkout_root, dry_run):
+ """Updates fuchsia's third-party dart packages.
+
+ Args:
+ checkout_root (Path): Root path to checkouts.
+ dry_run (bool): Whether the roll will be allowed to complete or not.
+
+ Returns:
+ A string with third_party/dart-pkg/pub latest commit hash.
+ """
+ commit_msg = '[roll] Update third-party dart packages'
+ packages_root = checkout_root.join('third_party', 'dart-pkg', 'pub')
+ with self.m.context(cwd=packages_root):
+ # Make sure third_party/dart-pkg is at origin/master before running the
+ # update script to catch any manual commits that extend past the revision at
+ # integration's HEAD.
+ self.m.git('fetch', 'origin')
+ self.m.git('checkout', 'origin/master')
+ current_hash = self.m.git.get_hash()
+ self.run_update_3p_packages(checkout_root)
+ rolled = self.m.auto_roller.attempt_roll(
+ gerrit_project='third_party/dart-pkg/pub',
+ repo_dir=packages_root,
+ commit_message=commit_msg,
+ dry_run=dry_run)
+ if rolled:
+ current_hash = self.m.git.get_hash()
+ self.m.step.active_result.presentation.logs['revision'] = [current_hash]
+ return current_hash
+
+ def update_pkg_manifest(self, path, checkout_root):
+ """Overwrites a dart third party package manifest.
+
+ Args:
+ path (Path): A path to the dart/sdk repository.
+ checkout_root (Path): A path to where the integration project
+ was checked out.
+ """
+ manifest_path = checkout_root.join('fuchsia', 'topaz',
+ 'dart_third_party_pkg')
+ self.m.python(
+ name='update %s' % self.m.path.basename(manifest_path),
+ script=path.join('tools', 'create_pkg_manifest.py'),
+ args=['-d', path.join('DEPS'), '-o', manifest_path],
+ )
+
+ def checkout(self, path, revision=None):
+ """Get dart/sdk.
+
+ Args:
+ path (Path): Location where dart source code will be checked out.
+ revision (str): The revision of the source code to check out.
+ """
+ deps_info = self.m.jiri.project([DART_SDK_PROJECT])
+ remote = deps_info.json.output[0]['remote']
+ self.m.git.checkout(
+ url=remote,
+ path=path,
+ ref=revision,
+ )
diff --git a/recipe_modules/dart_util/examples/full.expected/default.json b/recipe_modules/dart_util/examples/full.expected/default.json
new file mode 100644
index 0000000..7664ff0
--- /dev/null
+++ b/recipe_modules/dart_util/examples/full.expected/default.json
@@ -0,0 +1,505 @@
+[
+ {
+ "cmd": [],
+ "name": "ensure jiri"
+ },
+ {
+ "cmd": [
+ "cipd",
+ "ensure",
+ "-root",
+ "[START_DIR]/cipd/jiri",
+ "-ensure-file",
+ "fuchsia/tools/jiri/${platform} git_revision:4bbab8725bd3c64b56e70af3d973d526cd894b49",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "infra_step": true,
+ "name": "ensure jiri.ensure_installed",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"resolved-instance_id-of-git_revision:4bb\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"fuchsia/tools/jiri/resolved-platform\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ ]@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "[START_DIR]/cipd/jiri/jiri",
+ "project",
+ "-vv",
+ "-time",
+ "-j=50",
+ "-json-output",
+ "/path/to/tmp/json",
+ "dart/sdk"
+ ],
+ "name": "jiri project",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@json.output@[@@@",
+ "@@@STEP_LOG_LINE@json.output@ {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"branches\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"(HEAD detached at c22471f)\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ ], @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"current_branch\": \"\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"name\": \"dart/sdk\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"path\": \"path/to/dart/sdk\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"remote\": \"https://fuchsia.googlesource.com/dart/sdk\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"revision\": \"c22471f4e3f842ae18dd9adec82ed9eb78ed1127\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@]@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "ensure-directory",
+ "--mode",
+ "0777",
+ "[START_DIR]/dart"
+ ],
+ "infra_step": true,
+ "name": "makedirs"
+ },
+ {
+ "cmd": [
+ "git",
+ "init"
+ ],
+ "cwd": "[START_DIR]/dart",
+ "name": "git init"
+ },
+ {
+ "cmd": [
+ "git",
+ "remote",
+ "add",
+ "origin",
+ "https://fuchsia.googlesource.com/dart/sdk"
+ ],
+ "cwd": "[START_DIR]/dart",
+ "name": "git remote"
+ },
+ {
+ "cmd": [],
+ "name": "cache"
+ },
+ {
+ "cmd": [
+ "vpython",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "ensure-directory",
+ "--mode",
+ "0777",
+ "[CACHE]/git/fuchsia.googlesource.com-dart-sdk"
+ ],
+ "cwd": "[START_DIR]/dart",
+ "infra_step": true,
+ "name": "cache.makedirs",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "init",
+ "--bare"
+ ],
+ "cwd": "[CACHE]/git/fuchsia.googlesource.com-dart-sdk",
+ "name": "cache.git init",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "config",
+ "remote.origin.url",
+ "https://fuchsia.googlesource.com/dart/sdk"
+ ],
+ "cwd": "[CACHE]/git/fuchsia.googlesource.com-dart-sdk",
+ "name": "cache.remote set-url",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "config",
+ "--replace-all",
+ "remote.origin.fetch",
+ "+refs/heads/*:refs/heads/*",
+ "\\+refs/heads/\\*:.*"
+ ],
+ "cwd": "[CACHE]/git/fuchsia.googlesource.com-dart-sdk",
+ "name": "cache.git config",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "fetch",
+ "--prune",
+ "--tags",
+ "origin"
+ ],
+ "cwd": "[CACHE]/git/fuchsia.googlesource.com-dart-sdk",
+ "name": "cache.git fetch",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "ensure-directory",
+ "--mode",
+ "0777",
+ "[START_DIR]/dart/.git/objects/info"
+ ],
+ "cwd": "[START_DIR]/dart",
+ "infra_step": true,
+ "name": "cache.makedirs object/info",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "copy",
+ "[CACHE]/git/fuchsia.googlesource.com-dart-sdk/objects\n",
+ "[START_DIR]/dart/.git/objects/info/alternates"
+ ],
+ "cwd": "[START_DIR]/dart",
+ "infra_step": true,
+ "name": "cache.alternates",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LOG_LINE@alternates@[CACHE]/git/fuchsia.googlesource.com-dart-sdk/objects@@@",
+ "@@@STEP_LOG_END@alternates@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "fetch",
+ "--tags",
+ "origin",
+ "abc_revision"
+ ],
+ "cwd": "[START_DIR]/dart",
+ "name": "git fetch"
+ },
+ {
+ "cmd": [
+ "git",
+ "checkout",
+ "-f",
+ "FETCH_HEAD"
+ ],
+ "cwd": "[START_DIR]/dart",
+ "name": "git checkout"
+ },
+ {
+ "cmd": [
+ "git",
+ "rev-parse",
+ "HEAD"
+ ],
+ "cwd": "[START_DIR]/dart",
+ "name": "git rev-parse"
+ },
+ {
+ "cmd": [
+ "git",
+ "clean",
+ "-f",
+ "-d",
+ "-x"
+ ],
+ "cwd": "[START_DIR]/dart",
+ "name": "git clean"
+ },
+ {
+ "cmd": [],
+ "name": "submodule"
+ },
+ {
+ "cmd": [
+ "git",
+ "submodule",
+ "sync"
+ ],
+ "cwd": "[START_DIR]/dart",
+ "name": "submodule.git submodule sync",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "submodule",
+ "update",
+ "--init"
+ ],
+ "cwd": "[START_DIR]/dart",
+ "name": "submodule.git submodule update",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "[START_DIR]/dart/tools/create_pkg_manifest.py",
+ "-d",
+ "[START_DIR]/dart/DEPS",
+ "-o",
+ "[START_DIR]/integration/fuchsia/topaz/dart_third_party_pkg"
+ ],
+ "name": "update dart_third_party_pkg"
+ },
+ {
+ "cmd": [
+ "git",
+ "fetch",
+ "origin"
+ ],
+ "cwd": "[START_DIR]/third_party/dart-pkg/pub",
+ "name": "git fetch (2)"
+ },
+ {
+ "cmd": [
+ "git",
+ "checkout",
+ "origin/master"
+ ],
+ "cwd": "[START_DIR]/third_party/dart-pkg/pub",
+ "name": "git checkout (2)"
+ },
+ {
+ "cmd": [
+ "git",
+ "rev-parse",
+ "HEAD"
+ ],
+ "cwd": "[START_DIR]/third_party/dart-pkg/pub",
+ "name": "git rev-parse (2)"
+ },
+ {
+ "cmd": [
+ "python",
+ "-u",
+ "[START_DIR]/scripts/dart/update_3p_packages.py",
+ "--debug"
+ ],
+ "cwd": "[START_DIR]/third_party/dart-pkg/pub",
+ "name": "update dart 3p packages"
+ },
+ {
+ "cmd": [
+ "git",
+ "ls-files",
+ "--modified",
+ "--deleted",
+ "--exclude-standard"
+ ],
+ "cwd": "[START_DIR]/third_party/dart-pkg/pub",
+ "name": "check for no-op commit",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@stdout@hello@@@",
+ "@@@STEP_LOG_END@stdout@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "diff"
+ ],
+ "cwd": "[START_DIR]/third_party/dart-pkg/pub",
+ "name": "git diff"
+ },
+ {
+ "cmd": [
+ "git",
+ "hash-object",
+ "a diff"
+ ],
+ "cwd": "[START_DIR]/third_party/dart-pkg/pub",
+ "name": "git hash-object"
+ },
+ {
+ "cmd": [
+ "git",
+ "commit",
+ "-m",
+ "[roll] Update third-party dart packages\nChange-Id: Iabc123\n",
+ "-a"
+ ],
+ "cwd": "[START_DIR]/third_party/dart-pkg/pub",
+ "name": "git commit"
+ },
+ {
+ "cmd": [
+ "git",
+ "push",
+ "origin",
+ "HEAD:refs/for/master"
+ ],
+ "cwd": "[START_DIR]/third_party/dart-pkg/pub",
+ "name": "git push",
+ "~followup_annotations": [
+ "@@@STEP_LINK@gerrit link@https://fuchsia-review.googlesource.com/q/Iabc123@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "ensure gerrit"
+ },
+ {
+ "cmd": [
+ "cipd",
+ "ensure",
+ "-root",
+ "[START_DIR]/cipd/gerrit",
+ "-ensure-file",
+ "infra/tools/luci/gerrit/${platform} latest",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[START_DIR]/third_party/dart-pkg/pub",
+ "infra_step": true,
+ "name": "ensure gerrit.ensure_installed",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"resolved-instance_id-of-latest----------\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"infra/tools/luci/gerrit/resolved-platform\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ ]@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "[START_DIR]/cipd/gerrit/gerrit",
+ "set-review",
+ "-host",
+ "https://fuchsia-review.googlesource.com",
+ "-input",
+ "{\"change_id\": \"third_party/dart-pkg/pub~master~Iabc123\", \"input\": {\"labels\": {\"Commit-Queue\": 1}}, \"revision_id\": \"current\"}",
+ "-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[START_DIR]/third_party/dart-pkg/pub",
+ "name": "submit to commit queue",
+ "~followup_annotations": [
+ "@@@STEP_LOG_END@json.output (invalid)@@@",
+ "@@@STEP_LOG_LINE@json.output (exception)@No JSON object could be decoded@@@",
+ "@@@STEP_LOG_END@json.output (exception)@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "check for completion"
+ },
+ {
+ "cmd": [
+ "[START_DIR]/cipd/gerrit/gerrit",
+ "change-detail",
+ "-host",
+ "https://fuchsia-review.googlesource.com",
+ "-input",
+ "{\"change_id\": \"third_party/dart-pkg/pub~master~Iabc123\"}",
+ "-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[START_DIR]/third_party/dart-pkg/pub",
+ "infra_step": true,
+ "name": "check for completion.check if done (0)",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"labels\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"Commit-Queue\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"approved\": {}@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ }, @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"status\": \"MERGED\"@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "[START_DIR]/cipd/gerrit/gerrit",
+ "change-abandon",
+ "-host",
+ "https://fuchsia-review.googlesource.com",
+ "-input",
+ "{\"change_id\": \"third_party/dart-pkg/pub~master~Iabc123\"}",
+ "-output",
+ "/path/to/tmp/json"
+ ],
+ "cwd": "[START_DIR]/third_party/dart-pkg/pub",
+ "name": "abandon roll: dry run complete",
+ "~followup_annotations": [
+ "@@@STEP_LOG_END@json.output (invalid)@@@",
+ "@@@STEP_LOG_LINE@json.output (exception)@No JSON object could be decoded@@@",
+ "@@@STEP_LOG_END@json.output (exception)@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "git",
+ "rev-parse",
+ "HEAD"
+ ],
+ "cwd": "[START_DIR]/third_party/dart-pkg/pub",
+ "name": "git rev-parse (3)",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@revision@deadbeef@@@",
+ "@@@STEP_LOG_END@revision@@@"
+ ]
+ },
+ {
+ "name": "$result"
+ }
+]
\ No newline at end of file
diff --git a/recipe_modules/dart_util/examples/full.py b/recipe_modules/dart_util/examples/full.py
new file mode 100644
index 0000000..5d62f0f
--- /dev/null
+++ b/recipe_modules/dart_util/examples/full.py
@@ -0,0 +1,26 @@
+# Copyright 2020 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+DEPS = [
+ 'fuchsia/auto_roller',
+ 'fuchsia/dart_util',
+ 'recipe_engine/path',
+ 'recipe_engine/json',
+]
+
+
+def RunSteps(api):
+ """Tests for fetching and uploading debug symbols."""
+ dart_path = api.path['start_dir'].join('dart')
+ api.dart_util.checkout(path=dart_path, revision='abc_revision')
+
+ checkout_root = api.path['start_dir'].join('integration')
+ api.dart_util.update_pkg_manifest(path=dart_path, checkout_root=checkout_root)
+
+ api.dart_util.update_3p_packages(
+ checkout_root=api.path['start_dir'], dry_run=True)
+
+
+def GenTests(api):
+ yield api.test('default') + api.auto_roller.success_step_data()