Commits

Anonymous committed 5681db4 Merge

merge from Simon Cross

  • Participants
  • Parent commits f931e41, 7606f4c

Comments (0)

Files changed (4)

File docs/news.txt

 * Support Debian/Ubuntu "dist-packages" in zip command. Thanks duckx.
 * Fix relative --src folder. Thanks Simon Cross.
 * Handle missing VCS with an error message. Thanks Alexandre Conrad.
+* Added --no-download option to install; pairs with --no-install to separate
+  download and installation into two steps. Thanks Simon Cross.
 
 0.6.3
 -----

File pip/commands/install.py

             dest='no_install',
             action='store_true',
             help="Download and unpack all packages, but don't actually install them")
+        self.parser.add_option(
+            '--no-download',
+            dest='no_download',
+            action="store_true",
+            help="Don't download any packages, just install the ones already downloaded "
+            "(completes an install run with --no-install)")
 
         self.parser.add_option(
             '--install-option',
         for filename in options.requirements:
             for req in parse_requirements(filename, finder=finder, options=options):
                 requirement_set.add_requirement(req)
-        requirement_set.install_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
+        if not options.no_download:
+            requirement_set.install_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
+        else:
+            requirement_set.locate_files()
         if not options.no_install and not self.bundle:
             requirement_set.install(install_options)
             installed = ' '.join([req.name for req in
             req.uninstall(auto_confirm=auto_confirm)
             req.commit_uninstall()
 
+    def locate_files(self):
+        ## FIXME: duplicates code from install_files; relevant code should
+        ##        probably be factored out into a separate method
+        unnamed = list(self.unnamed_requirements)
+        reqs = self.requirements.values()
+        while reqs or unnamed:
+            if unnamed:
+                req_to_install = unnamed.pop(0)
+            else:
+                req_to_install = reqs.pop(0)
+            install_needed = True
+            if not self.ignore_installed and not req_to_install.editable:
+                req_to_install.check_if_exists()
+                if req_to_install.satisfied_by:
+                    if self.upgrade:
+                        req_to_install.conflicts_with = req_to_install.satisfied_by
+                        req_to_install.satisfied_by = None
+                    else:
+                        install_needed = False
+                if req_to_install.satisfied_by:
+                    logger.notify('Requirement already satisfied '
+                                  '(use --upgrade to upgrade): %s'
+                                  % req_to_install)
+
+            if req_to_install.editable:
+                if req_to_install.source_dir is None:
+                    req_to_install.source_dir = req_to_install.build_location(self.src_dir)
+            elif install_needed:
+                req_to_install.source_dir = req_to_install.build_location(self.build_dir, not self.is_download)
+
+            if req_to_install.source_dir is not None and not os.path.isdir(req_to_install.source_dir):
+                raise InstallationError('Could not install requirement %s '
+                                       'because source folder %s does not exist '
+                                       '(perhaps --no-download was used without first running '
+                                       'an equivalent install with --no-install?)'
+                                       % (req_to_install, req_to_install.source_dir))
+
     def install_files(self, finder, force_root_egg_info=False, bundle=False):
         unnamed = list(self.unnamed_requirements)
         reqs = self.requirements.values()

File tests/test_basic.py

     assert 'customsrc/initools/setup.py' in result.files_created
     assert [filename for filename in result.files_created.keys() if filename.startswith('customdl/initools')]
 
+def test_editable_no_install_followed_by_no_download():
+    """
+    Test installing an editable in two steps (first with --no-install, then with --no-download).
+    
+    """
+    reset_env()
+
+    result = run_pip('install', '-e', 'svn+http://svn.colorstudy.com/INITools/trunk#egg=initools-dev',
+        '--no-install', expect_error=True)
+    assert lib_py + 'site-packages/INITools.egg-link' not in result.files_created
+    assert 'src/initools' in result.files_created
+    assert 'src/initools/.svn' in result.files_created
+
+    result = run_pip('install', '-e', 'svn+http://svn.colorstudy.com/INITools/trunk#egg=initools-dev',
+        '--no-download',  expect_error=True)
+    egg_link = result.files_created[lib_py + 'site-packages/INITools.egg-link']
+    # FIXME: I don't understand why there's a trailing . here:
+    assert egg_link.bytes.endswith('/test-scratch/src/initools\n.'), egg_link.bytes
+    assert (lib_py + 'site-packages/easy-install.pth') in result.files_updated
+    assert 'src/initools' not in result.files_created
+    assert 'src/initools/.svn' not in result.files_created
+
+def test_no_install_followed_by_no_download():
+    """
+    Test installing in two steps (first with --no-install, then with --no-download).
+    
+    """
+    reset_env()
+
+    result = run_pip('install', 'INITools==0.2', '--no-install', expect_error=True)
+    assert (lib_py + 'site-packages/INITools-0.2-py%s.egg-info' % pyversion) not in result.files_created, str(result)
+    assert (lib_py + 'site-packages/initools') not in result.files_created, sorted(result.files_created.keys())
+    assert 'build/INITools' in result.files_created
+    assert 'build/INITools/INITools.egg-info' in result.files_created
+
+    result = run_pip('install', 'INITools==0.2', '--no-download',  expect_error=True)
+    assert (lib_py + 'site-packages/INITools-0.2-py%s.egg-info' % pyversion) in result.files_created, str(result)
+    assert (lib_py + 'site-packages/initools') in result.files_created, sorted(result.files_created.keys())
+    assert 'build/INITools' not in result.files_created
+    assert 'build/INITools/INITools.egg-info' not in result.files_created
+
+def test_bad_install_with_no_download():
+    """
+    Test that --no-download behaves sensibly if the package source can't be found.
+    
+    """
+    reset_env()
+
+    result = run_pip('install', 'INITools==0.2', '--no-download',  expect_error=True)
+    assert result.stdout.find("perhaps --no-download was used without first running an equivalent install with --no-install?") > 0
 
 def test_install_dev_version_from_pypi():
     """