Repository: royreznik/plz (language: python)

Issue:
Add init command



Discussion / hints:

Fix patch:
diff --git a/.gitignore b/.gitignore
index b6e4761..a0b56cf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -127,3 +127,6 @@ dmypy.json
 
 # Pyre type checker
 .pyre/
+
+# pycharm
+.idea/
diff --git a/plz/__main__.py b/plz/__main__.py
new file mode 100644
index 0000000..9a50c56
--- /dev/null
+++ b/plz/__main__.py
@@ -0,0 +1,16 @@
+import click
+
+from .commands import init
+
+
+@click.group()
+def cli() -> None:
+    pass
+
+
+# noinspection PyTypeChecker
+cli.add_command(init)
+
+
+if __name__ == "__main__":
+    cli()
diff --git a/plz/commands/__init__.py b/plz/commands/__init__.py
new file mode 100644
index 0000000..b43180a
--- /dev/null
+++ b/plz/commands/__init__.py
@@ -0,0 +1,1 @@
+from .init import init
diff --git a/plz/commands/consts.py b/plz/commands/consts.py
new file mode 100644
index 0000000..057c30c
--- /dev/null
+++ b/plz/commands/consts.py
@@ -0,0 +1,1 @@
+REQUIREMENTS_FILE = "requirements.in"
\ No newline at end of file
diff --git a/plz/commands/init.py b/plz/commands/init.py
new file mode 100644
index 0000000..a41b4ee
--- /dev/null
+++ b/plz/commands/init.py
@@ -0,0 +1,22 @@
+from pathlib import Path
+from typing import Optional
+
+import click
+
+from .consts import REQUIREMENTS_FILE
+
+
+# noinspection PyTypeChecker
+@click.command("init")
+@click.option("-p", "--path", type=click.Path(exists=True, path_type=Path))
+def init(path: Optional[Path] = None) -> None:
+    path = path or Path.cwd()
+    requirements_file = path / REQUIREMENTS_FILE
+    if requirements_file.exists():
+        raise click.BadParameter(
+            f"Path {requirements_file} already have {REQUIREMENTS_FILE},"
+            f"did you meant to run `plz install`?"
+        )
+    requirements_file.touch()
+    click.secho('Requirements file created!'
+                'You can add requirements and run `plz install`', fg='green')


Test patch:
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..40228e4
--- /dev/null
+++ b/tests/__init__.py
@@ -0,0 +1,1 @@
+from plz.__main__ import cli
diff --git a/tests/conftest.py b/tests/conftest.py
new file mode 100644
index 0000000..e6a2f74
--- /dev/null
+++ b/tests/conftest.py
@@ -0,0 +1,23 @@
+from pathlib import Path
+from typing import Tuple, Generator
+
+import pytest as pytest
+from click.testing import CliRunner, Result
+
+
+@pytest.fixture
+def runner_and_path() -> Generator[Tuple[CliRunner, Path], None, None]:
+    cli_runner = CliRunner(mix_stderr=False)
+    with cli_runner.isolated_filesystem() as path:
+        yield cli_runner, Path(path)
+
+
+@pytest.fixture
+def runner(runner_and_path: Tuple[CliRunner, Path]) -> Generator[CliRunner, None, None]:
+    yield runner_and_path[0]
+
+
+@pytest.fixture
+def isolated_dir(runner_and_path: Tuple[CliRunner, Path]) -> Generator[Path, None, None]:
+    yield runner_and_path[1]
+
diff --git a/tests/test_init.py b/tests/test_init.py
new file mode 100644
index 0000000..66f3658
--- /dev/null
+++ b/tests/test_init.py
@@ -0,0 +1,39 @@
+import shlex
+from pathlib import Path
+
+from click.testing import CliRunner
+
+from plz.__main__ import cli
+from plz.commands.consts import REQUIREMENTS_FILE
+
+
+def test_init_create_expected_files_in_cwd(
+    runner: CliRunner, isolated_dir: Path
+) -> None:
+    # noinspection PyTypeChecker
+    result = runner.invoke(cli, "init")
+    assert "Requirements file created" in result.stdout
+
+    assert (isolated_dir / REQUIREMENTS_FILE).exists()
+
+
+def test_init_create_expected_files_in_path(
+    runner: CliRunner, isolated_dir: Path
+) -> None:
+    new_dir = isolated_dir / "dir"
+    new_dir.mkdir()
+    # noinspection PyTypeChecker
+    result = runner.invoke(cli, shlex.split("init -p dir"))
+    assert "Requirements file created" in result.stdout
+
+    assert (new_dir / REQUIREMENTS_FILE).exists()
+
+
+def test_init_fails_on_files_already_exists(
+    runner: CliRunner, isolated_dir: Path
+) -> None:
+    (isolated_dir / REQUIREMENTS_FILE).touch()
+    # noinspection PyTypeChecker
+    result = runner.invoke(cli, "init")
+    assert result.exit_code != 0
+    assert "already have requirements.in" in result.stderr