| Store | Cart

Re: [Python-Dev] Status of packaging in 3.3

From: Nick Coghlan <ncog...@gmail.com>
Fri, 22 Jun 2012 15:05:08 +1000
On Fri, Jun 22, 2012 at 10:01 AM, Donald Stufft <dona...@gmail.com> wrote:
> The idea i'm hoping for is to stop worrying about one implementation over> another and> hoping to create a common format that all the tools can agree upon and> create/install.

Right, and this is where it encouraged me to see in the Bento docs
that David had cribbed from RPM in this regard (although I don't
believe he has cribbed *enough*).

A packaging system really needs to cope with two very different levels
of packaging:
1. Source distributions (e.g. SRPMs). To get from this to useful
software requires developer tools.
2. "Binary" distributions (e.g. RPMs). To get from this to useful
software mainly requires a "file copy" utility (well, that and an
archive decompressor).

An SRPM is *just* a SPEC file and source tarball. That's it. To get
from that to an installed product, you have a bunch of additional
"BuildRequires" dependencies, along with %build and %install scripts
and a %files definition that define what will be packaged up and
included in the binary RPM. The exact nature of the metadata format
doesn't really matter, what matters is that it's a documented standard
that multiple tools can read.

An RPM includes files that actually get installed on the target
system. An RPM can be arch specific (if they include built binary
bits) or "noarch" if they're platform neutral.

distutils really only plays at the SRPM level - there is no defined OS
neutral RPM equivalent. That's why I brought up the bdist_simple
discussion earlier in the thread - if we can agree on a standard
bdist_simple format, then we can more cleanly decouple the "build"
step from the "install" step.

I think one of the key things to learn from the SPEC file format is
the configuration language it used for the various build phases: sh
(technically, any shell on the system, but almost everyone just uses
the default system shell)

This is why you can integrate whatever build system you like with it:
so long as you can invoke the build from the shell, then you can use
it to make your RPM.

Now, there's an obvious problem with this: it's completely useless
from a *cross-platform* building point of view. Isn't it a shame
there's no language we could use that would let us invoke build
systems in a cross platform way? Oh, wait...

So here's some sheer pie-in-the-sky speculation. If people like
elements of this idea enough to run with it, great. If not... oh well:

- I believe the "egg" term has way too much negative baggage (courtesy
of easy_install), and find the full term Distribution to be too easily
confused with "Linux distribution". However, "Python dist" is
unambiguous (since the more typical abbreviation for an aggregate
distribution is "distro"). Thus, I attempt to systematically refer to
the objects used to distribute Python software from developers to
users as "dists". In practice, this terminology is already used in
many places (distutils, sdist, bdist_msi, bdist_rpm, the .dist-info
format in PEP 376 etc). Thus, Python software is distributed as dists
(either sdists or bdists), which may in turn be converted to distro
packages (e.g. SRPMs and RPMs) for deployment to particular
environments.

- I reject setup.cfg, as I believe ini-style configuration files are
not appropriate for a metadata format that needs to include file
listings and code fragments

- I reject bento.info, as I think if we accept
yet-another-custom-configuration-file-format into the standard library
instead of just using YAML, we're even crazier than is already
apparent

- I shall use "dist.yaml" as my proposed name for my "I wish I could
define packages like this" format (and yes, that means adding yaml
support to the standard library is part of the wish)

- many of the details below will be flawed, but I want to give a clear
idea for how a concept like this might work in practice

- we need to define a clear set of build phases, and then design the
dist metadata format accordingly. For example:
    - source
        - uses a "source" section in dist.yaml
        - "source/install" maps source files directly to desired
install locations
           - essentially what the setup.cfg Resources section tries to do
           - used for pure Python code, documentation, etc
           - See below for example
        - "source/files" defines a list of extra files to be included
        - "source/exclude" defines the list of files to be excluded
        - "source/run" defines a Python fragment to be executed
        - serves a similar purpose to the "files" section in setup.cfg
        - creates a temporary directory (and sets it as the working directory)
        - dist.yaml is copied to the temporary directory
        - all files to be installed are copied to the temporary directory
        - all extra files are copied to the temporary directory
        - the Python fragment in "source/run" is executed (which can
thus easily add more files)
        - if sdist archive creation is requested, entire contents of
