Skip to content

Commit 1fc91f1

Browse files
committed
👌 IMPROVE: Use gitpython (#2)
1 parent fc87c0e commit 1fc91f1

File tree

5 files changed

+60
-37
lines changed

5 files changed

+60
-37
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ Options:
7070
-q, --quiet Remove stdout logging.
7171
-v, --verbose Increase stdout logging.
7272
--exit-code INTEGER Exit code when files changed. [default: 2]
73+
--no-git Do not add new files to a git index.
7374
--test-run Do not delete/create any files.
7475
--config FILE Read default configuration from a file
7576
(allowed extensions: .json, .toml, .yml,
@@ -199,13 +200,13 @@ To run the tests:
199200

200201
```console
201202
pip install tox
202-
tox
203+
tox -e py37
203204
```
204205

205206
To test out the CLI:
206207

207208
```console
208-
tox -e py37-cli -- --help
209+
tox -e py37-cli
209210
```
210211

211212
For code style:

scss_compile/__init__.py

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@
44
import hashlib
55
import os
66
from pathlib import Path
7-
from subprocess import check_call
87
import sys
9-
from typing import Set
8+
from typing import Optional, Set
109

1110
import click
1211
import click_config_file
12+
from git import Repo, InvalidGitRepositoryError
1313
import sass
1414
import toml
1515
import yaml
1616

1717

18-
def config_provider(file_path, cmd_name):
18+
def config_provider(file_path: str, cmd_name: str):
1919
"""Read configuration file."""
2020
_, ext = os.path.splitext(file_path)
2121
text = Path(file_path).read_text()
@@ -101,11 +101,9 @@ def config_provider(file_path, cmd_name):
101101
help="Exit code when files changed.",
102102
)
103103
@click.option(
104-
"--git-add/--no-git-add",
105-
default=True,
104+
"--no-git",
106105
is_flag=True,
107-
show_default=True,
108-
help="Attempt to add new files to the git index (required by pre-commit).",
106+
help="Do not add new files to a git index.",
109107
)
110108
@click.option("--test-run", is_flag=True, help="Do not delete/create any files.")
111109
@click_config_file.configuration_option(
@@ -130,14 +128,26 @@ def run_compile(
130128
quiet,
131129
verbose,
132130
exit_code,
133-
git_add,
131+
no_git,
134132
test_run,
135133
):
136134
"""Compile all SCSS files in the paths provided.
137135
138136
For directories; include all non-partial SCSS files, and
139137
for files; if partial, include all adjacent, non-partial, SCSS files.
140138
"""
139+
140+
if no_git:
141+
git_repo = None
142+
else:
143+
try:
144+
# TODO allow for the cwd to be in a child directory of the repo
145+
git_repo = Repo(os.getcwd(), search_parent_directories=False)
146+
except InvalidGitRepositoryError:
147+
raise click.ClickException(
148+
f"CWD is not the root of a git repository (use --no-git): {os.getcwd()}"
149+
)
150+
141151
try:
142152
translate = (
143153
{}
@@ -157,6 +167,8 @@ def run_compile(
157167
"translate": translate,
158168
"sourcemap": sourcemap,
159169
"precision": precision,
170+
"git": git_repo.git_dir if git_repo else None,
171+
"exit_code": exit_code,
160172
}
161173
}
162174
)
@@ -251,13 +263,14 @@ def run_compile(
251263
css_out_path = out_dir / (out_name + ".css")
252264
if not test_run:
253265

254-
if update_file(css_out_path, css_str, encoding, git_add):
266+
if update_file(css_out_path, css_str, encoding, git_repo, verbose):
255267
changed_files = True
256268
if sourcemap and update_file(
257269
out_dir / (scss_path.name + ".map.json"),
258270
sourcemap_str,
259271
encoding,
260-
git_add,
272+
git_repo,
273+
verbose,
261274
):
262275
changed_files = True
263276

@@ -283,13 +296,17 @@ def run_compile(
283296
sys.exit(exit_code)
284297

285298

286-
def update_file(path, text, encoding, git_add) -> bool:
299+
def update_file(
300+
path: Path, text: str, encoding: str, git_repo: Optional[Repo], verbose: bool
301+
) -> bool:
287302

288303
if not path.exists():
289304
path.write_text(text, encoding=encoding)
290-
if git_add:
291-
# this is required, to ensure creations are picked up by pre-commit
292-
check_call(["git", "add", str(path)])
305+
if git_repo is not None:
306+
# this is required, to ensure file creations are picked up by pre-commit
307+
git_repo.index.add([str(path)], write=True)
308+
if verbose:
309+
click.echo(f"Added to git index: {str(path)}")
293310
return True
294311

295312
if text != path.read_text(encoding=encoding):

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"click~=7.1.2",
2929
"click-config-file~=0.6.0",
3030
"libsass~=0.20.1",
31+
"gitpython~=3.1.8",
3132
"pyyaml",
3233
"toml",
3334
],

tests/test_run_compile.py

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
1+
import os
12
from pathlib import Path
23
import shutil
34

45
from click.testing import CliRunner
6+
from git import Repo
57
import pytest
68

79
from scss_compile import run_compile
810

911

1012
@pytest.fixture()
11-
def scss_folder(tmp_path):
13+
def scss_folder(tmp_path: Path) -> Path:
14+
"""Copy the scss folder to a temporary folder, and initialise it as git repo."""
1215
src = tmp_path / "scss"
1316
shutil.copytree(Path(__file__).parent / "example_scss", src)
17+
repo = Repo.init(str(tmp_path))
18+
repo.index.commit("initial commit")
19+
original_cwd = os.getcwd()
20+
os.chdir(tmp_path)
1421
yield src
22+
os.chdir(original_cwd)
1523
shutil.rmtree(tmp_path)
1624

1725

@@ -20,25 +28,22 @@ def test_help():
2028
assert result.exit_code == 0, result.output
2129

2230

23-
def test_file(scss_folder):
24-
result = CliRunner().invoke(
25-
run_compile, ["--no-git-add", str(scss_folder / "example1.scss")]
26-
)
31+
def test_file(scss_folder: Path):
32+
result = CliRunner().invoke(run_compile, [str(scss_folder / "example1.scss"), "-v"])
2733
assert result.exit_code == 2, result.output
2834
assert (scss_folder / "example1.css").exists(), result.output
35+
assert len(Repo(scss_folder.parent).index.diff("HEAD")) == 1
2936

3037
# should not change any files
31-
result = CliRunner().invoke(
32-
run_compile, ["--no-git-add", str(scss_folder / "example1.scss")]
33-
)
38+
result = CliRunner().invoke(run_compile, [str(scss_folder / "example1.scss")])
3439
assert result.exit_code == 0, result.output
3540
assert (scss_folder / "example1.css").exists(), result.output
3641

3742

38-
def test_file_hash(scss_folder):
43+
def test_file_hash(scss_folder: Path):
3944
result = CliRunner().invoke(
4045
run_compile,
41-
["--no-git-add", str(scss_folder / "example1.scss"), "--hash-filenames"],
46+
[str(scss_folder / "example1.scss"), "--hash-filenames"],
4247
)
4348
assert result.exit_code == 2, result.output
4449
assert len(list(scss_folder.glob("example1#*.css"))) == 1, result.output
@@ -47,33 +52,32 @@ def test_file_hash(scss_folder):
4752
# should create same hash
4853
result = CliRunner().invoke(
4954
run_compile,
50-
["--no-git-add", str(scss_folder / "example1.scss"), "--hash-filenames"],
55+
[str(scss_folder / "example1.scss"), "--hash-filenames"],
5156
)
5257
assert result.exit_code == 0, result.output
5358
assert len(list(scss_folder.glob("example1#*.css"))) == 1, result.output
5459
assert path.exists(), result.output
5560

5661

57-
def test_file_sourcemap(scss_folder):
62+
def test_file_sourcemap(scss_folder: Path):
5863
result = CliRunner().invoke(
59-
run_compile, ["--no-git-add", str(scss_folder / "example1.scss"), "--sourcemap"]
64+
run_compile, [str(scss_folder / "example1.scss"), "--sourcemap"]
6065
)
6166
assert result.exit_code == 2, result.output
6267
assert (scss_folder / "example1.css").exists(), result.output
6368
assert (scss_folder / "example1.scss.map.json").exists(), result.output
6469

6570

66-
def test_partials(scss_folder):
71+
def test_partials(scss_folder: Path):
6772
result = CliRunner().invoke(
68-
run_compile, ["--no-git-add", str(scss_folder / "partials" / "_example1.scss")]
73+
run_compile, [str(scss_folder / "partials" / "_example1.scss")]
6974
)
7075
assert result.exit_code == 0, result.output
7176
assert not (scss_folder / "example1.css").exists(), result.output
7277

7378
result = CliRunner().invoke(
7479
run_compile,
7580
[
76-
"--no-git-add",
7781
str(scss_folder / "partials" / "_example1.scss"),
7882
"--partial-depth=1",
7983
],
@@ -82,18 +86,18 @@ def test_partials(scss_folder):
8286
assert (scss_folder / "example1.css").exists(), result.output
8387

8488

85-
def test_folder(scss_folder):
86-
result = CliRunner().invoke(run_compile, ["--no-git-add", str(scss_folder)])
89+
def test_folder(scss_folder: Path):
90+
result = CliRunner().invoke(run_compile, [str(scss_folder)])
8791
assert result.exit_code == 2, result.output
8892
assert (scss_folder / "example1.css").exists(), result.output
8993
assert (scss_folder / "example2.css").exists(), result.output
94+
assert len(Repo(scss_folder.parent).index.diff("HEAD")) == 2
9095

9196

92-
def test_translate(scss_folder):
97+
def test_translate(scss_folder: Path):
9398
result = CliRunner().invoke(
9499
run_compile,
95100
[
96-
"--no-git-add",
97101
str(scss_folder / "example1.scss"),
98102
"--translate",
99103
str(scss_folder) + ":" + str(scss_folder.parent / "css"),

tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ extras = testing
1818
commands = pytest {posargs}
1919

2020
[testenv:py{36,37,38}-cli]
21-
commands = scss-compile {posargs}
21+
commands = scss-compile {posargs:tests/ -v --config=scss-compile-config.yml}
2222

2323
[testenv:try-repo]
2424
deps = pre-commit

0 commit comments

Comments
 (0)