ant-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From anto...@apache.org
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 GMT
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:
  * <xslt>'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
        ===================================================================
   -->
-  <target name="main_distribution" depends="jars-sources,test-jar-source"
-    description="--> creates the zip and tar distributions">
+  <target name="-distribution_prep">
     <delete dir="${dist.base}"/>
     <delete dir="${dist.name}"/>
     <delete dir="${java-repository.dir}"/>
@@ -1161,6 +1160,10 @@
     <antcall inheritAll="false" target="internal_dist">
       <param name="dist.dir" value="${dist.name}"/>
     </antcall>
+  </target>
+
+  <target name="zip_distribution" depends="jars,-distribution_prep"
+    description="--> creates the zip distribution">
     <zip destfile="${dist.base.binaries}/${dist.name}-bin.zip">
       <zipfileset dir="${dist.name}/.." filemode="755">
         <include name="${dist.name}/bin/ant"/>
@@ -1176,6 +1179,22 @@
         <exclude name="${dist.name}/bin/*.py"/>
       </fileset>
     </zip>
+  </target>
+
+  <condition property="buildosxpackage">
+    <os family="mac"/>
+  </condition>
+
+  <target name="pkg_distribution" depends="zip_distribution" if="buildosxpackage">
+    <exec executable="release/build-osx-pkg.py">
+      <arg value="--output-dir"/>
+      <arg value="${dist.base.binaries}"/>
+      <arg value="${dist.base.binaries}/${dist.name}-bin.zip"/>
+    </exec>
+  </target>
+
+  <target name="tar_distribution" depends="jars,-distribution_prep"
+    description="--> creates the tar distribution">
     <tar longfile="gnu"
       destfile="${dist.base.binaries}/${dist.name}-bin.tar">
       <!-- removes redundant definition of permissions, but seems to
@@ -1201,6 +1220,10 @@
     <bzip2 destfile="${dist.base.binaries}/${dist.name}-bin.tar.bz2"
       src="${dist.base.binaries}/${dist.name}-bin.tar"/>
     <delete file="${dist.base.binaries}/${dist.name}-bin.tar"/>
+  </target>
+
+  <target name="main_distribution" depends="zip_distribution,pkg_distribution,tar_distribution,jars-sources,test-jar-source"
+    description="--> creates the zip, pkg, and tar distributions">
 
     <copy todir="${java-repository.dir}">
       <fileset dir="${dist.name}/lib">

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 @@
     <last>Galbraith</last>
   </name>
   <name>
+    <first>Ben</first>
+    <last>Gertzfield</last>
+  </name>
+  <name>
     <first>Benoit</first>
     <last>Moussaud</last>
   </name>

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 = *



Mime
View raw message