Greetings. Per the setuptools docs, below is patch to add
support for the Monotone revision control system[1] to setuptools.
I've tested this patch lightly on Linux (Fedora Core 5) with Python
2.4.3 and Monotone 0.33.
Patch is against setuptools r54707 (which I think is "head").
Apologies if this isn't the appropriate place for these
patches. If that's the case and someone could advise me where they
should go (setuptools documentation doesn't seem too specific) I would
be grateful.
Dale
[1] http://monotone.ca/
--
Add support for automatically detecting files under control by
Monotone (mtn_revctrl). I also renamed _default_revctrl to
svn_cvs_revctrl, so that the naming could be more consistent.
Clearly my patches to the documentation were a bit slapdash, simply
adding Monotone to the list where appropriate; apologies.
Index: setuptools/command/sdist.py
===================================================================
--- setuptools/command/sdist.py (revision 54707)
+++ setuptools/command/sdist.py (working copy)
@@ -1,6 +1,7 @@
from distutils.command.sdist import sdist as _sdist
from distutils.util import convert_path
import os, re, sys, pkg_resources
+import popen2
entities = [
("<","<"), (">", ">"), (""", '"'), ("'", "'"),
@@ -45,7 +46,7 @@
for item in ep.load()(dirname):
yield item
-def _default_revctrl(dirname=''):
+def svn_cvs_revctrl(dirname=''):
for path, finder in finders:
path = joinpath(dirname,path)
if os.path.isfile(path):
@@ -53,7 +54,7 @@
if os.path.isfile(path):
yield path
elif os.path.isdir(path):
- for item in _default_revctrl(path):
+ for item in svn_cvs_revctrl(path):
yield item
def externals_finder(dirname, filename):
@@ -107,20 +108,147 @@
]
+class Monotone (object):
+ def __init__(self, command, capture_stderr=False):
+ if capture_stderr:
+ popen_constructor = popen2.Popen4
+ else:
+ popen_constructor = popen2.Popen3
+ mtn_executable = os.environ.get("MTN", "mtn")
+ popen = self._popen = popen_constructor("%s --xargs -"
+ % (mtn_executable,))
+ popen.tochild.write(command)
+ popen.tochild.close()
+ self.readline = popen.fromchild.readline
+ self._closed = False
+ def __iter__(self):
+ return iter(self._popen.fromchild)
+ def iter_inventory(self):
+ "Yields valid file names from 'automate inventory' output."
+ for line in self:
+ # The specs for this are in monotone's automate.cc. Briefly:
+ #
+ # * First column is " " for unchanged, "D"eleted, or
+ # "R"enamed from
+ # * Second column is " " for unchanged, "R"enamed to, or
+ # "A"dded
+ # * Third column is " " for unchanged, "P"atched, "U"nknown,
+ # "I"gnored, or "M"issing (from the filesystem)
+ #
+ # Then a space, two ID numbers separated by a space,
+ # another space, and the file name. So we strip the first
+ # columns, split on space twice, and return the tail end
+ # of the line which should be path/file.
+ line = line.rstrip()
+ if line[0] == " " and line[2] in " P":
+ yield line[4:].split(" ", 2)[2]
+ def discard_output(self):
+ for line in self:
+ pass
+ def _close(self):
+ assert not self._closed
+ self._popen.fromchild.close()
+ result = self._popen.wait()
+ if os.WIFEXITED(result):
+ self.exit_status = (True, os.WEXITSTATUS(result))
+ else:
+ self.exit_status = (False, result)
+ self._closed = True
+ return self.exit_status
+ def exited_normally(self):
+ if not self._closed:
+ self._close()
+ exited, code = self.exit_status
+ return exited and code == 0
+def acceptable_mtn_version():
+ mtn = Monotone("automate interface_version", capture_stderr=True)
+ version = mtn.readline().strip()
+ if not mtn.exited_normally():
+ return False
+ try:
+ major, minor = version.split(".", 1)
+ if 1 <= int(major) <= 4:
+ return True
+ else:
+ distutils.log.warn("no support for mtn automate version %r"
+ % (version,))
+ return False
+ except:
+ distutils.log.warn("couldn't parse mtn automate version %r"
+ % (version,))
+ return False
+def find_mtn_root(a_path):
+ assert os.path.isabs(a_path)
+ assert a_path == os.path.normpath(a_path)
+ if os.path.isdir(os.path.join(a_path, "_MTN")):
+ return a_path
+ else:
+ head, tail = os.path.split(a_path)
+ if head != a_path:
+ return find_mtn_root(head)
+ else:
+ return None
+def get_path_relative_to_mtn_root(mtn_root, abs_path):
+ common_path = os.path.commonprefix([mtn_root, abs_path])
+ return abs_path[len(common_path) + 1:]
+def call_with_cwd(temp_cwd, callable, *args, **kwargs):
+ orig_cwd = os.getcwd()
+ try:
+ try:
+ os.chdir(temp_cwd)
+ except OSError, e:
+ distutils.log.warn("error with mtn plug-in: %s" % (str(e),))
+ return None
+ return callable(*args, **kwargs)
+ finally:
+ os.chdir(orig_cwd)
+def mtn_revctrl(a_path):
+ abs_path = os.path.normpath(os.path.abspath(a_path))
+ mtn_root = find_mtn_root(abs_path)
+ if mtn_root is None or not acceptable_mtn_version():
+ return
+ mtn_relative_path = get_path_relative_to_mtn_root(mtn_root, abs_path)
+ if mtn_relative_path:
+ strip_before = len(mtn_relative_path) + 1
+ else:
+ strip_before = 0
+ mtn = call_with_cwd(abs_path, Monotone, "automate inventory")
+ if not mtn:
+ return
+ for file in mtn.iter_inventory():
+ if (file.startswith(mtn_relative_path)
+ and file.rstrip("/") != mtn_relative_path):
+ yield os.path.join(a_path, file[strip_before:])
+ if not mtn.exited_normally():
+ distutils.log.warn("error running mtn: exited=%r status=%r"
+ % mtn.exit_status)
+
+
+
+
+
+
+
+
+
+
+
+
+
class sdist(_sdist):
"""Smart sdist that finds anything supported by revision control"""
Index: setup.py
===================================================================
--- setup.py (revision 54707)
+++ setup.py (working copy)
@@ -70,7 +70,8 @@
% sys.version[:3]
],
"setuptools.file_finders":
- ["svn_cvs = setuptools.command.sdist:_default_revctrl"],
+ ["svn_cvs = setuptools.command.sdist:svn_cvs_revctrl",
+ "mtn = setuptools.command.sdist:mtn_revctrl"],
"setuptools.installation":
Index: setuptools.txt
===================================================================
--- setuptools.txt (revision 54707)
+++ setuptools.txt (working copy)
@@ -261,10 +261,10 @@
``include_package_data``
If set to ``True``, this tells ``setuptools`` to automatically include any
- data files it finds inside your package directories, that are either under
- CVS or Subversion control, or which are specified by your ``MANIFEST.in``
- file. For more information, see the section below on `Including Data
- Files`_.
+ data files it finds inside your package directories, that are under CVS,
+ Subversion, or Monotone control, or data files which are specified by your
+ ``MANIFEST.in`` file. For more information, see the section below on
+ `Including Data Files`_.
``exclude_package_data``
A dictionary mapping package names to lists of glob patterns that should
@@ -745,10 +745,10 @@
)
This tells setuptools to install any data files it finds in your packages. The
-data files must be under CVS or Subversion control, or else they must be
-specified via the distutils' ``MANIFEST.in`` file. (They can also be tracked
-by another revision control system, using an appropriate plugin. See the
-section below on `Adding Support for Other Revision Control Systems`_ for
+data files must be under CVS, Subversion, or Monotone control, or else they
+must be specified via the distutils' ``MANIFEST.in`` file. (They can also be
+tracked by another revision control system, using an appropriate plugin. See
+the section below on `Adding Support for Other Revision Control Systems`_ for
information on how to write such plugins.)
If you want finer-grained control over what files are included (for example, if
@@ -1429,17 +1429,17 @@
-------------------------------
``setuptools`` enhances the distutils' default algorithm for source file
-selection, so that all files managed by CVS or Subversion in your project tree
-are included in any source distribution you build. This is a big improvement
-over having to manually write a ``MANIFEST.in`` file and try to keep it in
-sync with your project. So, if you are using CVS or Subversion, and your
-source distributions only need to include files that you're tracking in
-revision control, don't create a a ``MANIFEST.in`` file for your project.
-(And, if you already have one, you might consider deleting it the next time
-you would otherwise have to change it.)
+selection, so that all files managed by CVS, Subversion, or Monotone in your
+project tree are included in any source distribution you build. This is a big
+improvement over having to manually write a ``MANIFEST.in`` file and try to
+keep it in sync with your project. So, if you are using CVS, Subversion, or
+Monotone, and your source distributions only need to include files that you're
+tracking in revision control, don't create a a ``MANIFEST.in`` file for your
+project. (And, if you already have one, you might consider deleting it the
+next time you would otherwise have to change it.)
-(NOTE: other revision control systems besides CVS and Subversion can be
-supported using plugins; see the section below on `Adding Support for Other
+(NOTE: other revision control systems besides CVS, Subversion, and Monotone can
+be supported using plugins; see the section below on `Adding Support for Other
Revision Control Systems`_ for information on how to write such plugins.)
If you need to include automatically generated files, or files that are kept in
@@ -2495,9 +2495,9 @@
-------------------------------------------------
If you would like to create a plugin for ``setuptools`` to find files in other
-source control systems besides CVS and Subversion, you can do so by adding an
-entry point to the ``setuptools.file_finders`` group. The entry point should
-be a function accepting a single directory name, and should yield
+source control systems besides CVS, Subversion, and Monotone, you can do so by
+adding an entry point to the ``setuptools.file_finders`` group. The entry
+point should be a function accepting a single directory name, and should yield
all the filenames within that directory (and any subdirectories thereof) that
are under revision control.
Index: setuptools.egg-info/entry_points.txt
===================================================================
--- setuptools.egg-info/entry_points.txt (revision 54707)
+++ setuptools.egg-info/entry_points.txt (working copy)
@@ -35,7 +35,8 @@
easy_install-2.3 = setuptools.command.easy_install:main
[setuptools.file_finders]
-svn_cvs = setuptools.command.sdist:_default_revctrl
+svn_cvs = setuptools.command.sdist:svn_cvs_revctrl
+mtn = setuptools.command.sdist:mtn_revctrl
[distutils.setup_keywords]
dependency_links = setuptools.dist:assert_string_list
Hello,
I needed support in easy_install for installing from HTTP
digest and basic authenticated sites so I wrote the included
patch. It currently supports specifying username and password
information at the command line (however misguided that may be)
and prompting the user interactively. It should also be easy to
integrate with graphical interfaces. Please consider it for
inclusion in the next release.
Thanks,
--
David D. Smith
At 09:38 AM 4/5/2007 +0200, Jan-Wijbrand Kolman wrote:
>So, this needs either a very clear explanation somewhere, or maybe a
>little bit of work on easy_install, in order to "cache" the
>credentials on a host/scheme basis.
I've added an entry to the "tips" section of the documentation (in my local
copy, not checked in anywhere yet):
Password-Protected Sites
------------------------
If a site you want to download from is password-protected using HTTP
"Basic" authentication, you can specify your credentials in the URL, like so::
http://some_userid:some_password@some.example.com/some_path/
You can do this with both index page URLs and direct download URLs. As
long as any HTML pages read by easy_install use *relative* links to point
to the downloads, the same user ID and password will be used to do the
downloading.
At 05:20 PM 4/4/2007 +0200, Jan-Wijbrand Kolman wrote:
>What I do is:
>
> easy_install -f \
> https://user:secret@myhost.com/trac/wiki/PackageIndex SomePackage
>
>This index page requires authentication and easy_install can indeed
>read the index page with the supplied credentials. It finds the
>correct download URL too, i.e.:
>
> https://myhost.com/svn/somepackage#egg=SomePackage
>
>It was my understanding that easy_install would reuse the credentials
>as specified for the index page URL, since both host and scheme are
>identical for the download and index page URLs. However downloading
>fails, with a 401 Authorization Required error.
>
>As I said, it could very well be I'm doing something wrong here. Any
>hint is highly appreciated.
Is the download link a *relative* URL, or absolute? If it's absolute, the
credentials won't be there.
I would like to announce the release of stdeb 0.2.a1.
= What is it? =
stdeb http://stdeb.python-hosting.com/ ("setuptools debian") produces
Debian source packages from Python packages via a new distutils command,
sdist_dsc, which produces a Debian source package of a Python package.
Automatic defaults are provided for the Debian package, but many aspects
of the resulting package can be customized via a configuration file.
= What's new? =
1) python-central support
2) lots of testing resulting in lots of bug fixes
= The gory details =
Changelog for Release 0.2.a1 (2007-04-02)
2007-04-02 Make default distribution 'unstable'
2007-03-28 Removed versioned Python interpreter from packages in
/usr/bin and /usr/lib. Bump version to 0.2.a1. Include
version in autogenerated debian/rules and debian/changelog.
2007-03-15 pycentral support enabled by default
2007-02-04 fix for cases in which setup.py wants __file__ variable
2006-09-07 added --patch-posix to support posix-mode patches
2006-09-07 always extract source using "dpkg-source -x"
2006-09-07 moved working directory for patches one level shallower
(may require patch level 1 instead of patch level 0)
2006-08-25 added Forced-Upstream-Version field in .cfg file
2006-08-22 patching source works when --premade-distfile option is
given but distfile must be regenerated
2006-08-22 patch level supported via --patch-level option
2006-08-22 Add support for bzip2 tarballs
2006-08-13 Generate source by copying tree, not "python setup.py
sdist"
2006-08-13 Patches can be applied prior to first call to setup.py
2006-07-21 Allow patches to upstream source via Stdeb-Patch-File in
.cfg file.
2006-07-21 Don't bother trying to rename .egg-info directories.
2006-07-09 Ability to specify MIME-Desktop-Files, MIME-File, and
Shared-MIME-File in configuration file.
2006-07-09 Use of dh_python for generation of postinst and prerm
scripts.
2006-07-05 Auto-generation of debian/postinst and debian/prerm scripts
that create and remove .pyc and .pyo files.
2006-06-21 Upstream .tar.gz files can be used exactly, allowing
md5sums to match.
2006-06-21 Expanded source directory is only deleted when commandline
option is set.