SDK stuff: Add a script to download the mojom parser binary.
(Using another new, added script that downloads/verifies stuff from
Google Storage.)
R=vardhan@google.com
Review URL: https://codereview.chromium.org/1720433003 .
diff --git a/sdk_build/build_sdk.py b/sdk_build/build_sdk.py
index e5a7638..586a8fc 100755
--- a/sdk_build/build_sdk.py
+++ b/sdk_build/build_sdk.py
@@ -15,12 +15,22 @@
import sys
-def _CopyFiles(source_path, dest_path, **kwargs):
- """Copies files from the source git repository (the current working directory
- should be the root of this repository) to the destination path. |source_path|
- and the keyword arguments are as for the arguments of |GitLsFiles|.
- |dest_path| should be the "root" destination path. Note that a file such as
- <source_path>/foo/bar/baz.quux is copied to <dest_path>/foo/bar/baz.quux."""
+def _MakeDirs(*args, **kwargs):
+ """Like |os.makedirs()|, but ignores |OSError| exceptions (it assumes that
+ these are due to the directory already existing)."""
+ try:
+ os.makedirs(*args, **kwargs)
+ except OSError:
+ pass
+
+
+def _CopyDir(source_path, dest_path, **kwargs):
+ """Copies directories from the source git repository (the current working
+ directory should be the root of this repository) to the destination path.
+ |source_path| and the keyword arguments are as for the arguments of
+ |GitLsFiles|. |dest_path| should be the "root" destination path. Note that a
+ file such as <source_path>/foo/bar/baz.quux is copied to
+ <dest_path>/foo/bar/baz.quux."""
# Normalize the source path. Note that this strips any trailing '/'.
source_path = os.path.normpath(source_path)
@@ -28,16 +38,29 @@
for source_file in source_files:
rel_path = source_file[len(source_path) + 1:]
dest_file = os.path.join(dest_path, rel_path)
- try:
- os.makedirs(os.path.dirname(dest_file))
- except OSError:
- pass
- shutil.copyfile(source_file, dest_file)
+ _MakeDirs(os.path.dirname(dest_file))
+ shutil.copy(source_file, dest_file)
+
+
+def _CopyFiles(source_files, dest_path):
+ """Copies a given source file or files from the source git repository to the
+ given destination path (the current working directory should be the root of
+ this repository) |source_files| should either be a relative path to a single
+ file in the source git repository or an iterable of such paths; note that this
+ does not check that files are actually in the git repository (i.e., are
+ tracked)."""
+
+ if type(source_files) is str:
+ source_files = [source_files]
+ _MakeDirs(dest_path)
+ for source_file in source_files:
+ shutil.copy(source_file,
+ os.path.join(dest_path, os.path.basename(source_file)))
def main():
parser = argparse.ArgumentParser(
- description="Constructs an SDK from a specification")
+ description="Constructs an SDK from a specification.")
parser.add_argument("--allow-dirty-tree", dest="allow_dirty_tree",
action="store_true",
help="proceed even if the source tree is dirty")
@@ -64,11 +87,16 @@
except OSError:
FatalError("failed to create target directory %s" % target_dir)
- def CopyFilesToTargetDir(source_path, rel_dest_path, **kwargs):
- return _CopyFiles(source_path, os.path.join(target_dir, rel_dest_path),
+ def CopyDirToTargetDir(source_path, rel_dest_path, **kwargs):
+ return _CopyDir(source_path, os.path.join(target_dir, rel_dest_path),
+ **kwargs)
+
+ def CopyFilesToTargetDir(source_files, rel_dest_path, **kwargs):
+ return _CopyFiles(source_files, os.path.join(target_dir, rel_dest_path),
**kwargs)
- execution_globals = {"CopyFiles": CopyFilesToTargetDir,
+ execution_globals = {"CopyDir": CopyDirToTargetDir,
+ "CopyFiles": CopyFilesToTargetDir,
"FatalError": FatalError,
"GitLsFiles": GitLsFiles}
exec args.sdk_spec_file in execution_globals
diff --git a/sdk_build/data/common/download_file_from_google_storage.py b/sdk_build/data/common/download_file_from_google_storage.py
new file mode 100755
index 0000000..28feb4d
--- /dev/null
+++ b/sdk_build/data/common/download_file_from_google_storage.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+#FIXME
+
+import argparse
+import hashlib
+import httplib
+import os
+import sys
+
+
+def _FatalError(message):
+ print >> sys.stderr, "%s: fatal error: %s" % (os.path.basename(sys.argv[0]),
+ message)
+
+
+def _DownloadFile(source):
+ """FIXME"""
+
+ try:
+ conn = httplib.HTTPSConnection("storage.googleapis.com")
+ conn.request("GET", "/" + source)
+ resp = conn.getresponse()
+ if resp.status != httplib.OK:
+ _FatalError("HTTP status: %s" % resp.reason)
+ data = resp.read()
+ conn.close()
+ return data
+ except httplib.HTTPException as e:
+ _FatalError("HTTP exception: %s" % str(e))
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description="Downloads a file from Google Cloud Storage.")
+ parser.add_argument("--sha1-hash", dest="sha1_hash",
+ help="SHA-1 hash for the downloaded file")
+ parser.add_argument("--executable", action="store_true",
+ help="make the downloaded file executable")
+ parser.add_argument("source", help="source path, including bucket name")
+ parser.add_argument("destination", help="destination path")
+ args = parser.parse_args()
+
+ bits = _DownloadFile(args.source)
+ if args.sha1_hash:
+ got_sha1_hash = hashlib.sha1(bits).hexdigest().lower()
+ expected_sha1_hash = args.sha1_hash.lower()
+ if got_sha1_hash != expected_sha1_hash:
+ _FatalError("SHA-1 hash did not match: got %s, expected %s" %
+ (got_sha1_hash, expected_sha1_hash))
+
+ with open(args.destination, "wb") as f:
+ f.write(bits)
+
+ if args.executable:
+ curr_mode = os.stat(args.destination).st_mode
+ # Set the x bits (0111) where the r bits (0444) are set.
+ new_mode = curr_mode | ((curr_mode & 0444) >> 2)
+ os.chmod(args.destination, new_mode)
+
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/sdk_build/data/common/download_mojom_parser.sh b/sdk_build/data/common/download_mojom_parser.sh
new file mode 100755
index 0000000..5051e77
--- /dev/null
+++ b/sdk_build/data/common/download_mojom_parser.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Note: In the SDK, this script lives in third_party/mojo_sdk_setup.
+SCRIPT_DIR=$(dirname $0)
+DOWNLOADER=${SCRIPT_DIR}/download_file_from_google_storage.py
+
+UNAME=$(uname)
+case "$UNAME" in
+ Linux)
+ # TODO(vtl): We currently just always assume 64-bit.
+ HOST_ARCH=linux64
+ ;;
+ Darwin)
+ HOST_ARCH=mac64
+ ;;
+ *)
+ echo "$0: unknown system: ${UNAME}" 1>&2
+ ;;
+esac
+
+FILE=${SCRIPT_DIR}/../mojo/public/tools/bindings/mojom_parser/bin/${HOST_ARCH}/mojom_parser
+HASH=$(cat "${FILE}.sha1")
+# This includes the bucket name first.
+GS_NAME=mojo/mojom_parser/${HOST_ARCH}/${HASH}
+
+"$DOWNLOADER" --sha1-hash="${HASH}" --executable "$GS_NAME" "$FILE"
diff --git a/sdk_build/data/cpp/cpp.sdk b/sdk_build/data/cpp/cpp.sdk
index 3e061ac..66d000b 100644
--- a/sdk_build/data/cpp/cpp.sdk
+++ b/sdk_build/data/cpp/cpp.sdk
@@ -9,34 +9,44 @@
EXCLUDE_FILES=[".*", "*.gn", "*.gni", "PRESUBMIT.py", "*_win.*"]
EXCLUDE_PATHS=["*/tests/*"]
-CopyFiles("mojo/public",
- "third_party/mojo/public",
- recursive=False,
- exclude_file_patterns=EXCLUDE_FILES)
+CopyDir("mojo/public",
+ "third_party/mojo/public",
+ recursive=False,
+ exclude_file_patterns=EXCLUDE_FILES)
-CopyFiles("mojo/public/c",
- "third_party/mojo/public/c",
- recursive=True,
- exclude_file_patterns=EXCLUDE_FILES,
- exclude_path_patterns=EXCLUDE_PATHS)
-CopyFiles("mojo/public/cpp",
- "third_party/mojo/public/cpp",
- recursive=True,
- exclude_file_patterns=EXCLUDE_FILES,
- exclude_path_patterns=EXCLUDE_PATHS+
- ["mojo/public/cpp/test_support/*"])
+CopyDir("mojo/public/c",
+ "third_party/mojo/public/c",
+ recursive=True,
+ exclude_file_patterns=EXCLUDE_FILES,
+ exclude_path_patterns=EXCLUDE_PATHS)
+CopyDir("mojo/public/cpp",
+ "third_party/mojo/public/cpp",
+ recursive=True,
+ exclude_file_patterns=EXCLUDE_FILES,
+ exclude_path_patterns=EXCLUDE_PATHS+["mojo/public/cpp/test_support/*"])
# For simplicity, copy all of the bindings generators, even though we really
# only need/want C++.
-CopyFiles("mojo/public/tools/bindings",
- "third_party/mojo/public/tools/bindings",
- recursive=True,
- exclude_file_patterns=EXCLUDE_FILES,
- exclude_path_patterns=EXCLUDE_PATHS+["*/mojom_tests/*"])
+CopyDir("mojo/public/tools/bindings",
+ "third_party/mojo/public/tools/bindings",
+ recursive=True,
+ exclude_file_patterns=EXCLUDE_FILES,
+ exclude_path_patterns=EXCLUDE_PATHS+["*/mojom_tests/*"])
# The generators need jinja2, which needs markupsafe. Sigh.
-CopyFiles("mojo/public/third_party/jinja2",
- "third_party/mojo/public/third_party/jinja2",
- recursive=True)
-CopyFiles("mojo/public/third_party/markupsafe",
- "third_party/mojo/public/third_party/markupsafe",
- recursive=True)
+CopyDir("mojo/public/third_party/jinja2",
+ "third_party/mojo/public/third_party/jinja2",
+ recursive=True)
+CopyDir("mojo/public/third_party/markupsafe",
+ "third_party/mojo/public/third_party/markupsafe",
+ recursive=True)
+
+# Seed an example.
+CopyDir("examples/hello_mojo",
+ "examples/hello_mojo",
+ recursive=True,
+ exclude_file_patterns=EXCLUDE_FILES)
+
+# Scripts to download binaries.
+CopyFiles(["sdk_build/data/common/download_file_from_google_storage.py",
+ "sdk_build/data/common/download_mojom_parser.sh"],
+ "third_party/mojo_sdk_setup")