Commit fb98a95e authored by PJ Eby's avatar PJ Eby

Added ``--local-snapshots-ok`` flag, to allow building eggs from

projects installed using ``setup.py develop``.  (backport from trunk)

--HG--
branch : setuptools-0.6
extra : convert_revision : svn%3A6015fed2-1504-0410-9fe1-9d1591cc4771/sandbox/branches/setuptools-0.6%4053877
parent aba13220
...@@ -383,6 +383,13 @@ prevents .pth files from being used, ``-a`` means to copy all the eggs needed, ...@@ -383,6 +383,13 @@ prevents .pth files from being used, ``-a`` means to copy all the eggs needed,
even if they're installed elsewhere on the machine, and ``-d`` indicates the even if they're installed elsewhere on the machine, and ``-d`` indicates the
directory to place the eggs in.) directory to place the eggs in.)
You can also build the eggs from local development packages that were installed
with the ``setup.py develop`` command, by including the ``-l`` option, e.g.::
easy_install -zmaxld somedir SomePackage
This will use locally-available source distributions to build the eggs.
Packaging Others' Projects As Eggs Packaging Others' Projects As Eggs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...@@ -887,6 +894,25 @@ Command-Line Options ...@@ -887,6 +894,25 @@ Command-Line Options
script directories, and does not override the ones set on the command line script directories, and does not override the ones set on the command line
or in a configuration file. or in a configuration file.
``--local-snapshots-ok, -l`` (New in 0.6c6)
Normally, EasyInstall prefers to only install *released* versions of
projects, not in-development ones, because such projects may not
have a currently-valid version number. So, it usually only installs them
when their ``setup.py`` directory is explicitly passed on the command line.
However, if this option is used, then any in-development projects that were
installed using the ``setup.py develop`` command, will be used to build
eggs, effectively upgrading the "in-development" project to a snapshot
release. Normally, this option is used only in conjunction with the
``--always-copy`` option to create a distributable snapshot of every egg
needed to run an application.
Note that if you use this option, you must make sure that there is a valid
version number (such as an SVN revision number tag) for any in-development
projects that may be used, as otherwise EasyInstall may not be able to tell
what version of the project is "newer" when future installations or
upgrades are attempted.
.. _non-root installation: .. _non-root installation:
...@@ -1201,6 +1227,9 @@ Release Notes/Change History ...@@ -1201,6 +1227,9 @@ Release Notes/Change History
* Fixed distutils-style scripts originally built on Windows having their line * Fixed distutils-style scripts originally built on Windows having their line
endings doubled when installed on any platform. endings doubled when installed on any platform.
* Added ``--local-snapshots-ok`` flag, to allow building eggs from projects
installed using ``setup.py develop``.
0.6c5 0.6c5
* Fixed ``.dll`` files on Cygwin not having executable permisions when an egg * Fixed ``.dll`` files on Cygwin not having executable permisions when an egg
......
...@@ -1676,7 +1676,7 @@ def find_on_path(importer, path_item, only=False): ...@@ -1676,7 +1676,7 @@ def find_on_path(importer, path_item, only=False):
if not line.strip(): continue if not line.strip(): continue
for item in find_distributions(os.path.join(path_item,line.rstrip())): for item in find_distributions(os.path.join(path_item,line.rstrip())):
yield item yield item
break
register_finder(ImpWrapper,find_on_path) register_finder(ImpWrapper,find_on_path)
_namespace_handlers = {} _namespace_handlers = {}
......
...@@ -31,7 +31,7 @@ class develop(easy_install): ...@@ -31,7 +31,7 @@ class develop(easy_install):
self.uninstall = None self.uninstall = None
self.egg_path = None self.egg_path = None
easy_install.initialize_options(self) easy_install.initialize_options(self)
self.setup_path = None
...@@ -61,6 +61,7 @@ class develop(easy_install): ...@@ -61,6 +61,7 @@ class develop(easy_install):
" directory to "+target " directory to "+target
) )
# Make a distribution for the package's source # Make a distribution for the package's source
self.dist = Distribution( self.dist = Distribution(
target, target,
...@@ -68,16 +69,15 @@ class develop(easy_install): ...@@ -68,16 +69,15 @@ class develop(easy_install):
project_name = ei.egg_name project_name = ei.egg_name
) )
p = self.egg_base.replace(os.sep,'/')
if p!= os.curdir:
p = '../' * (p.count('/')+1)
self.setup_path = p
p = normalize_path(os.path.join(self.install_dir, self.egg_path, p))
if p != normalize_path(os.curdir):
raise DistutilsOptionError(
"Can't get a consistent path to setup script from"
" installation directory", p, normalize_path(os.curdir))
def install_for_development(self): def install_for_development(self):
...@@ -95,7 +95,7 @@ class develop(easy_install): ...@@ -95,7 +95,7 @@ class develop(easy_install):
log.info("Creating %s (link to %s)", self.egg_link, self.egg_base) log.info("Creating %s (link to %s)", self.egg_link, self.egg_base)
if not self.dry_run: if not self.dry_run:
f = open(self.egg_link,"w") f = open(self.egg_link,"w")
f.write(self.egg_path) f.write(self.egg_path + "\n" + self.setup_path)
f.close() f.close()
# postprocess the installed distro, fixing up .pth, installing scripts, # postprocess the installed distro, fixing up .pth, installing scripts,
# and handling requirements # and handling requirements
...@@ -106,7 +106,7 @@ class develop(easy_install): ...@@ -106,7 +106,7 @@ class develop(easy_install):
if os.path.exists(self.egg_link): if os.path.exists(self.egg_link):
log.info("Removing %s (link to %s)", self.egg_link, self.egg_base) log.info("Removing %s (link to %s)", self.egg_link, self.egg_base)
contents = [line.rstrip() for line in file(self.egg_link)] contents = [line.rstrip() for line in file(self.egg_link)]
if contents != [self.egg_path]: if contents not in ([self.egg_path], [self.egg_path, self.setup_path]):
log.warn("Link points to %s: uninstall aborted", contents) log.warn("Link points to %s: uninstall aborted", contents)
return return
if not self.dry_run: if not self.dry_run:
......
...@@ -70,18 +70,18 @@ class easy_install(Command): ...@@ -70,18 +70,18 @@ class easy_install(Command):
('editable', 'e', "Install specified packages in editable form"), ('editable', 'e', "Install specified packages in editable form"),
('no-deps', 'N', "don't install dependencies"), ('no-deps', 'N', "don't install dependencies"),
('allow-hosts=', 'H', "pattern(s) that hostnames must match"), ('allow-hosts=', 'H', "pattern(s) that hostnames must match"),
('local-snapshots-ok', 'l', "allow building eggs from local checkouts"),
] ]
boolean_options = [ boolean_options = [
'zip-ok', 'multi-version', 'exclude-scripts', 'upgrade', 'always-copy', 'zip-ok', 'multi-version', 'exclude-scripts', 'upgrade', 'always-copy',
'delete-conflicting', 'ignore-conflicts-at-my-risk', 'editable', 'delete-conflicting', 'ignore-conflicts-at-my-risk', 'editable',
'no-deps', 'no-deps', 'local-snapshots-ok',
] ]
negative_opt = {'always-unzip': 'zip-ok'} negative_opt = {'always-unzip': 'zip-ok'}
create_index = PackageIndex create_index = PackageIndex
def initialize_options(self): def initialize_options(self):
self.zip_ok = None self.zip_ok = self.local_snapshots_ok = None
self.install_dir = self.script_dir = self.exclude_scripts = None self.install_dir = self.script_dir = self.exclude_scripts = None
self.index_url = None self.index_url = None
self.find_links = None self.find_links = None
...@@ -177,7 +177,8 @@ class easy_install(Command): ...@@ -177,7 +177,8 @@ class easy_install(Command):
self.find_links = self.find_links.split() self.find_links = self.find_links.split()
else: else:
self.find_links = [] self.find_links = []
if self.local_snapshots_ok:
self.package_index.scan_egg_links(self.shadow_path+sys.path)
self.package_index.add_find_links(self.find_links) self.package_index.add_find_links(self.find_links)
self.set_undefined_options('install_lib', ('optimize','optimize')) self.set_undefined_options('install_lib', ('optimize','optimize'))
if not isinstance(self.optimize,int): if not isinstance(self.optimize,int):
...@@ -202,7 +203,6 @@ class easy_install(Command): ...@@ -202,7 +203,6 @@ class easy_install(Command):
self.outputs = [] self.outputs = []
def run(self): def run(self):
if self.verbose<>self.distribution.verbose: if self.verbose<>self.distribution.verbose:
log.set_verbosity(self.verbose) log.set_verbosity(self.verbose)
......
...@@ -228,20 +228,20 @@ class PackageIndex(Environment): ...@@ -228,20 +228,20 @@ class PackageIndex(Environment):
else: else:
self.warn(msg, url) self.warn(msg, url)
def scan_egg_links(self, search_path):
for item in search_path:
if os.path.isdir(item):
for entry in os.listdir(item):
if entry.endswith('.egg-link'):
self.scan_egg_link(item, entry)
def scan_egg_link(self, path, entry):
lines = filter(None, map(str.strip, file(os.path.join(path, entry))))
if len(lines)==2:
for dist in find_distributions(os.path.join(path, lines[0])):
dist.location = os.path.join(path, *lines)
dist.precedence = SOURCE_DIST
self.add(dist)
def process_index(self,url,page): def process_index(self,url,page):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment