Return-Path: X-Original-To: apmail-ant-notifications-archive@minotaur.apache.org Delivered-To: apmail-ant-notifications-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id B04CF10756 for ; Mon, 23 Dec 2013 04:43:21 +0000 (UTC) Received: (qmail 59242 invoked by uid 500); 23 Dec 2013 04:43:19 -0000 Delivered-To: apmail-ant-notifications-archive@ant.apache.org Received: (qmail 59192 invoked by uid 500); 23 Dec 2013 04:43:08 -0000 Mailing-List: contact notifications-help@ant.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ant.apache.org Delivered-To: mailing list notifications@ant.apache.org Received: (qmail 59179 invoked by uid 99); 23 Dec 2013 04:43:02 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 23 Dec 2013 04:43:02 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 23 Dec 2013 04:42:58 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id E52FF238897A for ; Mon, 23 Dec 2013 04:42:36 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1553066 - in /ant/core/trunk: CONTRIBUTORS WHATSNEW build.xml contributors.xml release/build-osx-pkg.py Date: Mon, 23 Dec 2013 04:42:36 -0000 To: notifications@ant.apache.org From: antoine@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20131223044236.E52FF238897A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: antoine Date: Mon Dec 23 04:42:36 2013 New Revision: 1553066 URL: http://svn.apache.org/r1553066 Log: adding Mac OS X .pkg installer generation in build, PR 55899 Added: ant/core/trunk/release/build-osx-pkg.py (with props) Modified: ant/core/trunk/CONTRIBUTORS ant/core/trunk/WHATSNEW ant/core/trunk/build.xml ant/core/trunk/contributors.xml Modified: ant/core/trunk/CONTRIBUTORS URL: http://svn.apache.org/viewvc/ant/core/trunk/CONTRIBUTORS?rev=1553066&r1=1553065&r2=1553066&view=diff ============================================================================== --- ant/core/trunk/CONTRIBUTORS (original) +++ ant/core/trunk/CONTRIBUTORS Mon Dec 23 04:42:36 2013 @@ -36,6 +36,7 @@ Balazs Fejes 2 Bart Vanhaute Benjamin Burgess Ben Galbraith +Ben Gertzfield Benoit Moussaud Bernd Dutkowski Bernhard Rosenkraenzer Modified: ant/core/trunk/WHATSNEW URL: http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?rev=1553066&r1=1553065&r2=1553066&view=diff ============================================================================== --- ant/core/trunk/WHATSNEW (original) +++ ant/core/trunk/WHATSNEW Mon Dec 23 04:42:36 2013 @@ -46,6 +46,9 @@ Other changes: * 's params can now be typed. Bugzilla Report 21525. + * build of Mac OS X pkg installer + Bugzilla Report 55899. + Changes from Ant 1.9.1 TO Ant 1.9.2 =================================== Modified: ant/core/trunk/build.xml URL: http://svn.apache.org/viewvc/ant/core/trunk/build.xml?rev=1553066&r1=1553065&r2=1553066&view=diff ============================================================================== --- ant/core/trunk/build.xml (original) +++ ant/core/trunk/build.xml Mon Dec 23 04:42:36 2013 @@ -1148,8 +1148,7 @@ Create the binary distribution =================================================================== --> - + @@ -1161,6 +1160,10 @@ + + + @@ -1176,6 +1179,22 @@ + + + + + + + + + + + + + + + creates the zip, pkg, and tar distributions"> Modified: ant/core/trunk/contributors.xml URL: http://svn.apache.org/viewvc/ant/core/trunk/contributors.xml?rev=1553066&r1=1553065&r2=1553066&view=diff ============================================================================== --- ant/core/trunk/contributors.xml (original) +++ ant/core/trunk/contributors.xml Mon Dec 23 04:42:36 2013 @@ -169,6 +169,10 @@ Galbraith + Ben + Gertzfield + + Benoit Moussaud Added: ant/core/trunk/release/build-osx-pkg.py URL: http://svn.apache.org/viewvc/ant/core/trunk/release/build-osx-pkg.py?rev=1553066&view=auto ============================================================================== --- ant/core/trunk/release/build-osx-pkg.py (added) +++ ant/core/trunk/release/build-osx-pkg.py Mon Dec 23 04:42:36 2013 @@ -0,0 +1,179 @@ +#!/usr/bin/env 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. + +# Builds a Mac OS X .pkg from a binary ZIP archive of Apache Ant. + +import collections +import contextlib +import os + +ApacheAntURL = collections.namedtuple( + 'ApacheAntURL', + ('url', 'url_scheme', 'version', 'directory_name')) + +@contextlib.contextmanager +def make_temp_directory(): + '''Creates a temporary directory which is recursively deleted when out of scope.''' + import shutil + import tempfile + temp_dir = tempfile.mkdtemp() + yield temp_dir + shutil.rmtree(temp_dir) + +@contextlib.contextmanager +def self_closing_url(url): + '''Opens a URL and returns a self-closing file-like object.''' + import urllib2 + url_fp = urllib2.urlopen(url) + yield url_fp + url_fp.close() + +def apache_ant_url(url_string): + '''Parses a URL string into an ApacheAntURL object.''' + import argparse, collections, os.path, urlparse + parse_result = urlparse.urlparse(url_string) + filename = os.path.split(parse_result.path)[1] + if not (filename.startswith('apache-ant-') and filename.endswith('-bin.zip')): + raise argparse.ArgumentTypeError( + 'Expected [%s] to end with apache-ant-X.Y.Z-bin.zip' % (url_string)) + extracted_directory = filename.replace('-bin.zip', '') + extracted_version = extracted_directory.replace('apache-ant-', '') + return ApacheAntURL( + url=url_string, + url_scheme=parse_result.scheme, + version=extracted_version, + directory_name=extracted_directory) + +def fetch_url(url, local_output_file): + '''Downloads the contents of 'url' and writes them the opened file 'output_file'.''' + import shutil + import urllib2 + CHUNK_SIZE = 16 * 1024 + print 'Fetching {url}...'.format(url=url) + with self_closing_url(url) as url_input_file: + while True: + chunk = url_input_file.read(CHUNK_SIZE) + if not chunk: + break + local_output_file.write(chunk) + local_output_file.seek(0) + +def fetch_apache_ant_url(apache_ant_url, temp_dir): + '''If the ApacheAntURL object is remote, fetches and returns the local file object. + Otherwise, opens and returns a file object.''' + import tempfile + if apache_ant_url.url_scheme == '' or apache_ant_url.url_scheme == 'file': + return open(apache_ant_url.url, 'rb') + else: + fp = tempfile.TemporaryFile(dir=temp_dir) + fetch_url(apache_ant_url.url, fp) + return fp + +def uncompress_contents(temp_dir, archive_file, directory_name, path_prefix): + '''Uncompresses the contents of 'archive_file' to 'temp_dir'. + + Strips the prefix 'directory_name' and prepends 'path_prefix' to each entry + of the zip file. + ''' + import shutil, zipfile + output_path = os.path.join(temp_dir, 'pkg') + os.mkdir(output_path) + z = zipfile.ZipFile(archive_file) + print 'Extracting archive to {output_path}...'.format( + output_path=output_path) + for entry in z.infolist(): + # We can't just extract directly, since we want to map: + # + # apache-ant-X.Y.Z/bin/foo + # + # to + # + # usr/local/ant/bin/foo + # + # So, we strip out the apache-ant-X.Y.Z prefix, then instead of + # using ZipFile.extract(), we use ZipFile.open() to get a read fd to + # the source file, then os.fdopen() with the appropriate permissions + # to geta write fd to the modified destination path. + expected_prefix = directory_name + '/' + if not entry.filename.startswith(expected_prefix): + raise Exeption('Unexpected entry in zip file: [{filename}]'.format( + filename=entry.filename)) + entry_path = entry.filename.replace(expected_prefix, '', 1) + + # Using os.path.join is annoying here (we'd have to explode output_path + # and entry_path). + entry_output_path = output_path + path_prefix + '/' + entry_path + + # Zip file paths are normalized with '/' at the end for directories. + if entry_output_path.endswith('/'): + print 'Creating directory {path}'.format(path=entry_output_path) + os.makedirs(entry_output_path) + else: + # Yes, this is really how you extract permissions from a ZipInfo entry. + perms = (entry.external_attr >> 16L) & 0777 + print 'Extracting {entry_filename} to {path} with mode 0{mode:o}'.format( + entry_filename=entry.filename, path=entry_output_path, mode=perms) + with z.open(entry) as source: + with os.fdopen( + os.open(entry_output_path, os.O_WRONLY | os.O_CREAT, perms), 'w') \ + as destination: + shutil.copyfileobj(source, destination) + return output_path + +def write_paths_d_entry(paths_d_directory, filename): + os.makedirs(paths_d_directory) + output_file = os.path.join(paths_d_directory, filename) + with open(output_file, 'w') as f: + print >>f, '/usr/local/ant/bin' + +def make_pkg(pkg_dir, pkg_identifier, pkg_version, output_pkg_path): + import subprocess + print 'Building package at {output_pkg_path}...'.format( + output_pkg_path=output_pkg_path) + subprocess.call( + ['pkgbuild', + '--root', pkg_dir, + '--identifier', pkg_identifier, + '--version', pkg_version, + output_pkg_path]) + +def main(): + import argparse + parser = argparse.ArgumentParser(description='Builds a Mac OS X .pkg of ant.') + parser.add_argument( + 'apache_ant_url', + metavar='file-or-url', + help='Source file or URL from which to uncompress apache-ant-X.Y.Z-bin.zip', + type=apache_ant_url) + parser.add_argument( + '--output-dir', + default='.', + help='Directory to which .pkg will be written. Defaults to current directory.') + args = parser.parse_args() + with make_temp_directory() as temp_dir: + archive_file = fetch_apache_ant_url(args.apache_ant_url, temp_dir) + pkg_dir = uncompress_contents( + temp_dir, archive_file, args.apache_ant_url.directory_name, '/usr/local/ant') + etc_paths_d_dir = os.path.join(pkg_dir, 'etc', 'paths.d') + write_paths_d_entry(etc_paths_d_dir, 'org.apache.ant') + pkg_identifier = 'org.apache.ant' + output_pkg_path = os.path.join( + args.output_dir, args.apache_ant_url.directory_name + '.pkg') + make_pkg(pkg_dir, pkg_identifier, args.apache_ant_url.version, output_pkg_path) + +if __name__ == '__main__': + main() Propchange: ant/core/trunk/release/build-osx-pkg.py ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ant/core/trunk/release/build-osx-pkg.py ------------------------------------------------------------------------------ svn:executable = *