You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by Ben Gertzfield <bg...@gmail.com> on 2013/12/17 02:18:43 UTC

Contributing a tool to build OS X .pkg of Apache Ant

Hi Ant folks,

As of OS X version 10.9 ("Mavericks"), OS X no longer includes Apache Ant.

To help people who don't want to install Homebrew or similar systems to
grab Ant, I wrote a Python script to build a OS X .pkg installer of Ant:

http://pastebin.com/raw.php?i=StmYCeZd

I'd like to contribute this script (which runs on OS X) to the project, but
I'm not sure which Ant repo it belongs in (core? build? antlibs?).

Where should this script live?

Thanks,

Ben

Re: Contributing a tool to build OS X .pkg of Apache Ant

Posted by Antoine Levy Lambert <an...@gmx.de>.
Thanks Ben,

I will apply your patch within a few days, I am too tired tonight.

Regards,

Antoine
On Dec 17, 2013, at 12:17 AM, Antoine Levy Lambert wrote:

> Hello Ben,
> 
> this should be living in ant core. Either in the root directory or in the release directory.
> 
> Regards,
> 
> Antoine
> On Dec 16, 2013, at 8:18 PM, Ben Gertzfield wrote:
> 
>> Hi Ant folks,
>> 
>> As of OS X version 10.9 ("Mavericks"), OS X no longer includes Apache Ant.
>> 
>> To help people who don't want to install Homebrew or similar systems to
>> grab Ant, I wrote a Python script to build a OS X .pkg installer of Ant:
>> 
>> http://pastebin.com/raw.php?i=StmYCeZd
>> 
>> I'd like to contribute this script (which runs on OS X) to the project, but
>> I'm not sure which Ant repo it belongs in (core? build? antlibs?).
>> 
>> Where should this script live?
>> 
>> Thanks,
>> 
>> Ben
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
> For additional commands, e-mail: dev-help@ant.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Contributing a tool to build OS X .pkg of Apache Ant

Posted by Ben Gertzfield <bg...@gmail.com>.
Looks like I should have filed this as an Ant Enhancement task.

I've just done so and filed Ant Bug 55899 along with a patch:

https://issues.apache.org/bugzilla/show_bug.cgi?id=55899

Ben



On Tue, Dec 17, 2013 at 10:50 AM, Ben Gertzfield <bg...@gmail.com>wrote:

> Excellent. I'm not sure what the process is for code review, but here's a
> patch against SVN trunk @ r1551525.
>
> The patch adds an OS X .pkg installer generation script under
> 'release/build-osx-pkg.py' and updates build.xml to conditionally build an
> OS X .pkg installer when it's run on OS X hosts.
>
> From bf8c0746ef979aff0e439b4e2fe917e78023356a Mon Sep 17 00:00:00 2001
> From: Ben Gertzfield <be...@fb.com>
> Date: Tue, 17 Dec 2013 10:43:53 -0800
> Subject: [PATCH] Add OS X build script. Split targets zip_distribution,
>  tar_distribution, pkg_distribution off main_distribution.
>
> ---
>  build.xml                |  27 ++++++-
>  release/build-osx-pkg.py | 179
> +++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 204 insertions(+), 2 deletions(-)
>  create mode 100755 release/build-osx-pkg.py
>
> diff --git a/build.xml b/build.xml
> index af9123c..c1e58f1 100644
> --- a/build.xml
> +++ b/build.xml
> @@ -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">
> diff --git a/release/build-osx-pkg.py b/release/build-osx-pkg.py
> new file mode 100755
> index 0000000..4144a03
> --- /dev/null
> +++ b/release/build-osx-pkg.py
> @@ -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()
> --
> 1.8.3.4 (Apple Git-47)
>
>
>
> On Mon, Dec 16, 2013 at 9:17 PM, Antoine Levy Lambert <an...@gmx.de>wrote:
>
>> Hello Ben,
>>
>> this should be living in ant core. Either in the root directory or in the
>> release directory.
>>
>> Regards,
>>
>> Antoine
>> On Dec 16, 2013, at 8:18 PM, Ben Gertzfield wrote:
>>
>> > Hi Ant folks,
>> >
>> > As of OS X version 10.9 ("Mavericks"), OS X no longer includes Apache
>> Ant.
>> >
>> > To help people who don't want to install Homebrew or similar systems to
>> > grab Ant, I wrote a Python script to build a OS X .pkg installer of Ant:
>> >
>> > http://pastebin.com/raw.php?i=StmYCeZd
>> >
>> > I'd like to contribute this script (which runs on OS X) to the project,
>> but
>> > I'm not sure which Ant repo it belongs in (core? build? antlibs?).
>> >
>> > Where should this script live?
>> >
>> > Thanks,
>> >
>> > Ben
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
>> For additional commands, e-mail: dev-help@ant.apache.org
>>
>>
>

