Skip to content

Commit d8a96a1

Browse files
committed
Merge branch 'feat-gitignore' into feat-local-gitignore
2 parents 697eedc + d4fdd71 commit d8a96a1

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

sphinx_polyversion/driver.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from inspect import isawaitable
1212
from logging import getLogger
1313
from pathlib import Path
14+
from subprocess import CalledProcessError
1415
from types import TracebackType
1516
from typing import (
1617
TYPE_CHECKING,
@@ -33,6 +34,7 @@
3334

3435
from sphinx_polyversion.builder import Builder, BuildError
3536
from sphinx_polyversion.environment import Environment
37+
from sphinx_polyversion.git import get_unignored_files
3638
from sphinx_polyversion.json import GLOBAL_ENCODER, Encoder, JSONable
3739
from sphinx_polyversion.utils import shift_path
3840

@@ -333,8 +335,20 @@ async def build_local(self) -> None:
333335
with tempfile.TemporaryDirectory() as tmp:
334336
path = Path(tmp)
335337
# copy source files
336-
logger.info("Copying source files...")
337-
shutil.copytree(self.root, path, symlinks=True, dirs_exist_ok=True)
338+
logger.info("Copying source files (except for files ignored by git)...")
339+
try:
340+
files = await get_unignored_files(self.root)
341+
for filename in files:
342+
source = self.root / filename
343+
target = path / filename
344+
target.parent.mkdir(parents=True, exist_ok=True)
345+
if not target.exists():
346+
shutil.copy2(source, target, follow_symlinks=False)
347+
except CalledProcessError:
348+
logger.warning(
349+
"Could not list un-ignored files using git. Copying full working directory..."
350+
)
351+
shutil.copytree(self.root, path, symlinks=True, dirs_exist_ok=True)
338352
# setup build environment (e.g. poetry/pip venv)
339353
async with await self.init_environment(path, rev) as env:
340354
# construct metadata to pass to the build process

sphinx_polyversion/git.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ async def _copy_tree(
202202
"""
203203
# retrieve commit contents as tar archive
204204
cmd = ("git", "archive", "--format", "tar", ref)
205+
git_init_cmd = ("git", "init", "--initial-branch=dummy")
205206
with tempfile.SpooledTemporaryFile(max_size=buffer_size) as f:
206207
process = await asyncio.create_subprocess_exec(
207208
*cmd, cwd=repo, stdout=f, stderr=PIPE
@@ -213,6 +214,13 @@ async def _copy_tree(
213214
f.seek(0)
214215
with tarfile.open(fileobj=f) as tf:
215216
tf.extractall(str(dest))
217+
# initialize dummy git repository in copied directory (required for setuptools-scm)
218+
process = await asyncio.create_subprocess_exec(
219+
*git_init_cmd, cwd=str(dest), stdout=f, stderr=PIPE
220+
)
221+
out, err = await process.communicate()
222+
if process.returncode:
223+
raise CalledProcessError(process.returncode, " ".join(cmd), stderr=err)
216224

217225

218226
async def file_exists(repo: Path, ref: GitRef, file: PurePath) -> bool:
@@ -250,6 +258,34 @@ async def file_exists(repo: Path, ref: GitRef, file: PurePath) -> bool:
250258
return rc == 0
251259

252260

261+
async def get_unignored_files(directory: Path) -> list[Path]:
262+
"""
263+
List all unignored files in the directory.
264+
265+
Parameters
266+
----------
267+
directory : Path
268+
Any directory in the repo.
269+
270+
Returns
271+
-------
272+
Path
273+
The paths to all un-ignored files in the directory (recursive)
274+
275+
"""
276+
cmd = (
277+
"git",
278+
"ls-files",
279+
"--cached",
280+
"--others",
281+
"--exclude-standard",
282+
)
283+
process = await asyncio.create_subprocess_exec(*cmd, cwd=directory, stdout=PIPE)
284+
out, err = await process.communicate()
285+
files = out.decode().split("\n")
286+
return [Path(path.strip()) for path in files]
287+
288+
253289
# -- VersionProvider API -----------------------------------------------------
254290

255291

0 commit comments

Comments
 (0)