temporary directory are included
    - build
        - uses a "build" section in dist.yaml
        - "build/install" maps built files to desired install locations
           - like source/install, but for build artifacts
           - compiled C extensions, .pyc and .pyo files, etc would all go here
        - "build/run" defines a Python fragment to be executed
        - "build/files" defines the list of files to be included
        - "build/exclude" defines the list of files to be excluded
        - "build/requires" defines extra dependencies not needed at runtime
        - starting environment is a source directory that is either:
          - preexisting (e.g. to allow building in-place in the source tree)
          - created by running source first
          - created by unpacking an sdist archive
        - the Python fragment in "build/run" is executed to trigger the build
        - if the build succeeds (i.e. doesn't throw an exception)
          - create a temporary directory
          - copy dist.yaml
          - copy all specified files
          - this is the easiest way to exclude build artifacts from
the distribution, while still keeping them around to enable
incremental builds
        - if bdist_simple archive creation is requested, entire
contents of temporary directory are included
        - other bdist formats (such as bdist_rpm) will have their own
rules for getting from the bdist_simple format to the platform
specific format
    - install
        - uses an "install" section in dist.yaml
        - "install/pre" defines a Python fragment to be executed
before copying files
        - "install/post" defines a Python fragment to be executed
after copying files
        - starting environment is a bdist_simple directory that is either:
          - preexisting (e.g. to allow creation by system packaging tools)
          - created by running build first
          - created by unpacking a bdist_simple archive
        - end result is a fully installed and usable piece of software
    - test
        - uses a "test" section in dist.yaml
        - "test/run" defines a Python fragment to be executed to start the tests
        - "test/requires" defines extra dependencies needed to run the
test suite

- Example "source/install" based on
http://alexis.notmyidea.org/distutils2/setupcfg.html#complete-example
(my YAML may be a bit dodgy).
  - With this scheme, module installation is just another install category.
  - A solution for easily installing entire subtrees is desirable. I
propose the recursive glob ** syntax for that purpose.
  - Unlike setup.cfg, every category would have an "-excluded"
counterpart to filter unwanted files. Explicit is better than
implicit.

    source:
      install:
        modules:
          example.py
          example_pkg/*.py
          example_pkg/**/*.py
          example_pkg/resource.txt
        doc:
          README
          doc/*
        doc-excluded:
          doc/man
        man:
          doc/man
        scripts:
          # Directory details are stripped automatically
          scripts/LAUNCH
          scripts/*.{sh,bat}
          # But subdirectories can be made explicit
          extras/:
              scripts/extras/*.{sh,bat}

- the goal of a dist.yaml syntax would be to be *explicit* and
*comprehensive*. If this gets too verbose, then the solution would be
dist.yaml generators that are less expressive, but also reduce the
necessary boilerplate.

- a typical "sdist" will now just be an archive consisting of:
    - the project's dist.yaml file
    - all files created by the "source" phase

- the "bdist_simple" format will just be an archive consisting of:
    - the project's dist.yaml file
    - all files created by the "build" phase

- the source and build run hooks and install pre and post hooks become
the way you integrate with arbitrary build systems. No fancy command
or compiler system or anything like that, you just import whatever you
need and call it with the appropriate arguments. To other tools, they
will just be opaque chunks of text, but to the build system, they're
executable pieces of Python code, just as RPM includes executable
scripts.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncog...@gmail.com   |   Brisbane, Australia
_______________________________________________
Python-Dev mailing list
Pyth...@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/python-dev-ml%40activestate.com

Recent Messages in this Thread
Éric Araujo Jun 19, 2012 09:46 pm
mar...@v.loewis.de Jun 22, 2012 03:24 pm
Vinay Sajip Jun 22, 2012 03:48 pm
Vinay Sajip Jun 23, 2012 02:14 pm
Stephen J. Turnbull Jun 23, 2012 08:02 am
Donald Stufft Jun 22, 2012 04:56 pm
Paul Moore Jun 22, 2012 01:24 pm
Tarek Ziadé Jun 22, 2012 06:42 am
Nick Coghlan Jun 22, 2012 07:11 am
Donald Stufft Jun 22, 2012 12:01 am
Hynek Schlawack Jun 28, 2012 11:09 am
Ethan Furman Jun 19, 2012 10:09 pm
Nick Coghlan Jun 19, 2012 10:14 pm
Guido van Rossum Jun 20, 2012 04:36 am
Antoine Pitrou Jun 20, 2012 09:27 am
Hynek Schlawack Jun 20, 2012 11:20 am
Antoine Pitrou Jun 20, 2012 11:29 am
Éric Araujo Jun 20, 2012 03:34 pm
Georg Brandl Jun 20, 2012 03:44 pm
Tarek Ziadé Jun 20, 2012 04:24 pm
Paul Moore Jun 19, 2012 10:54 pm
Chris McDonough Jun 19, 2012 11:34 pm
Antoine Pitrou Jun 20, 2012 01:23 am
Nick Coghlan Jun 20, 2012 05:00 am
Antoine Pitrou Jun 20, 2012 09:04 am
Tarek Ziadé Jun 20, 2012 09:18 am
Victor Stinner Jun 20, 2012 06:36 am
Donald Stufft Jun 20, 2012 07:36 am
Georg Brandl Jun 20, 2012 07:09 am
Dirkjan Ochtman Jun 20, 2012 07:32 am
"Martin v. Löwis" Jun 20, 2012 08:18 am
Tarek Ziadé Jun 20, 2012 08:55 am
Dirkjan Ochtman Jun 20, 2012 09:05 am
Antoine Pitrou Jun 20, 2012 09:12 am
Tarek Ziadé Jun 20, 2012 09:22 am
Antoine Pitrou Jun 20, 2012 09:49 am
Tarek Ziadé Jun 20, 2012 10:30 am
Antoine Pitrou Jun 20, 2012 10:39 am
Tarek Ziadé Jun 20, 2012 10:54 am
Georg Brandl Jun 20, 2012 11:06 am
Vinay Sajip Jun 20, 2012 09:51 am
Antoine Pitrou Jun 20, 2012 09:54 am
Tarek Ziadé Jun 20, 2012 10:34 am
Paul Moore Jun 20, 2012 11:19 am
Tarek Ziadé Jun 20, 2012 11:31 am
Nick Coghlan Jun 20, 2012 12:53 pm
Paul Moore Jun 20, 2012 01:10 pm
Alexis Métaireau Jun 20, 2012 01:19 pm
Nick Coghlan Jun 20, 2012 01:28 pm
Alexis Métaireau Jun 20, 2012 01:36 pm
Tarek Ziadé Jun 21, 2012 12:00 pm
Alexis Métaireau Jun 20, 2012 01:16 pm
Paul Moore Jun 20, 2012 01:47 pm
Paul Moore Jun 20, 2012 11:11 am
Antoine Pitrou Jun 20, 2012 11:46 am
Nick Coghlan Jun 20, 2012 01:02 pm
Bill Janssen Jun 20, 2012 02:46 pm
PJ Eby Jun 20, 2012 05:29 pm
Nick Coghlan Jun 21, 2012 03:57 am
Chris McDonough Jun 21, 2012 04:44 am
Nick Coghlan Jun 21, 2012 08:45 am
David Cournapeau Jun 21, 2012 09:28 am
Nick Coghlan Jun 21, 2012 11:58 am
David Cournapeau Jun 21, 2012 12:19 pm
Nick Coghlan Jun 21, 2012 12:31 pm
Chris McDonough Jun 21, 2012 11:48 am
Oscar Benjamin Jun 21, 2012 12:07 pm
Nick Coghlan Jun 21, 2012 12:21 pm
Chris McDonough Jun 21, 2012 12:51 pm
Nick Coghlan Jun 21, 2012 01:29 pm
Chris McDonough Jun 21, 2012 02:12 pm
Nick Coghlan Jun 21, 2012 02:30 pm
Chris McDonough Jun 21, 2012 02:59 pm
Nick Coghlan Jun 21, 2012 03:48 pm
Jesse Noller Jun 22, 2012 04:12 pm
PJ Eby Jun 21, 2012 03:45 pm
Chris McDonough Jun 21, 2012 04:02 pm
Chris Lambacher Jun 21, 2012 03:17 pm
Barry Warsaw Jun 21, 2012 02:08 pm
Vinay Sajip Jun 21, 2012 01:45 pm
Barry Warsaw Jun 21, 2012 01:57 pm
Nick Coghlan Jun 21, 2012 02:09 pm
Dag Sverre Seljebotn Jun 21, 2012 09:08 am
Tarek Ziadé Jun 21, 2012 11:56 am
Dag Sverre Seljebotn Jun 21, 2012 12:45 pm
Tarek Ziadé Jun 21, 2012 01:23 pm
Dag Sverre Seljebotn Jun 21, 2012 02:26 pm
Tarek Ziadé Jun 21, 2012 07:05 pm
Dag Sverre Seljebotn Jun 21, 2012 08:46 pm
Tarek Ziadé Jun 21, 2012 09:04 pm
David Cournapeau Jun 21, 2012 09:55 pm
Tarek Ziadé Jun 21, 2012 10:42 pm
Dag Sverre Seljebotn Jun 21, 2012 10:05 pm
Dag Sverre Seljebotn Jun 21, 2012 10:25 pm
Antoine Pitrou Jun 21, 2012 10:00 pm
David Cournapeau Jun 21, 2012 10:32 pm
Alex Clark Jun 21, 2012 01:56 pm
PJ Eby Jun 21, 2012 01:31 pm
Nick Coghlan Jun 21, 2012 02:03 pm
Zooko Wilcox-OHearn Jun 21, 2012 03:02 pm
Antoine Pitrou Jun 21, 2012 03:10 pm
PJ Eby Jun 21, 2012 03:37 pm
Chris McDonough Jun 21, 2012 03:50 pm
Tarek Ziadé Jun 21, 2012 04:03 pm
PJ Eby Jun 21, 2012 04:26 pm
Chris McDonough Jun 21, 2012 04:44 pm
Tarek Ziadé Jun 21, 2012 05:20 pm
Alex Clark Jun 21, 2012 05:43 pm
PJ Eby Jun 21, 2012 05:49 pm
Tarek Ziadé Jun 21, 2012 06:49 pm
Chris McDonough Jun 21, 2012 05:56 pm
Tarek Ziadé Jun 21, 2012 07:17 pm
Paul Moore Jun 21, 2012 08:01 pm
PJ Eby Jun 21, 2012 08:34 pm
Donald Stufft Jun 21, 2012 09:38 pm
Alex Clark Jun 21, 2012 11:34 pm
Stephen J. Turnbull Jun 22, 2012 06:25 am
Nick Coghlan Jun 22, 2012 06:30 am
Tarek Ziadé Jun 20, 2012 09:17 am
Antoine Pitrou Jun 22, 2012 08:40 pm
Paul Moore Jun 22, 2012 01:48 pm
Vinay Sajip Jun 22, 2012 03:36 pm
David Cournapeau Jun 22, 2012 01:47 pm
Vinay Sajip Jun 22, 2012 12:09 pm
Dag Sverre Seljebotn Jun 23, 2012 01:37 pm
Antoine Pitrou Jun 23, 2012 01:28 pm
Barry Warsaw Jun 22, 2012 12:14 pm
Antoine Pitrou Jun 22, 2012 02:19 pm
Antoine Pitrou Jun 23, 2012 02:24 pm
Tim Golden Jun 22, 2012 12:23 pm
Stephen J. Turnbull Jun 22, 2012 12:39 pm
Nick Coghlan Jun 23, 2012 11:57 am
mar...@v.loewis.de Jun 28, 2012 11:56 am
David Cournapeau Jun 23, 2012 11:53 am
Lennart Regebro Jun 23, 2012 11:55 am
Alexandre Zani Jun 22, 2012 05:09 pm
Floris Bruynooghe Jun 23, 2012 10:52 am
Donald Stufft Jun 22, 2012 10:38 am
Antoine Pitrou Jun 23, 2012 12:35 pm
Vinay Sajip Jun 23, 2012 01:14 pm
Dag Sverre Seljebotn Jun 23, 2012 12:48 pm
Vinay Sajip Jun 23, 2012 01:20 pm
Terry Reedy Jun 22, 2012 08:55 pm
Donald Stufft Jun 22, 2012 09:06 pm
Dag Sverre Seljebotn Jun 22, 2012 10:28 am
Paul Moore Jun 22, 2012 11:27 am
Antoine Pitrou Jun 22, 2012 09:55 am
Alex Clark Jun 22, 2012 01:13 pm
Vinay Sajip Jun 22, 2012 09:11 am
Nick Coghlan Jun 22, 2012 06:29 am
Nick Coghlan Jun 22, 2012 05:05 am
Dag Sverre Seljebotn Jun 23, 2012 11:13 am
Vinay Sajip Jun 23, 2012 12:27 pm
Barry Warsaw Jun 22, 2012 12:20 pm
Dag Sverre Seljebotn Jun 22, 2012 09:52 am
Vinay Sajip Jun 22, 2012 10:09 am
Donald Stufft Jun 22, 2012 10:35 am
Vinay Sajip Jun 22, 2012 07:56 am
Donald Stufft Jun 22, 2012 09:38 am
PJ Eby Jun 22, 2012 08:11 pm
David Cournapeau Jun 22, 2012 08:35 pm
David Cournapeau Jun 22, 2012 10:20 am
Donald Stufft Jun 22, 2012 08:05 am
Dag Sverre Seljebotn Jun 22, 2012 09:22 am
Messages in this thread