Skip to content

Commit 75f8f02

Browse files
authored
Merge pull request #152 from jedwards4b/sort_by_local_path
Sort by local path
2 parents 5b5e1c2 + 42687bd commit 75f8f02

File tree

4 files changed

+105
-16
lines changed

4 files changed

+105
-16
lines changed

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
language: python
22
os: linux
3-
python:
4-
- "2.7"
3+
python:
54
- "3.4"
65
- "3.5"
76
- "3.6"

manic/checkout.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,14 +380,14 @@ def main(args):
380380

381381
if args.status:
382382
# user requested status-only
383-
for comp in sorted(tree_status.keys()):
383+
for comp in sorted(tree_status):
384384
tree_status[comp].log_status_message(args.verbose)
385385
else:
386386
# checkout / update the external repositories.
387387
safe_to_update = check_safe_to_update_repos(tree_status)
388388
if not safe_to_update:
389389
# print status
390-
for comp in sorted(tree_status.keys()):
390+
for comp in sorted(tree_status):
391391
tree_status[comp].log_status_message(args.verbose)
392392
# exit gracefully
393393
msg = """The external repositories labeled with 'M' above are not in a clean state.

manic/sourcetree.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -331,12 +331,14 @@ def checkout(self, verbosity, load_all, load_comp=None):
331331
printlog('Checking out externals: ', end='')
332332

333333
if load_all:
334-
load_comps = self._all_components.keys()
334+
tmp_comps = self._all_components.keys()
335335
elif load_comp is not None:
336-
load_comps = [load_comp]
336+
tmp_comps = [load_comp]
337337
else:
338-
load_comps = self._required_compnames
339-
338+
tmp_comps = self._required_compnames
339+
# Sort by path so that if paths are nested the
340+
# parent repo is checked out first.
341+
load_comps = sorted(tmp_comps, key=lambda comp: self._all_components[comp].get_local_path())
340342
# checkout the primary externals
341343
for comp in load_comps:
342344
if verbosity < VERBOSITY_VERBOSE:
@@ -346,8 +348,6 @@ def checkout(self, verbosity, load_all, load_comp=None):
346348
# output a newline
347349
printlog(EMPTY_STR)
348350
self._all_components[comp].checkout(verbosity, load_all)
349-
printlog('')
350-
351-
# now give each external an opportunitity to checkout it's externals.
352-
for comp in load_comps:
351+
# now give each external an opportunitity to checkout it's externals.
353352
self._all_components[comp].checkout_externals(verbosity, load_all)
353+
printlog('')

test/test_sys_checkout.py

Lines changed: 94 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@
8585
CFG_SUB_NAME = 'sub-externals.cfg'
8686
README_NAME = 'readme.txt'
8787
REMOTE_BRANCH_FEATURE2 = 'feature2'
88+
NESTED_NAME = ['./fred', './fred/wilma', './fred/wilma/barney']
89+
8890

8991
SVN_TEST_REPO = 'https://github.com/escomp/cesm'
9092

@@ -160,6 +162,23 @@ def container_simple_required(self, dest_dir):
160162

161163
self.write_config(dest_dir)
162164

165+
def container_nested_required(self, dest_dir, order):
166+
"""Create a container externals file with only simple externals.
167+
168+
"""
169+
self.create_config()
170+
self.create_section(SIMPLE_REPO_NAME, 'simp_tag', nested=True,
171+
tag='tag1', path=NESTED_NAME[order[0]])
172+
173+
self.create_section(SIMPLE_REPO_NAME, 'simp_branch', nested=True,
174+
branch=REMOTE_BRANCH_FEATURE2, path=NESTED_NAME[order[1]])
175+
176+
self.create_section(SIMPLE_REPO_NAME, 'simp_hash', nested=True,
177+
ref_hash='60b1cc1a38d63', path=NESTED_NAME[order[2]])
178+
179+
self.write_config(dest_dir)
180+
181+
163182
def container_simple_optional(self, dest_dir):
164183
"""Create a container externals file with optional simple externals
165184
@@ -261,7 +280,7 @@ def create_metadata(self):
261280
def create_section(self, repo_type, name, tag='', branch='',
262281
ref_hash='', required=True, path=EXTERNALS_NAME,
263282
externals='', repo_path=None, from_submodule=False,
264-
sparse=''):
283+
sparse='', nested=False):
265284
# pylint: disable=too-many-branches
266285
"""Create a config section with autofilling some items and handling
267286
optional items.
@@ -270,8 +289,11 @@ def create_section(self, repo_type, name, tag='', branch='',
270289
# pylint: disable=R0913
271290
self._config.add_section(name)
272291
if not from_submodule:
273-
self._config.set(name, ExternalsDescription.PATH,
274-
os.path.join(path, name))
292+
if nested:
293+
self._config.set(name, ExternalsDescription.PATH, path)
294+
else:
295+
self._config.set(name, ExternalsDescription.PATH,
296+
os.path.join(path, name))
275297

276298
self._config.set(name, ExternalsDescription.PROTOCOL,
277299
ExternalsDescription.PROTOCOL_GIT)
@@ -671,10 +693,16 @@ def _check_simple_tag_empty(self, tree, directory=EXTERNALS_NAME):
671693
name = './{0}/simp_tag'.format(directory)
672694
self._check_generic_empty_default_required(tree, name)
673695

696+
def _check_nested_tag_empty(self, tree, name=EXTERNALS_NAME):
697+
self._check_generic_empty_default_required(tree, name)
698+
674699
def _check_simple_tag_ok(self, tree, directory=EXTERNALS_NAME):
675700
name = './{0}/simp_tag'.format(directory)
676701
self._check_generic_ok_clean_required(tree, name)
677702

703+
def _check_nested_tag_ok(self, tree, name=EXTERNALS_NAME):
704+
self._check_generic_ok_clean_required(tree, name)
705+
678706
def _check_simple_tag_dirty(self, tree, directory=EXTERNALS_NAME):
679707
name = './{0}/simp_tag'.format(directory)
680708
self._check_generic_ok_dirty_required(tree, name)
@@ -687,10 +715,16 @@ def _check_simple_branch_empty(self, tree, directory=EXTERNALS_NAME):
687715
name = './{0}/simp_branch'.format(directory)
688716
self._check_generic_empty_default_required(tree, name)
689717

718+
def _check_nested_branch_empty(self, tree, name=EXTERNALS_NAME):
719+
self._check_generic_empty_default_required(tree, name)
720+
690721
def _check_simple_branch_ok(self, tree, directory=EXTERNALS_NAME):
691722
name = './{0}/simp_branch'.format(directory)
692723
self._check_generic_ok_clean_required(tree, name)
693724

725+
def _check_nested_branch_ok(self, tree, name=EXTERNALS_NAME):
726+
self._check_generic_ok_clean_required(tree, name)
727+
694728
def _check_simple_branch_modified(self, tree, directory=EXTERNALS_NAME):
695729
name = './{0}/simp_branch'.format(directory)
696730
self._check_generic_modified_ok_required(tree, name)
@@ -699,10 +733,16 @@ def _check_simple_hash_empty(self, tree, directory=EXTERNALS_NAME):
699733
name = './{0}/simp_hash'.format(directory)
700734
self._check_generic_empty_default_required(tree, name)
701735

736+
def _check_nested_hash_empty(self, tree, name=EXTERNALS_NAME):
737+
self._check_generic_empty_default_required(tree, name)
738+
702739
def _check_simple_hash_ok(self, tree, directory=EXTERNALS_NAME):
703740
name = './{0}/simp_hash'.format(directory)
704741
self._check_generic_ok_clean_required(tree, name)
705742

743+
def _check_nested_hash_ok(self, tree, name=EXTERNALS_NAME):
744+
self._check_generic_ok_clean_required(tree, name)
745+
706746
def _check_simple_hash_modified(self, tree, directory=EXTERNALS_NAME):
707747
name = './{0}/simp_hash'.format(directory)
708748
self._check_generic_modified_ok_required(tree, name)
@@ -754,19 +794,38 @@ def _check_container_simple_required_pre_checkout(self, overall, tree):
754794
self._check_simple_branch_empty(tree)
755795
self._check_simple_hash_empty(tree)
756796

797+
def _check_container_nested_required_pre_checkout(self, overall, tree, order):
798+
self.assertEqual(overall, 0)
799+
self._check_nested_tag_empty(tree, name=NESTED_NAME[order[0]])
800+
self._check_nested_branch_empty(tree, name=NESTED_NAME[order[1]])
801+
self._check_nested_hash_empty(tree, name=NESTED_NAME[order[2]])
802+
757803
def _check_container_simple_required_checkout(self, overall, tree):
758804
# Note, this is the internal tree status just before checkout
759805
self.assertEqual(overall, 0)
760806
self._check_simple_tag_empty(tree)
761807
self._check_simple_branch_empty(tree)
762808
self._check_simple_hash_empty(tree)
763809

810+
def _check_container_nested_required_checkout(self, overall, tree, order):
811+
# Note, this is the internal tree status just before checkout
812+
self.assertEqual(overall, 0)
813+
self._check_nested_tag_empty(tree, name=NESTED_NAME[order[0]])
814+
self._check_nested_branch_empty(tree, name=NESTED_NAME[order[1]])
815+
self._check_nested_hash_empty(tree, name=NESTED_NAME[order[2]])
816+
764817
def _check_container_simple_required_post_checkout(self, overall, tree):
765818
self.assertEqual(overall, 0)
766819
self._check_simple_tag_ok(tree)
767820
self._check_simple_branch_ok(tree)
768821
self._check_simple_hash_ok(tree)
769822

823+
def _check_container_nested_required_post_checkout(self, overall, tree, order):
824+
self.assertEqual(overall, 0)
825+
self._check_nested_tag_ok(tree, name=NESTED_NAME[order[0]])
826+
self._check_nested_branch_ok(tree, name=NESTED_NAME[order[1]])
827+
self._check_nested_hash_ok(tree, name=NESTED_NAME[order[2]])
828+
770829
def _check_container_simple_required_out_of_sync(self, overall, tree):
771830
self.assertEqual(overall, 0)
772831
self._check_simple_tag_modified(tree)
@@ -964,6 +1023,37 @@ def test_container_simple_required(self):
9641023
self.status_args)
9651024
self._check_container_simple_required_post_checkout(overall, tree)
9661025

1026+
def test_container_nested_required(self):
1027+
"""Verify that a container with nested subrepos
1028+
generates the correct initial status.
1029+
Tests over all possible permutations
1030+
"""
1031+
1032+
orders = [[0, 1, 2], [1, 2, 0], [2, 0, 1],
1033+
[0, 2, 1], [2, 1, 0], [1, 0, 2]]
1034+
for n, order in enumerate(orders):
1035+
# create repo
1036+
dest_dir = os.path.join(os.environ[MANIC_TEST_TMP_REPO_ROOT],
1037+
self._test_id, "test"+str(n))
1038+
under_test_dir = self.setup_test_repo(CONTAINER_REPO_NAME,
1039+
dest_dir_in=dest_dir)
1040+
self._generator.container_nested_required(under_test_dir, order)
1041+
1042+
# status of empty repo
1043+
overall, tree = self.execute_cmd_in_dir(under_test_dir,
1044+
self.status_args)
1045+
self._check_container_nested_required_pre_checkout(overall, tree, order)
1046+
1047+
# checkout
1048+
overall, tree = self.execute_cmd_in_dir(under_test_dir,
1049+
self.checkout_args)
1050+
self._check_container_nested_required_checkout(overall, tree, order)
1051+
1052+
# status clean checked out
1053+
overall, tree = self.execute_cmd_in_dir(under_test_dir,
1054+
self.status_args)
1055+
self._check_container_nested_required_post_checkout(overall, tree, order)
1056+
9671057
def test_container_simple_optional(self):
9681058
"""Verify that container with an optional simple subrepos
9691059
generates the correct initial status.
@@ -1591,7 +1681,7 @@ def setUp(self):
15911681
"""
15921682

15931683
# Run the basic setup
1594-
super(TestSubrepoCheckout, self).setUp()
1684+
super().setUp()
15951685
# create test repo
15961686
# We need to do this here (rather than have a static repo) because
15971687
# git submodules do not allow for variables in .gitmodules files

0 commit comments

Comments
 (0)