Skip to content

Commit

Permalink
Merge pull request #237 from Erich-McMillan/feature/236-default-group
Browse files Browse the repository at this point in the history
Feature/236 default group
  • Loading branch information
jacebrowning committed Dec 8, 2020
2 parents 6538d49 + 4f0f193 commit 2c04233
Show file tree
Hide file tree
Showing 10 changed files with 246 additions and 6 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ groups:
members:
- fontawesome
- material-design-icons

default_group: 'code'
```

Ignore the dependency storage location:
Expand Down
49 changes: 49 additions & 0 deletions docs/use-cases/default-groups.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Specifying a Default Group

Using the `default_group` attribute in gitman.yml specifies which group of
dependencies to install if no inputs are provided to `gitman install`. If
if is set to a blank string, `default_group: ''`, then all sources are
installed.

When nested gitman projects are used default groups are installed if they
exist. In the case of the following project layout:

Project A gitman.yml

```yaml
location: dependencies
sources:
- name: b
type: git
repo: https://project_b
rev: master
```

Project B gitman.yml

```yaml
location: dependencies
sources:
- name: c
type: git
repo: https://project_c
rev: master
- name: d
type: git
repo: https://project_d
rev: master
groups:
- name: group_c_d
members:
- c
- d
- name: group_d
members:
- d
- default_group: 'group_d'
```

When `gitman install` is invoked from project A then project B is installed.
As project B is installed the default group `group_d` will be installed, unless
`gitman install -n` or `gitman install --no-defaults` is specified which will result in all of project B's
dependencies (both c and d) being installed.
11 changes: 10 additions & 1 deletion gitman/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ def main(args=None, function=None): # pylint: disable=too-many-statements
sub.add_argument(
'-e', '--fetch', action='store_true', help="always fetch the latest branches"
)
sub.add_argument(
'-n',
'--no-defaults',
help='override default groups and install all dependencies if none specified',
action='store_true',
dest='no_defaults',
)

# Update parser
info = "update dependencies to the latest versions"
Expand Down Expand Up @@ -248,7 +255,9 @@ def _get_command(function, namespace): # pylint: disable=too-many-statements
skip_changes=namespace.skip_changes,
)
if namespace.command == 'install':
kwargs.update(fetch=namespace.fetch)
kwargs.update(
fetch=namespace.fetch, skip_default_group=namespace.no_defaults
)
if namespace.command == 'update':
kwargs.update(recurse=namespace.recurse, lock=namespace.lock)

Expand Down
8 changes: 8 additions & 0 deletions gitman/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def install(
force_interactive=False,
clean=True,
skip_changes=False,
skip_default_group=False,
):
"""Install dependencies for a project.
Expand All @@ -79,6 +80,8 @@ def install(
- `clean`: indicates untracked files should be deleted from dependencies
- `skip_changes`: indicates dependencies with uncommitted changes
should be skipped
- `skip_default_group`: indicates default_group should be skipped if
`*names` is empty
"""
log.info(
"%sInstalling dependencies: %s",
Expand All @@ -102,6 +105,7 @@ def install(
fetch=fetch,
clean=clean,
skip_changes=skip_changes,
skip_default_group=skip_default_group,
)

if count:
Expand All @@ -123,6 +127,7 @@ def update(
clean=True,
lock=None, # pylint: disable=redefined-outer-name
skip_changes=False,
skip_default_group=False,
):
"""Update dependencies for a project.
Expand All @@ -140,6 +145,8 @@ def update(
- `lock`: indicates updated dependency versions should be recorded
- `skip_changes`: indicates dependencies with uncommitted changes
should be skipped
- `skip_default_group`: indicates default_group should be skipped if
`*names` is empty
"""
log.info(
"%s dependencies%s: %s",
Expand All @@ -165,6 +172,7 @@ def update(
fetch=True,
clean=clean,
skip_changes=skip_changes,
skip_default_group=skip_default_group,
)

if count and lock is not False:
Expand Down
30 changes: 26 additions & 4 deletions gitman/models/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class Config:
location: str = "gitman_sources"
sources: List[Source] = field(default_factory=list)
sources_locked: List[Source] = field(default_factory=list)
default_group: str = field(default_factory=str)
groups: List[Group] = field(default_factory=list)

def __post_init__(self):
Expand Down Expand Up @@ -77,14 +78,17 @@ def install_dependencies(
fetch=False,
clean=True,
skip_changes=False,
skip_default_group=False,
): # pylint: disable=too-many-locals
"""Download or update the specified dependencies."""
if depth == 0:
log.info("Skipped directory: %s", self.location_path)
return 0

sources = self._get_sources(use_locked=False if update else None)
sources_filter = self._get_sources_filter(*names, sources=sources)
sources_filter = self._get_sources_filter(
*names, sources=sources, skip_default_group=skip_default_group
)

if not os.path.isdir(self.location_path):
shell.mkdir(self.location_path)
Expand Down Expand Up @@ -122,6 +126,7 @@ def install_dependencies(
fetch=fetch,
clean=clean,
skip_changes=skip_changes,
skip_default_group=skip_default_group,
)
common.dedent()

Expand All @@ -141,7 +146,9 @@ def run_scripts(self, *names, depth=None, force=False, show_shell_stdout=False):
return 0

sources = self._get_sources()
sources_filter = self._get_sources_filter(*names, sources=sources)
sources_filter = self._get_sources_filter(
*names, sources=sources, skip_default_group=False
)

shell.cd(self.location_path)
common.newline()
Expand Down Expand Up @@ -170,7 +177,9 @@ def run_scripts(self, *names, depth=None, force=False, show_shell_stdout=False):
def lock_dependencies(self, *names, obey_existing=True, skip_changes=False):
"""Lock down the immediate dependency versions."""
sources = self._get_sources(use_locked=obey_existing).copy()
sources_filter = self._get_sources_filter(*names, sources=sources)
sources_filter = self._get_sources_filter(
*names, sources=sources, skip_default_group=False
)

shell.cd(self.location_path)
common.newline()
Expand Down Expand Up @@ -302,11 +311,24 @@ def _get_sources(self, *, use_locked=None):

return sources + extras

def _get_sources_filter(self, *names, sources):
def _get_default_group(self, names):
"""Get default group if names is empty."""
use_default = not names
default_groups = [
group
for group in self.groups
if group.name == self.default_group and use_default
]

return default_groups

def _get_sources_filter(self, *names, sources, skip_default_group):
"""Get filtered sublist of sources."""
sources_filter = None

groups_filter = [group for group in self.groups if group.name in list(names)]
if not skip_default_group:
groups_filter += self._get_default_group(list(names))

if groups_filter:
sources_filter = [
Expand Down
18 changes: 18 additions & 0 deletions gitman/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,23 @@ def main(args=None):
# Options group
group = parser.add_mutually_exclusive_group()

# Install option
group.add_argument(
'-i',
'--install',
const='install',
help='get the specified versions of all dependencies',
action='store_const',
dest='command',
)
parser.add_argument(
'-n',
'--no-defaults',
help='override default groups and install all dependencies if none specified',
action='store_true',
dest='no_defaults',
)

# Update option
group.add_argument(
'-u',
Expand Down Expand Up @@ -105,6 +122,7 @@ def main(args=None):

# Modify arguments to match CLI interface
if not namespace.command:
# Default to install to remain compatable with older interface
namespace.command = 'install'
namespace.name = []
namespace.root = None
Expand Down
7 changes: 7 additions & 0 deletions gitman/tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def test_install(self, mock_install):
fetch=False,
clean=False,
skip_changes=False,
skip_default_group=False,
)

@patch('gitman.commands.install')
Expand All @@ -92,6 +93,7 @@ def test_install_root(self, mock_install):
fetch=False,
clean=False,
skip_changes=False,
skip_default_group=False,
)

@patch('gitman.commands.install')
Expand All @@ -107,6 +109,7 @@ def test_install_force(self, mock_install):
fetch=False,
clean=False,
skip_changes=False,
skip_default_group=False,
)

@patch('gitman.commands.install')
Expand All @@ -122,6 +125,7 @@ def test_install_fetch(self, mock_install):
fetch=True,
clean=False,
skip_changes=False,
skip_default_group=False,
)

@patch('gitman.commands.install')
Expand All @@ -137,6 +141,7 @@ def test_install_clean(self, mock_install):
fetch=False,
clean=True,
skip_changes=False,
skip_default_group=False,
)

@patch('gitman.commands.install')
Expand All @@ -154,6 +159,7 @@ def test_install_specific_sources(self, mock_install):
fetch=False,
clean=False,
skip_changes=False,
skip_default_group=False,
)

@patch('gitman.commands.install')
Expand All @@ -169,6 +175,7 @@ def test_install_with_depth(self, mock_update):
fetch=False,
clean=False,
skip_changes=False,
skip_default_group=False,
)

@patch('gitman.commands.install', Mock())
Expand Down
1 change: 1 addition & 0 deletions gitman/tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def test_install(self, mock_commands):
force=False,
force_interactive=False,
skip_changes=False,
skip_default_group=False,
),
call.install().__bool__(), # command status check
] == mock_commands.mock_calls
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ nav:
- Linking Feature Branches: use-cases/linked-features.md
- Build System Integration: use-cases/build-integration.md
- Sparse Checkouts: use-cases/sparse-checkouts.md
- Default Groups: use-cases/default-groups.md
- Extras:
- Git SVN Bridge: extras/git-svn.md
- Self-Contained GitMan: extras/self-contained-gitman.md
Expand Down

0 comments on commit 2c04233

Please sign in to comment.