[Python-checkins] python/nondist/sandbox/setuptools/setuptools/command easy_install.py, 1.16, 1.17
pje@users.sourceforge.net
pje at users.sourceforge.net
Sun Jul 24 04:41:46 CEST 2005
Update of /cvsroot/python/python/nondist/sandbox/setuptools/setuptools/command
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7421/setuptools/command
Modified Files:
easy_install.py
Log Message:
Implement --editable option, which allows you to just download and extract
(or check out from Subversion) one or more source distributions, without
actually building or installing them (or their dependencies).
Index: easy_install.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/setuptools/setuptools/command/easy_install.py,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- easy_install.py 21 Jul 2005 00:49:45 -0000 1.16
+++ easy_install.py 24 Jul 2005 02:41:44 -0000 1.17
@@ -69,17 +69,17 @@
"filename in which to record list of installed files"),
('always-unzip', 'Z', "don't install as a zipfile, no matter what"),
('site-dirs=','S',"list of directories where .pth files work"),
+ ('editable', 'e', "Install specified packages in editable form"),
]
boolean_options = [
'zip-ok', 'multi-version', 'exclude-scripts', 'upgrade', 'always-copy',
- 'delete-conflicting', 'ignore-conflicts-at-my-risk',
+ 'delete-conflicting', 'ignore-conflicts-at-my-risk', 'editable',
]
negative_opt = {'always-unzip': 'zip-ok'}
create_index = PackageIndex
-
def initialize_options(self):
self.zip_ok = None
self.install_dir = self.script_dir = self.exclude_scripts = None
@@ -89,6 +89,8 @@
self.args = None
self.optimize = self.record = None
self.upgrade = self.always_copy = self.multi_version = None
+ self.editable = None
+
# Options not specifiable via command line
self.package_index = None
self.pth_file = None
@@ -119,8 +121,6 @@
-
-
def finalize_options(self):
# If a non-default installation directory was specified, default the
# script directory to match it.
@@ -203,27 +203,18 @@
"--ignore-conflicts-at-my-risk at the same time"
)
- if not self.args:
+ if self.editable and not self.build_directory:
raise DistutilsArgError(
- "No urls, filenames, or requirements specified (see --help)")
+ "Must specify a build directory (-b) when using --editable"
+ )
- elif len(self.args)>1 and self.build_directory is not None:
+ if not self.args:
raise DistutilsArgError(
- "Build directory can only be set when using one URL"
- )
+ "No urls, filenames, or requirements specified (see --help)")
self.outputs = []
- def alloc_tmp(self):
- if self.build_directory is None:
- return tempfile.mkdtemp(prefix="easy_install-")
- tmpdir = os.path.realpath(self.build_directory)
- if not os.path.isdir(tmpdir):
- os.makedirs(tmpdir)
- return tmpdir
-
-
def run(self):
if self.verbose<>self.distribution.verbose:
log.set_verbosity(self.verbose)
@@ -244,21 +235,6 @@
- def add_output(self, path):
- if os.path.isdir(path):
- for base, dirs, files in os.walk(path):
- for filename in files:
- self.outputs.append(os.path.join(base,filename))
- else:
- self.outputs.append(path)
-
-
-
-
-
-
-
-
@@ -268,9 +244,32 @@
+ def add_output(self, path):
+ if os.path.isdir(path):
+ for base, dirs, files in os.walk(path):
+ for filename in files:
+ self.outputs.append(os.path.join(base,filename))
+ else:
+ self.outputs.append(path)
+ def not_editable(self, spec):
+ if self.editable:
+ raise DistutilsArgError(
+ "Invalid argument %r: you can't use filenames or URLs "
+ "with --editable (except via the --find-links option)."
+ % (spec,)
+ )
+ def check_editable(self,spec):
+ if not self.editable:
+ return
+ if os.path.exists(os.path.join(self.build_directory, spec.key)):
+ raise DistutilsArgError(
+ "%r already exists in %s; can't do a checkout there" %
+ (spec.key, self.build_directory)
+ )
+
@@ -282,36 +281,33 @@
+
def easy_install(self, spec):
- tmpdir = self.alloc_tmp()
+ tmpdir = tempfile.mkdtemp(prefix="easy_install-")
download = None
try:
if not isinstance(spec,Requirement):
if URL_SCHEME(spec):
# It's a url, download it to tmpdir and process
+ self.not_editable(spec)
download = self.package_index.download(spec, tmpdir)
return self.install_item(None, download, tmpdir, True)
elif os.path.exists(spec):
# Existing file or directory, just process it directly
+ self.not_editable(spec)
return self.install_item(None, spec, tmpdir, True)
else:
- try:
- spec = Requirement.parse(spec)
- except ValueError:
- raise DistutilsError(
- "Not a URL, existing file, or requirement spec: %r"
- % (spec,)
- )
+ spec = parse_requirement_arg(spec)
- if isinstance(spec, Requirement):
- download = self.package_index.fetch(spec, tmpdir, self.upgrade)
- else:
- spec = None
+ self.check_editable(spec)
+ download = self.package_index.fetch(
+ spec, tmpdir, self.upgrade, self.editable
+ )
if download is None:
raise DistutilsError(
@@ -321,18 +317,22 @@
return self.install_item(spec, download, tmpdir)
finally:
- if self.build_directory is None:
+ if os.path.exists(tmpdir):
shutil.rmtree(tmpdir)
+
+
+
+
def install_item(self, spec, download, tmpdir, install_needed=False):
# Installation is also needed if file in tmpdir or is not an egg
install_needed = install_needed or os.path.dirname(download) == tmpdir
install_needed = install_needed or not download.endswith('.egg')
log.info("Processing %s", os.path.basename(download))
if install_needed or self.always_copy:
- dists = self.install_eggs(download, tmpdir)
+ dists = self.install_eggs(spec, download, tmpdir)
for dist in dists:
self.process_distribution(spec, dist)
else:
@@ -386,28 +386,28 @@
return True
return False
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ def maybe_move(self, spec, dist_filename, setup_base):
+ dst = os.path.join(self.build_directory, spec.key)
+ if os.path.exists(dst):
+ log.warn(
+ "%r already exists in %s; build directory %s will not be kept",
+ spec.key, self.build_directory, setup_base
+ )
+ return setup_base
+ if os.path.isdir(dist_filename):
+ setup_base = dist_filename
+ else:
+ if os.path.dirname(dist_filename)==setup_base:
+ os.unlink(dist_filename) # get it out of the tmp dir
+ contents = os.listdir(setup_base)
+ if len(contents)==1:
+ dist_filename = os.path.join(setup_base,contents[0])
+ if os.path.isdir(dist_filename):
+ # if the only thing there is a directory, move it instead
+ setup_base = dist_filename
+ ensure_directory(dst); shutil.move(setup_base, dst)
+ return dst
+
def install_script(self, dist, script_name, script_text, dev_path=None):
log.info("Installing %s script to %s", script_name,self.script_dir)
target = os.path.join(self.script_dir, script_name)
@@ -449,7 +449,7 @@
pass
- def install_eggs(self, dist_filename, tmpdir):
+ def install_eggs(self, spec, dist_filename, tmpdir):
# .egg dirs or files are already built, so just return them
if dist_filename.lower().endswith('.egg'):
return [self.install_egg(dist_filename, tmpdir)]
@@ -461,8 +461,12 @@
if os.path.isfile(dist_filename):
unpack_archive(dist_filename, tmpdir, self.unpack_progress)
elif os.path.isdir(dist_filename):
+ # note that setup_base==tmpdir here if this is a svn checkout
setup_base = os.path.abspath(dist_filename)
+ if setup_base==tmpdir and self.build_directory and spec is not None:
+ setup_base = self.maybe_move(spec, dist_filename, setup_base)
+
# Find the setup.py file
setup_script = os.path.join(setup_base, 'setup.py')
@@ -479,15 +483,11 @@
setup_script = setups[0]
# Now run it, and return the result
- return self.build_and_install(setup_script, setup_base)
-
-
-
-
-
-
-
-
+ if self.editable:
+ log.warn(self.report_editable(spec, setup_script))
+ return []
+ else:
+ return self.build_and_install(setup_script, setup_base)
def egg_distribution(self, egg_path):
@@ -723,24 +723,24 @@
version = dist.version
return msg % locals()
+ def report_editable(self, spec, setup_script):
+ dirname = os.path.dirname(setup_script)
+ python = sys.executable
+ return """\nExtracted editable version of %(spec)s to %(dirname)s
+If it uses setuptools in its setup script, you can activate it in
+"development" mode by going to that directory and running::
+ %(python)s setup.py --develop
+See the setuptools documentation for the "develop" command for more info.
+""" % locals()
-
-
-
-
-
-
-
-
-
- def build_and_install(self, setup_script, setup_base):
+ def run_setup(self, setup_script, setup_base, args):
sys.modules.setdefault('distutils.command.bdist_egg', bdist_egg)
- sys.modules.setdefault('distutils.command.bdist_egg', egg_info)
+ sys.modules.setdefault('distutils.command.egg_info', egg_info)
- args = ['bdist_egg', '--dist-dir']
+ args = list(args)
if self.verbose>2:
v = 'v' * self.verbose - 1
args.insert(0,'-'+v)
@@ -748,31 +748,31 @@
args.insert(0,'-q')
if self.dry_run:
args.insert(0,'-n')
+ log.info(
+ "Running %s %s", setup_script[len(setup_base)+1:], ' '.join(args)
+ )
+ try:
+ run_setup(setup_script, args)
+ except SystemExit, v:
+ raise DistutilsError("Setup script exited with %s" % (v.args[0],))
- dist_dir = tempfile.mkdtemp(prefix='egg-dist-tmp-', dir=os.path.dirname(setup_script))
+ def build_and_install(self, setup_script, setup_base):
+ args = ['bdist_egg', '--dist-dir']
+ dist_dir = tempfile.mkdtemp(
+ prefix='egg-dist-tmp-', dir=os.path.dirname(setup_script)
+ )
try:
args.append(dist_dir)
- log.info(
- "Running %s %s", setup_script[len(setup_base)+1:],
- ' '.join(args)
- )
- try:
- run_setup(setup_script, args)
- except SystemExit, v:
- raise DistutilsError(
- "Setup script exited with %s" % (v.args[0],)
- )
-
+ self.run_setup(setup_script, setup_base, args)
+ all_eggs = AvailableDistributions([dist_dir])
eggs = []
- for egg in glob(os.path.join(dist_dir,'*.egg')):
- eggs.append(self.install_egg(egg, setup_base))
-
+ for key in eggs:
+ for dist in eggs[key]:
+ eggs.append(self.install_egg(egg, setup_base))
if not eggs and not self.dry_run:
log.warn("No eggs found in %s (setup script problem?)",
dist_dir)
-
return eggs
-
finally:
shutil.rmtree(dist_dir)
log.set_verbosity(self.verbose) # restore our log verbosity
@@ -1010,13 +1010,13 @@
return prefixes
-
-
-
-
-
-
-
+def parse_requirement_arg(spec):
+ try:
+ return Requirement.parse(spec)
+ except ValueError:
+ raise DistutilsError(
+ "Not a URL, existing file, or requirement spec: %r" % (spec,)
+ )
More information about the Python-checkins
mailing list