Re: Contributing a tool to build OS X .pkg of Apache Ant

Posted by Ben Gertzfield <bg...@gmail.com>.
Excellent. I'm not sure what the process is for code review, but here's a
patch against SVN trunk @ r1551525.

The patch adds an OS X .pkg installer generation script under
'release/build-osx-pkg.py' and updates build.xml to conditionally build an
OS X .pkg installer when it's run on OS X hosts.

>From bf8c0746ef979aff0e439b4e2fe917e78023356a Mon Sep 17 00:00:00 2001
From: Ben Gertzfield <be...@fb.com>
Date: Tue, 17 Dec 2013 10:43:53 -0800
Subject: [PATCH] Add OS X build script. Split targets zip_distribution,
 tar_distribution, pkg_distribution off main_distribution.

---
 build.xml                |  27 ++++++-
 release/build-osx-pkg.py | 179
+++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 204 insertions(+), 2 deletions(-)
 create mode 100755 release/build-osx-pkg.py

diff --git a/build.xml b/build.xml
index af9123c..c1e58f1 100644
--- a/build.xml
+++ b/build.xml
@@ -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">
diff --git a/release/build-osx-pkg.py b/release/build-osx-pkg.py
new file mode 100755
index 0000000..4144a03
--- /dev/null
+++ b/release/build-osx-pkg.py
@@ -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()
-- 
1.8.3.4 (Apple Git-47)



On Mon, Dec 16, 2013 at 9:17 PM, Antoine Levy Lambert <an...@gmx.de>wrote:

> Hello Ben,
>
> this should be living in ant core. Either in the root directory or in the
> release directory.
>
> Regards,
>
> Antoine
> On Dec 16, 2013, at 8:18 PM, Ben Gertzfield wrote:
>
> > Hi Ant folks,
> >
> > As of OS X version 10.9 ("Mavericks"), OS X no longer includes Apache
> Ant.
> >
> > To help people who don't want to install Homebrew or similar systems to
> > grab Ant, I wrote a Python script to build a OS X .pkg installer of Ant:
> >
> > http://pastebin.com/raw.php?i=StmYCeZd
> >
> > I'd like to contribute this script (which runs on OS X) to the project,
> but
> > I'm not sure which Ant repo it belongs in (core? build? antlibs?).
> >
> > Where should this script live?
> >
> > Thanks,
> >
> > Ben
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
> For additional commands, e-mail: dev-help@ant.apache.org
>
>

Re: Contributing a tool to build OS X .pkg of Apache Ant

Posted by Antoine Levy Lambert <an...@gmx.de>.
Hello Ben,

this should be living in ant core. Either in the root directory or in the release directory.

Regards,

Antoine
On Dec 16, 2013, at 8:18 PM, Ben Gertzfield wrote:

> Hi Ant folks,
> 
> As of OS X version 10.9 ("Mavericks"), OS X no longer includes Apache Ant.
> 
> To help people who don't want to install Homebrew or similar systems to
> grab Ant, I wrote a Python script to build a OS X .pkg installer of Ant:
> 
> http://pastebin.com/raw.php?i=StmYCeZd
> 
> I'd like to contribute this script (which runs on OS X) to the project, but
> I'm not sure which Ant repo it belongs in (core? build? antlibs?).
> 
> Where should this script live?
> 
> Thanks,
> 
> Ben


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org