Skip to content

Commit

Permalink
Merge pull request #73 from lbonn/spec-git-dir
Browse files Browse the repository at this point in the history
Optionally specify the main git repository
  • Loading branch information
Kentzo authored Oct 31, 2019
2 parents 0d1806d + 53042d3 commit 1f7938c
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 30 deletions.
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Archive repository with all its submodules.

--prefix=PREFIX Prepend PREFIX to each filename in the archive. OUTPUT_FILE name is used by default to avoid tarbomb. You can set it to '' in order to explicitly request tarbomb.

-C BASE_REPO Use BASE_REPO as the main repository git working directory to archive. Defaults to current directory when empty
--no-exclude Don't read .gitattributes files for patterns containing export-ignore attributes.

--force-submodules Force a `git submodule init && git submodule update` at each level before iterating submodules
Expand Down
26 changes: 19 additions & 7 deletions git_archive_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,12 +480,15 @@ def get_git_version(cls):
return None


def main():
def main(argv=None):
if argv is None:
argv = sys.argv

from optparse import OptionParser, SUPPRESS_HELP

parser = OptionParser(
usage="usage: %prog [-v] [--prefix PREFIX] [--no-exclude] [--force-submodules]"
" [--extra EXTRA1 ...] [--dry-run] [-0 | ... | -9] OUTPUT_FILE",
usage="usage: %prog [-v] [-C BASE_REPO] [--prefix PREFIX] [--no-exclude]"
" [--force-submodules] [--extra EXTRA1 ...] [--dry-run] [-0 | ... | -9] OUTPUT_FILE",
version="%prog {0}".format(__version__)
)

Expand All @@ -497,6 +500,13 @@ def main():
OUTPUT_FILE name is used by default to avoid tarbomb.
You can set it to '' in order to explicitly request tarbomb""")

parser.add_option('-C',
type='string',
dest='base_repo',
default=None,
help="""use BASE_REPO as the main repository git working directory to archive.
Defaults to current directory when empty""")

parser.add_option('-v', '--verbose',
action='store_true',
dest='verbose',
Expand Down Expand Up @@ -531,7 +541,7 @@ def main():
dest='compresslevel',
help=SUPPRESS_HELP)

options, args = parser.parse_args()
options, args = parser.parse_args(argv[1:])

if len(args) != 1:
parser.error("You must specify exactly one output file")
Expand Down Expand Up @@ -561,13 +571,15 @@ def main():
archiver = GitArchiver(options.prefix,
options.exclude,
options.force_sub,
options.extra)
options.extra,
path.abspath(options.base_repo) if options.base_repo is not None else None
)
archiver.create(output_file_path, options.dry_run, compresslevel=options.compresslevel)
except Exception as e:
parser.exit(2, "{0}\n".format(e))

sys.exit(0)
return 0


if __name__ == '__main__':
main()
sys.exit(main())
71 changes: 48 additions & 23 deletions test_git_archive_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import pycodestyle
import pytest

import git_archive_all
from git_archive_all import GitArchiver


Expand Down Expand Up @@ -140,6 +141,36 @@ def archive(self, path):
a.create(path)


def make_expected_tree(contents):
e = {}

for k, v in contents.items():
if v.kind == 'file' and not v.excluded:
e[k] = v.contents
elif v.kind in ('dir', 'submodule') and not v.excluded:
for nested_k, nested_v in make_expected_tree(v.contents).items():
e[as_posix(os.path.join(k, nested_k))] = nested_v

return e


def make_actual_tree(tar_file):
a = {}

for m in tar_file.getmembers():
if m.isfile():
name = m.name

if sys.version_info < (3,):
name = m.name.decode('utf-8')

a[name] = tar_file.extractfile(m).read().decode()
else:
raise NotImplementedError

return a


base = {
'app': DirRecord({
'__init__.py': FileRecord('#Beautiful is better than ugly.'),
Expand Down Expand Up @@ -294,36 +325,30 @@ def test_ignore(contents, tmpdir, git_env, monkeypatch):
repo.archive(repo_tar_path)
repo_tar = TarFile(repo_tar_path, format=PAX_FORMAT, encoding='utf-8')

def make_expected(contents):
e = {}
expected = make_expected_tree(contents)
actual = make_actual_tree(repo_tar)

for k, v in contents.items():
if v.kind == 'file' and not v.excluded:
e[k] = v.contents
elif v.kind in ('dir', 'submodule') and not v.excluded:
for nested_k, nested_v in make_expected(v.contents).items():
e[as_posix(os.path.join(k, nested_k))] = nested_v

return e
assert actual == expected

def make_actual(tar_file):
a = {}

for m in tar_file.getmembers():
if m.isfile():
name = m.name
def test_cli(tmpdir, git_env, monkeypatch):
contents = base

if sys.version_info < (3,):
name = m.name.decode('utf-8')
for name, value in git_env.items():
monkeypatch.setenv(name, value)

a[name] = tar_file.extractfile(m).read().decode()
else:
raise NotImplementedError
repo_path = os.path.join(str(tmpdir), 'repo')
repo = Repo(repo_path)
repo.init()
repo.add_dir('.', contents)
repo.commit('init')

return a
repo_tar_path = os.path.join(str(tmpdir), 'repo.tar')
git_archive_all.main(['git_archive_all.py', '--prefix', '', '-C', repo_path, repo_tar_path])
repo_tar = TarFile(repo_tar_path, format=PAX_FORMAT, encoding='utf-8')

expected = make_expected(contents)
actual = make_actual(repo_tar)
expected = make_expected_tree(contents)
actual = make_actual_tree(repo_tar)

assert actual == expected

Expand Down

0 comments on commit 1f7938c

Please sign in to comment.