Merge "Replace logic for sdk source jar" into main am: 08709dccaf
Original change: https://android-review.googlesource.com/c/platform/development/+/2760387 Change-Id: Ie7220bb506069343136ab7c5a3cf1ede41034dc6 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -1,261 +0,0 @@
|
||||
#!/usr/bin/env python2
|
||||
#
|
||||
# Copyright (C) 2011 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
import re
|
||||
import os
|
||||
import sys
|
||||
import getopt
|
||||
import shutil
|
||||
import subprocess
|
||||
import zipfile
|
||||
|
||||
VERBOSE = False
|
||||
TOP_FOLDER = "src"
|
||||
_RE_PKG = re.compile("^\s*package\s+([^\s;]+)\s*;.*")
|
||||
|
||||
# Holds cmd-line arguments and context information
|
||||
class Params(object):
|
||||
def __init__(self):
|
||||
self.EXEC_ZIP = False
|
||||
self.DRY = False
|
||||
self.PROPS = None
|
||||
self.SRC = None
|
||||
self.DST = None
|
||||
self.CNT_USED = 0
|
||||
self.CNT_NOPKG = 0
|
||||
# DIR is the list of directories to scan in TOPDIR.
|
||||
self.DIR = "frameworks libcore"
|
||||
self.IGNORE_DIR = [ "hosttests", "tools", "tests", "samples", "layoutlib" ]
|
||||
# IGNORE is a list of namespaces to ignore. Must be java
|
||||
# package definitions (e.g. "com.blah.foo.")
|
||||
self.IGNORE = [ "sun.", "libcore.", "dalvik.",
|
||||
"com.test.", "com.google.",
|
||||
"coretestutils.", "test.", "test2.", "tests." ]
|
||||
self.zipfile = None
|
||||
|
||||
|
||||
def verbose(msg, *args):
|
||||
"""Prints a verbose message to stderr if --verbose is set."""
|
||||
global VERBOSE
|
||||
if VERBOSE:
|
||||
if args:
|
||||
msg = msg % args
|
||||
print >>sys.stderr, msg
|
||||
|
||||
|
||||
# Prints a usage summary
|
||||
def usage(error=None):
|
||||
print """
|
||||
Description:
|
||||
This script collects all framework Java sources from the current android
|
||||
source code and places them in a source.zip file that can be distributed
|
||||
by the SDK Manager.
|
||||
|
||||
Usage:
|
||||
%s [-n|-v|-z] <source.properties> <sources.zip> <topdir>
|
||||
|
||||
The source.properties file must exist and will be injected in the Zip file.
|
||||
The source directory must already exist.
|
||||
Use -v for verbose output (lists each file being picked up or ignored).
|
||||
Use -n for a dry-run (doesn't write the zip file).
|
||||
Use -z to use the system 'zip' command instead of the Python Zip module.
|
||||
|
||||
""" % sys.argv[0]
|
||||
|
||||
if error:
|
||||
print >>sys.stderr, "Error:", error
|
||||
|
||||
|
||||
# Parse command line args, returns a Params instance or sys.exit(2) on error
|
||||
# after printing the error and the usage.
|
||||
def parseArgs(argv):
|
||||
global VERBOSE
|
||||
p = Params()
|
||||
error = None
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(argv[1:],
|
||||
"zvns:",
|
||||
[ "exec-zip", "verbose", "dry", "sourcedir=" ])
|
||||
except getopt.GetoptError, e:
|
||||
error = str(e)
|
||||
|
||||
if error is None:
|
||||
for o, a in opts:
|
||||
if o in [ "-n", "--dry" ]:
|
||||
# Dry mode: don't copy/zip, print what would be done.
|
||||
p.DRY = True
|
||||
if o in [ "-v", "--verbose" ]:
|
||||
# Verbose mode. Display everything that's going on.
|
||||
VERBOSE = True
|
||||
elif o in [ "-s", "--sourcedir" ]:
|
||||
# The source directories to process (space separated list)
|
||||
p.DIR = a
|
||||
elif o in [ "-z", "--exec-zip" ]:
|
||||
# Don't use Python zip, instead call the 'zip' system exec.
|
||||
p.EXEC_ZIP = True
|
||||
|
||||
if len(args) != 3:
|
||||
error = "Missing arguments: <source> <dest>"
|
||||
else:
|
||||
p.PROPS = args[0]
|
||||
p.DST = args[1]
|
||||
p.SRC = args[2]
|
||||
|
||||
if not os.path.isfile(p.PROPS):
|
||||
error = "%s is not a file" % p.PROPS
|
||||
if not os.path.isdir(p.SRC):
|
||||
error = "%s is not a directory" % p.SRC
|
||||
|
||||
if error:
|
||||
usage(error)
|
||||
sys.exit(2)
|
||||
|
||||
return p
|
||||
|
||||
|
||||
# Recursively parses the given directory and processes java files found
|
||||
def parseSrcDir(p, srcdir):
|
||||
if not os.path.exists(srcdir):
|
||||
verbose("Error: Skipping unknown directory %s", srcdir)
|
||||
return
|
||||
|
||||
for filename in os.listdir(srcdir):
|
||||
filepath = os.path.join(srcdir, filename)
|
||||
if filename.endswith(".java") and os.path.isfile(filepath):
|
||||
pkg = checkJavaFile(filepath)
|
||||
if not pkg:
|
||||
verbose("No package found in %s", filepath)
|
||||
if pkg:
|
||||
# Should we ignore this package?
|
||||
pkg2 = pkg
|
||||
if not "." in pkg2:
|
||||
pkg2 += "."
|
||||
for ignore in p.IGNORE:
|
||||
if pkg2.startswith(ignore):
|
||||
verbose("Ignore package %s [%s]", pkg, filepath)
|
||||
pkg = None
|
||||
break
|
||||
|
||||
if pkg:
|
||||
pkg = pkg.replace(".", os.path.sep) # e.g. android.view => android/view
|
||||
copy(p, filepath, pkg)
|
||||
p.CNT_USED += 1
|
||||
else:
|
||||
p.CNT_NOPKG += 1
|
||||
elif os.path.isdir(filepath):
|
||||
if not filename in p.IGNORE_DIR:
|
||||
parseSrcDir(p, filepath)
|
||||
|
||||
|
||||
# Check a java file to find its package declaration, if any
|
||||
def checkJavaFile(path):
|
||||
try:
|
||||
f = None
|
||||
try:
|
||||
f = file(path)
|
||||
for l in f.readlines():
|
||||
m = _RE_PKG.match(l)
|
||||
if m:
|
||||
return m.group(1)
|
||||
finally:
|
||||
if f: f.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return None
|
||||
|
||||
|
||||
USED_ARC_PATH = {}
|
||||
|
||||
# Copy the given file (given its absolute filepath) to
|
||||
# the relative desk_pkg directory in the zip file.
|
||||
def copy(p, filepath, dest_pkg):
|
||||
arc_path = os.path.join(TOP_FOLDER, dest_pkg, os.path.basename(filepath))
|
||||
if arc_path in USED_ARC_PATH:
|
||||
verbose("Ignore duplicate archive path %s", arc_path)
|
||||
USED_ARC_PATH[arc_path] = 1
|
||||
if p.DRY:
|
||||
print >>sys.stderr, "zip %s [%s]" % (arc_path, filepath)
|
||||
elif p.zipfile is not None:
|
||||
if p.EXEC_ZIP:
|
||||
# zipfile is a path. Copy to it.
|
||||
dest_path = os.path.join(p.zipfile, arc_path)
|
||||
dest_dir = os.path.dirname(dest_path)
|
||||
if not os.path.isdir(dest_dir):
|
||||
os.makedirs(dest_dir)
|
||||
shutil.copyfile(filepath, dest_path)
|
||||
else:
|
||||
# zipfile is a ZipFile object. Compress with it.
|
||||
p.zipfile.write(filepath, arc_path)
|
||||
|
||||
|
||||
def shellExec(*cmd):
|
||||
"""
|
||||
Executes the given system command.
|
||||
|
||||
The command must be split into a list (c.f. shext.split().)
|
||||
|
||||
This raises an exception if the command fails.
|
||||
Stdin/out/err are not being redirected.
|
||||
"""
|
||||
verbose("exec: %s", repr(cmd))
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
|
||||
def main():
|
||||
p = parseArgs(sys.argv)
|
||||
z = None
|
||||
try:
|
||||
if not p.DRY:
|
||||
if p.EXEC_ZIP:
|
||||
p.zipfile = p.DST + "_temp_dir"
|
||||
if os.path.exists(p.zipfile):
|
||||
shutil.rmtree(p.zipfile)
|
||||
props_dest = os.path.join(p.zipfile, TOP_FOLDER + "/source.properties")
|
||||
os.makedirs(os.path.dirname(props_dest))
|
||||
shutil.copyfile(p.PROPS, props_dest)
|
||||
else:
|
||||
p.zipfile = z = zipfile.ZipFile(p.DST, "w", zipfile.ZIP_DEFLATED)
|
||||
z.write(p.PROPS, TOP_FOLDER + "/source.properties")
|
||||
for d in p.DIR.split():
|
||||
if d:
|
||||
parseSrcDir(p, os.path.join(p.SRC, d))
|
||||
if p.EXEC_ZIP and not p.DRY:
|
||||
curr_dir = os.getcwd()
|
||||
os.chdir(p.zipfile)
|
||||
if os.path.exists("_temp.zip"):
|
||||
os.unlink("_temp.zip");
|
||||
shellExec("zip", "-9r", "_temp.zip", TOP_FOLDER)
|
||||
os.chdir(curr_dir)
|
||||
shutil.move(os.path.join(p.zipfile, "_temp.zip"), p.DST)
|
||||
shutil.rmtree(p.zipfile)
|
||||
finally:
|
||||
if z is not None:
|
||||
z.close()
|
||||
print "%s: %d java files copied" % (p.DST, p.CNT_USED)
|
||||
if p.CNT_NOPKG:
|
||||
print "%s: %d java files ignored" % (p.DST, p.CNT_NOPKG)
|
||||
if p.DRY:
|
||||
print >>sys.stderr, "This was in *DRY* mode. No copies done."
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
# For emacs:
|
||||
# -*- tab-width: 4; -*-
|
||||
@@ -76,11 +76,13 @@ endef
|
||||
# $4=package to create, must be "sources"
|
||||
#
|
||||
define mk-sdk-repo-sources
|
||||
$(call sdk-repo-pkg-zip,$(2),$(3),$(4)): $(3) development/build/tools/mk_sources_zip.py $(HOST_OUT)/development/sdk/source_source.properties
|
||||
bcp_srcjar := $(call intermediates-dir-for,ETC,platform-bootclasspath.srcjar)/platform-bootclasspath.srcjar
|
||||
source_props := $(HOST_OUT)/development/sdk/source_source.properties
|
||||
$(call sdk-repo-pkg-zip,$(2),$(3),$(4)): $(3) $$(bcp_srcjar) $$(source_props)
|
||||
@echo "Building SDK sources package"
|
||||
development/build/tools/mk_sources_zip.py --exec-zip \
|
||||
$(HOST_OUT)/development/sdk/source_source.properties \
|
||||
$$@ .
|
||||
unzip -qd $(dir $$@)/tmp $$(bcp_srcjar)
|
||||
$$(SOONG_ZIP) -o $$@ -P src -e source.properties -f $$(source_props) -C $(dir $$@)/tmp -D $(dir $$@)/tmp
|
||||
rm -r $(dir $$@)/tmp
|
||||
$(call dist-for-goals-with-filenametag, sdk_repo, $(call sdk-repo-pkg-zip,$(2),$(3),$(4)))
|
||||
$(1) += $(4) $(2) \
|
||||
$(call sdk-repo-pkg-zip,$(2),$(3),$(4)):$(notdir $(call sdk-repo-pkg-zip,$(2),$(3),$(4)))
|
||||
|
||||
Reference in New Issue
Block a user