You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by su...@apache.org on 2012/10/16 18:02:14 UTC
svn commit: r1398865 -
/hadoop/common/branches/branch-trunk-win/dev-support/saveVersion.py
Author: suresh
Date: Tue Oct 16 16:02:13 2012
New Revision: 1398865
URL: http://svn.apache.org/viewvc?rev=1398865&view=rev
Log:
HADOOP-8924. Hadoop Common creating package-info.java must not depend on sh. Contributed by Chris Nauroth.
Added:
hadoop/common/branches/branch-trunk-win/dev-support/saveVersion.py
Added: hadoop/common/branches/branch-trunk-win/dev-support/saveVersion.py
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-trunk-win/dev-support/saveVersion.py?rev=1398865&view=auto
==============================================================================
--- hadoop/common/branches/branch-trunk-win/dev-support/saveVersion.py (added)
+++ hadoop/common/branches/branch-trunk-win/dev-support/saveVersion.py Tue Oct 16 16:02:13 2012
@@ -0,0 +1,154 @@
+#! /usr/bin/python
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+# This file is used to generate package-info.java with an annotation that
+# records the version, revision, user, date, url, and srcChecksum
+
+import os
+import sys
+import re
+import subprocess
+import getpass
+import time
+import hashlib
+
+def usage():
+ print >>sys.stderr, "Usage: saveVersion.py <annotation> <version> <src_checksum_root_dir> <package> <build_dir>"
+ print >>sys.stderr, "Eg: saveVersion.py @HadoopVersionAnnotation 1.1.0 src org.apache.hadoop build"
+
+
+# This template is what gets written to package-info.java.
+# It is filled out by (annotation, version, revision, user, date, url,
+# srcChecksum, package)
+
+template_string = \
+'''/*
+ * Generated by saveVersion.py
+ */
+%s(version="%s", revision="%s",
+ user="%s", date="%s", url="%s",
+ srcChecksum="%s")
+package %s;
+'''
+
+# Convert Windows paths with back-slashes into canonical Unix paths
+# with forward slashes. Unix paths are unchanged. Mixed formats
+# just naively have back-slashes converted to forward slashes.
+def canonicalpath(path):
+ return re.sub('\\\\','/',path)
+
+# This is an implementation of md5sum-like functionality in pure python.
+# The path name is output in canonical form to get the same aggregate
+# checksum as Linux.
+def md5sum(fname):
+ block_size = 2**20
+ f = open(os.path.normpath(fname), 'rb') # open in binary mode to make sure EOLs don't get munged
+ md5 = hashlib.md5()
+ while True:
+ data = f.read(block_size)
+ if not data:
+ break
+ md5.update(data)
+ f.close()
+ return md5.hexdigest()
+
+# Roughly emulate the Python 2.7 functionality of "subprocess.check_output()"
+# by accepting a CLI vector [cmd, arg1, arg2, ...], and returning its stdout result,
+# but without the "checking". For use in lower version Python interpreters.
+def subprocessOutput(args):
+ # result = subprocess.check_output(args, shell=True) # requires py2.7
+ process = subprocess.Popen(args, stdout=subprocess.PIPE)
+ result = process.communicate()[0].strip()
+ return result
+
+# Strip surrounding quotes from a string object that carried its quotes with it.
+def stripquotes(s):
+ if (s[0] == '"' and s[-1] == '"') or (s[0] == "'" and s[-1] == "'") :
+ return s[1:-1]
+ elif (s[0] == '\\' and s[-1] == '"') :
+ return s[1:-1]
+ else:
+ return s
+
+
+def main(argv=None):
+ if argv is None:
+ argv = sys.argv[1:]
+ if (len(argv) != 5) or (argv[0] == "--help") or (argv[0] == "-h"):
+ usage()
+ return -1
+
+ annotation = argv[0]
+ version = argv[1]
+ src_checksum_root_dir = argv[2]
+ package = argv[3]
+ build_dir = argv[4]
+
+ user = getpass.getuser()
+ date = time.strftime("%a %b %d %H:%M:%S %Z %Y") # simulate `date`
+
+ os.chdir(os.path.normpath(os.path.join(os.path.dirname(sys.argv[0]), "..")))
+ if os.path.isdir(".git"):
+ revision = stripquotes(subprocessOutput(['git', 'log', '-1', '--pretty=format:"%H"']))
+ origin = subprocessOutput(['git', 'config', '--get', 'remote.origin.url'])
+ branch = subprocessOutput(['git', 'branch'])
+
+ filter_current_branch = re.compile(r'^\* (.*)$', re.MULTILINE)
+ current_branch = filter_current_branch.search(branch).group(1).strip()
+ url = "%s on branch %s" % (origin, current_branch)
+ else:
+ svn_info = subprocessOutput(['svn', 'info'])
+ filter_last_revision = re.compile(r'^Last Changed Rev: (.*)$', re.MULTILINE)
+ revision = filter_last_revision.search(svn_info).group(1).strip()
+
+ filter_url = re.compile(r'^URL: (.*)$', re.MULTILINE)
+ url = filter_url.search(svn_info).group(1).strip()
+
+ filter_java = re.compile(r'.+\.java$')
+ file_list = []
+ for root, dirs, files in os.walk(os.path.normpath(src_checksum_root_dir)):
+ for name in files:
+ if filter_java.match(name):
+ canonical_name = canonicalpath(os.path.join(root, name))
+ if not 'generated-sources' in canonical_name:
+ file_list.append(canonical_name)
+
+ # Sorting is done on unix-format names, case-folded, in order to get a platform-independent sort.
+ file_list.sort(key=str.upper)
+ file_count = len(file_list)
+ hash = hashlib.md5()
+ for name in file_list:
+ file_hash_string = md5sum(name)
+ hash.update(file_hash_string)
+
+ srcChecksum = hash.hexdigest()
+
+ target_dir = os.path.normpath(build_dir)
+ if not os.path.exists(target_dir):
+ os.makedirs(target_dir)
+
+ target_file = os.path.join(target_dir, 'package-info.java')
+ fout = open(target_file, "w")
+ fout.write(template_string % (annotation, version, revision, user, date, url, srcChecksum, package))
+ fout.close()
+
+ print("Checksummed %s src/**.java files" % file_count)
+ return 0
+
+##########################
+if __name__ == "__main__":
+ sys.exit(main())