diff --git a/shub/build_egg.py b/shub/build_egg.py index 0efef160..d93037de 100644 --- a/shub/build_egg.py +++ b/shub/build_egg.py @@ -7,6 +7,7 @@ from shub.exceptions import NotFoundException, ShubException, SubcommandException from shub.utils import ( + _project_cwd, create_default_setup_py, inside_project, remember_cwd, @@ -54,7 +55,8 @@ def cli(filename, debug): def build_egg_cmd(filename, debug=False): tmpdir = None try: - egg, tmpdir = build_project_egg() + with _project_cwd(): + egg, tmpdir = build_project_egg() click.echo(f"Writing egg to {filename}") try: shutil.copyfile(egg, filename) diff --git a/shub/deploy.py b/shub/deploy.py index 95ebe0ef..f95becee 100644 --- a/shub/deploy.py +++ b/shub/deploy.py @@ -17,7 +17,12 @@ print_warning, ) from shub.image.upload import upload_cmd -from shub.utils import create_scrapinghub_yml_wizard, make_deploy_request, run_cmd +from shub.utils import ( + _project_cwd, + create_scrapinghub_yml_wizard, + make_deploy_request, + run_cmd, +) # The previous name of build_project_egg(), which deploy wrappers built on top # of shub still import from here. @@ -115,6 +120,12 @@ def cli(target, version, debug, egg, build_egg, verbose, keep_log, ignore_size): def deploy_cmd(target, version, debug, egg, verbose, keep_log, conf=None): + egg = egg and str(Path(egg).absolute()) + with _project_cwd(): + _deploy_cmd(target, version, debug, egg, verbose, keep_log, conf) + + +def _deploy_cmd(target, version, debug, egg, verbose, keep_log, conf): tmpdir = None try: conf = conf or load_shub_config() diff --git a/shub/utils.py b/shub/utils.py index 1a64efbb..3febe0ba 100644 --- a/shub/utils.py +++ b/shub/utils.py @@ -70,6 +70,17 @@ def remember_cwd(): os.chdir(current_dir) +@contextlib.contextmanager +def _project_cwd(): + """Change the current directory to that of the closest scrapy.cfg, if any, + and restore it afterwards.""" + scrapy_cfg = closest_file("scrapy.cfg") + with remember_cwd(): + if scrapy_cfg: + os.chdir(Path(scrapy_cfg).parent) + yield + + def get_scrapinghub_client_from_config(conf): return ScrapinghubClient(conf.apikey, dash_endpoint=conf.endpoint) diff --git a/tests/test_build_egg.py b/tests/test_build_egg.py index ca341cdc..313e7863 100644 --- a/tests/test_build_egg.py +++ b/tests/test_build_egg.py @@ -226,6 +226,27 @@ def test_overwrites_write_only_destination(self): result = self.runner.invoke(build_egg.cli, ["wo.egg"]) assert 0 == result.exit_code, result.output + def _build_egg_from_subdir(self): + os.chdir("project") + result = self.runner.invoke(build_egg.cli, ["built.egg"]) + assert 0 == result.exit_code, result.output + with zipfile.ZipFile("built.egg") as z: + return z.namelist() + + def test_builds_egg_from_subdir(self): + if shutil.which("git") is None: + self.skipTest("git executable not found") + with self.runner.isolated_filesystem(): + make_git_project() + names = self._build_egg_from_subdir() + assert "project/__init__.py" in names + + def test_builds_egg_from_subdir_without_git_repo(self): + with self.runner.isolated_filesystem(): + self._make_project() + names = self._build_egg_from_subdir() + assert "project/__init__.py" in names + def test_requires_a_scrapy_project(self): with self.runner.isolated_filesystem(): self.assertInvokeRaises(NotFoundException, build_egg.cli, ["built.egg"]) diff --git a/tests/test_deploy.py b/tests/test_deploy.py index f5460823..99c0d946 100644 --- a/tests/test_deploy.py +++ b/tests/test_deploy.py @@ -103,12 +103,13 @@ def test_deploys_given_egg(self, mock_deploy_req, mock_build): self._make_project() with Path("given.egg").open("w") as f: f.write("egg content") + given_egg = str(Path("given.egg").absolute()) result = self.runner.invoke(deploy.cli, ("--egg", "given.egg")) assert 0 == result.exit_code, result.output name, egg = mock_deploy_req.call_args[0][2][-1] egg.close() - assert "Using egg: given.egg" in result.output - assert ("egg", "given.egg") == (name, egg.name) + assert f"Using egg: {given_egg}" in result.output + assert ("egg", given_egg) == (name, egg.name) mock_build.assert_not_called() @patch("shub.deploy.make_deploy_request") @@ -337,6 +338,15 @@ def test_deploy_default_from_git_repo(self, mock_deploy_req): result = self.runner.invoke(deploy.cli) assert 0 == result.exit_code, result.output + @patch("shub.deploy.make_deploy_request") + def test_deploy_from_subdir(self, mock_deploy_req): + with self.runner.isolated_filesystem(): + make_git_project() + os.chdir("project") + result = self.runner.invoke(deploy.cli) + assert 0 == result.exit_code, result.output + mock_deploy_req.assert_called_once() + class DeployFilesTest(unittest.TestCase): def setUp(self):