diff --git a/README.md b/README.md
index 2744ef7..0b4188e 100644
--- a/README.md
+++ b/README.md
@@ -13,8 +13,9 @@ A lightweight Python utility to quickly clone, configure, and build CMake projec
- [Configuration](#configuration)
- [Usage](#usage)
- [Single Repository Mode](#single-repository-mode)
- - [Mono-Repo Mode](#mono-repo-mode)
- - [Profile Mode](#profile-mode-saved-configurations)
+ - [Mono-Repo Mode](#mono-repository-mode)
+ - [Profile Mode](#profile-mode)
+ - [Config Mode](#config-mode)
- [Development](#development)
- [License](#license)
@@ -75,9 +76,9 @@ pip install git+https://github.com/masonlet/starlet-setup.git
Once installed, you can use the `starlet-setup` command from anywhere.
+### ⚠️ Command not found? ⚠️
-⚠️ Command not found? ⚠️
-If you get an error saying the command is not found, you may need to add Python's user scripts directory to your PATH:
+If you get an error saying the command is not found, you may need to add Python's user scripts directory to your PATH.
**Find your scripts directory**:
```bash
@@ -136,9 +137,10 @@ Starlet Setup checks for configuration files in this order:
## Usage
+###
-Single Repository Mode
-
+Single Repository Mode
+
#### Basic Usage
```bash
@@ -171,11 +173,14 @@ starlet-setup username/repo --verbose
# Custom CMake args
starlet-setup username/repo --cmake-arg=-DCMAKE_CXX_COMPILER=clang++
```
-
+
+
+
+###
-Mono-Repo Mode
+Mono-Repo Mode
#### BUILD_LOCAL Usage
Mono-repo mode sets `BUILD_LOCAL=ON` in the root project's CMakeLists.txt.
@@ -264,10 +269,14 @@ This structure allows you to:
- Build everything together
- Debug across module boundaries
- Commit changes without digging into build directories
+
+
+
+###
-Profile Mode (Saved Configurations)
+Profile Mode (Saved Configurations)
#### Managing Profiles
```bash
@@ -292,13 +301,51 @@ starlet-setup username/repo --profile myprofile
# Use a profile with SSH
starlet-setup username/repo --profile myprofile --ssh
```
+
+
+
+
+
+###
+
+Config Mode (Saved Build Settings)
+
+#### Managing Configs
+```bash
+# List all saved configurations
+starlet-setup --list-configs
+
+# Add a new configuration with flags
+starlet-setup --config-add myconfig --ssh --build-type Release --no-build
+
+# Remove a configuration
+starlet-setup --config-remove myconfig
+```
+
+#### Using Configs
+```bash
+# Use a saved config
+starlet-setup username/repo --config myconfig
+
+# Override specific settings
+starlet-setup username/repo --config myconfig --verbose
+
+# Config with mono-repo mode
+starlet-setup username/repo --mono-repo --config myconfig --ssh
+```
+
+
+
+
## Development
+
+###
-Developing starlet-setup
+Development
### Running Tests
diff --git a/pyproject.toml b/pyproject.toml
index ed0dddc..5624288 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "starlet-setup"
-version = "1.0.2"
+version = "1.1.0"
description = "Quick setup for CMake projects"
readme = "README.md"
requires-python = ">=3.6"
diff --git a/src/starlet_setup/__main__.py b/src/starlet_setup/__main__.py
index 1b97f24..4c0b7a3 100644
--- a/src/starlet_setup/__main__.py
+++ b/src/starlet_setup/__main__.py
@@ -6,7 +6,7 @@
"""
from .cli import parse_args
-from .config import create_default_config
+from .config import create_default_config, list_configs, add_config, remove_config
from .profiles import list_profiles, add_profile, remove_profile
from .utils import check_prerequisites
from .commands import mono_repo_mode, single_repo_mode
@@ -19,21 +19,35 @@ def main() -> None:
if args.init_config:
create_default_config()
return
-
+ if args.list_configs:
+ list_configs(args.config)
+ return
+ if args.config_add:
+ new_config = {
+ 'ssh': args.ssh,
+ 'build_type': args.build_type,
+ 'build_dir': args.build_dir,
+ 'mono_dir': args.mono_dir,
+ 'no_build': args.no_build,
+ 'verbose': args.verbose,
+ 'cmake_arg': args.cmake_arg or []
+ }
+ add_config(args.config, args.config_add, new_config)
+ return
+ if args.config_remove:
+ remove_config(args.config, args.config_remove)
+ return
if args.list_profiles:
list_profiles(args.config)
return
-
if args.profile_add:
add_profile(args.config, args.profile_add)
return
-
if args.profile_remove:
remove_profile(args.config, args.profile_remove)
return
-
+
check_prerequisites(args.verbose)
-
if args.mono_repo or args.profile:
mono_repo_mode(args)
else:
diff --git a/src/starlet_setup/cli.py b/src/starlet_setup/cli.py
index 88e2067..a6eb72a 100644
--- a/src/starlet_setup/cli.py
+++ b/src/starlet_setup/cli.py
@@ -2,51 +2,14 @@
import argparse
from argparse import Namespace
+from typing import Any
from .config import get_config_value, load_config
-def parse_args() -> Namespace:
- """
- Parse command-line arguments for Starlet Setup.
-
- Returns:
- Parsed arguments namespace
- """
- config, config_path = load_config()
-
- parser = argparse.ArgumentParser(
- description="Starlet Setup - Quick setup script for CMake projects",
- formatter_class=argparse.RawDescriptionHelpFormatter,
- epilog="""
-Examples:
- Single Repository Mode:
- %(prog)s https://github.com/username/repo.git
- %(prog)s git@github.com:username/repo.git
- %(prog)s username/repo
- %(prog)s username/repo --ssh
- %(prog)s username/repo --no-build
- %(prog)s username/repo --build-dir build_name --build-type Release
-
- Mono-repo Repository Mode:
- %(prog)s username/repo --mono-repo
- %(prog)s username/repo --mono-repo --ssh --mono-dir my_workspace
- %(prog)s username/repo --repos user/lib1 user/lib2 user/lib3
-
- Profile Repository Mode:
- %(prog)s username/repo --profile
- %(prog)s username/repo --profile myprofile
-
- Profile Management:
- %(prog)s --list-profiles
- %(prog)s --profile-add myprofile user/lib1 user/lib2 user/lib3
- %(prog)s --profile-remove myprofile
-
- Config:
- %(prog)s --init-config
- """
- )
-
- # Common arguments
+def _add_common_args(
+ parser,
+ config: dict[str, Any]
+) -> None:
parser.add_argument(
'--ssh',
action='store_true',
@@ -66,14 +29,31 @@ def parse_args() -> Namespace:
help='Additional CMake arguments (e.g., --cmake-arg=-D_BUILD_TESTS=ON). Can be used multiple times.'
)
- # Configuration arguments
+
+def _add_config_management_args(parser) -> None:
parser.add_argument(
'--init-config',
action='store_true',
help='Create a default config file in the current directory'
)
+ parser.add_argument(
+ '--config-add',
+ metavar=('NAME'),
+ help="Add a new config"
+ )
+ parser.add_argument(
+ '--config-remove',
+ metavar='NAME',
+ help='Remove a saved configuration'
+ )
+ parser.add_argument(
+ '--list-configs',
+ action='store_true',
+ help='List all saved configs'
+ )
- # Profile management arguments
+
+def _add_profile_management_args(parser) -> None:
parser.add_argument(
'--profile-add',
nargs='+',
@@ -91,7 +71,8 @@ def parse_args() -> Namespace:
help='List all saved profiles'
)
- # Build arguments
+
+def _add_build_args(parser, config: dict[str, Any]) -> None:
parser.add_argument(
'-b', '--build-type',
choices=['Debug', 'Release', 'RelWithDebInfo', 'MinSizeRel'],
@@ -115,14 +96,8 @@ def parse_args() -> Namespace:
help='Clean build directory before building'
)
- # Repository argument
- parser.add_argument(
- 'repo',
- nargs='?',
- help='Repository name (username/repo) or full GitHub URL'
- )
-
- # Mono-repo repo mode arguments
+
+def _add_mono_repo_args(parser, config: dict[str, Any]) -> None:
parser.add_argument(
'--mono-repo',
action='store_true',
@@ -147,20 +122,79 @@ def parse_args() -> Namespace:
help='Use saved profile for library repositories (uses "default" if no name given)'
)
+
+def parse_args() -> Namespace:
+ """
+ Parse command-line arguments for Starlet Setup.
+
+ Returns:
+ Parsed arguments namespace
+ """
+ config, config_path = load_config()
+
+ parser = argparse.ArgumentParser(
+ description="Starlet Setup - Quick setup script for CMake projects",
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ epilog="""
+Examples:
+ Single Repository Mode:
+ %(prog)s https://github.com/username/repo.git
+ %(prog)s git@github.com:username/repo.git
+ %(prog)s username/repo
+ %(prog)s username/repo --ssh
+ %(prog)s username/repo --no-build
+ %(prog)s username/repo --build-dir build_name --build-type Release
+
+ Mono-repo Repository Mode:
+ %(prog)s username/repo --mono-repo
+ %(prog)s username/repo --mono-repo --ssh --mono-dir my_workspace
+ %(prog)s username/repo --repos user/lib1 user/lib2 user/lib3
+
+ Profile Repository Mode:
+ %(prog)s username/repo --profile
+ %(prog)s username/repo --profile myprofile
+
+ Profile Management:
+ %(prog)s --list-profiles
+ %(prog)s --profile-add myprofile user/lib1 user/lib2 user/lib3
+ %(prog)s --profile-remove myprofile
+
+ Config Mangement:
+ %(prog)s --init-config
+ %(prog)s --list-configs
+ %(prog)s --config-add myconfig
+ %(prog)s --config-add myconfig --ssh --no-build --build-type Release
+ %(prog)s --config-remove myconfig
+ """
+ )
+
+ # Repository argument
+ parser.add_argument(
+ 'repo',
+ nargs='?',
+ help='Repository name (username/repo) or full GitHub URL'
+ )
+ _add_common_args(parser, config)
+ _add_config_management_args(parser)
+ _add_profile_management_args(parser)
+ _add_build_args(parser, config)
+ _add_mono_repo_args(parser, config)
+
args = parser.parse_args()
args.config = config
args.config_path = config_path
- if args.init_config or args.list_profiles or args.profile_add or args.profile_remove:
+ if args.init_config \
+ or args.list_configs or args.config_add or args.config_remove \
+ or args.list_profiles or args.profile_add or args.profile_remove:
return args
if not args.repo:
parser.error("Repository argument is required")
- if args.profile or args.repos:
- args.mono_repo = True
-
if args.repos and args.profile:
parser.error("Cannot use both --repos and --profile")
+ if args.repos or args.profile:
+ args.mono_repo = True
return args
\ No newline at end of file
diff --git a/src/starlet_setup/config.py b/src/starlet_setup/config.py
index 36c6685..69a1589 100644
--- a/src/starlet_setup/config.py
+++ b/src/starlet_setup/config.py
@@ -1,5 +1,6 @@
"""Configuration file management"""
+import sys
import json
from pathlib import Path
from typing import Any
@@ -45,7 +46,7 @@ def load_config() -> tuple[dict, Path | None]:
def save_config(
- config: dict,
+ config: dict[str, Any],
config_path: Path | None = None
) -> Path:
"""
@@ -72,7 +73,11 @@ def save_config(
return config_path
-def get_config_value(config: dict, key: str, default: Any) -> Any:
+def get_config_value(
+ config: dict[str, Any],
+ key: str,
+ default: Any
+) -> Any:
"""
Get a config value with fallback to default.
@@ -93,14 +98,16 @@ def get_config_value(config: dict, key: str, default: Any) -> Any:
def create_default_config() -> None:
"""Create a default configuration file."""
default_config = {
- "defaults": {
- "ssh": False,
- "build_type": "Debug",
- "build_dir": "build",
- "mono_dir": "build_starlet",
- "no_build": False,
- "verbose": False,
- "cmake_arg": []
+ "configs": {
+ "default": {
+ "ssh": False,
+ "build_type": "Debug",
+ "build_dir": "build",
+ "mono_dir": "build_starlet",
+ "no_build": False,
+ "verbose": False,
+ "cmake_arg": []
+ }
},
"profiles": {
"default": [
@@ -136,4 +143,113 @@ def create_default_config() -> None:
print("Edit this file to customize your defaults.")
print("\nConfig files are checked in this order:")
print(" 1. ./.starlet-setup.json (current directory)")
- print(" 2. ~/.starlet-setup.json (home directory)")
\ No newline at end of file
+ print(" 2. ~/.starlet-setup.json (home directory)")
+
+
+def add_config(
+ config: dict[str, Any],
+ name: str,
+ new_config: dict[str, Any]
+) -> None:
+ """
+ Add a new config to the configuration.
+
+ Args:
+ config: Configuration dictionary
+ config_name: Configuration name
+ """
+ if 'configs' not in config:
+ config['configs'] = {}
+
+ if name in config['configs']:
+ print(f"Warning: Configuration '{name}' already exists.")
+ if input("Overwrite? (y/n): ").lower() != 'y':
+ print("Aborted.")
+ return
+
+ config['configs'][name] = new_config
+
+ config_path = save_config(config)
+
+ config_new = config['configs'][name]
+ print(f"Configuration '{name} added successfully to {config_path}")
+ print(f"Configuration details:")
+ print(f" SSH: {config_new.get('ssh')}")
+ print(f" Build Type: {config_new.get('build_type')}")
+ print(f" Build Directory: {config_new.get('build_dir')}")
+ print(f" Mono-build Directory: {config_new.get('mono_dir')}")
+ print(f" No-build flag: {config_new.get('no_build')}")
+ print(f" Verbose flag: {config_new.get('verbose')}")
+ cmake_args = config_new.get("cmake_args", [])
+ if cmake_args:
+ if len(cmake_args) == 1:
+ print(f" CMake argument: {cmake_args[0]}")
+ else:
+ print(" Cmake arguments: ")
+ for arg in cmake_args:
+ print(f" {arg}")
+ print(f"\nUsage: {Path(sys.argv[0]).name} username/repo --config {name}\n")
+
+
+def remove_config(
+ config: dict[str, Any],
+ name: str
+) -> None:
+ """
+ Remove a config from the configuration.
+
+ Args:
+ config: Configuration dictionary
+ name: Config name to remove
+ """
+ if 'configs' not in config or name not in config['configs']:
+ print(f"\nWarning: Config '{name}' not found.\n")
+ return
+
+ config_new = config['configs'][name]
+ print(f"Config {name}")
+ print(f"Configuration details:")
+ print(f" SSH: {config_new.get('ssh')}")
+ print(f" Build Type: {config_new.get('build_type')}")
+ print(f" Build Directory: {config_new.get('build_dir')}")
+ print(f" Mono-build Directory: {config_new.get('mono_dir')}")
+ print(f" No-build flag: {config_new.get('no_build')}")
+ print(f" Verbose flag: {config_new.get('verbose')}")
+
+ if input("\nAre you sure you want to remove this config? (y/n): ").lower() != 'y':
+ print("Aborted.")
+ return
+
+ del config['configs'][name]
+ config_path = save_config(config)
+ print(f"\nConfig '{name}' was successfully removed")
+ print(f"Configuration saved to: {config_path}\n")
+
+
+def list_configs(config: dict[str, Any]) -> None:
+ print("Available configs:")
+ configs = get_config_value(config, 'configs', {})
+
+ if not configs:
+ print(" No configurations created.")
+ print(" Run with --init-config to create a default configuration.")
+ return
+
+ print("Configurations:")
+ for name, cfg in configs.items():
+ print(f"\n{name}:")
+ print(f" SSH: {cfg.get('ssh')}")
+ print(f" Build Type: {cfg.get('build_type')}")
+ print(f" Build Directory: {cfg.get('build_dir')}")
+ print(f" Mono-build Directory: {cfg.get('mono_dir')}")
+ print(f" No-build flag: {cfg.get('no_build')}")
+ print(f" Verbose flag: {cfg.get('verbose')}")
+ cmake_args = cfg.get("cmake_args", [])
+ if not cmake_args:
+ print()
+ elif len(cmake_args) == 1:
+ print(f" CMake argument: {cmake_args[0]}")
+ else:
+ print(" CMake arguments:")
+ for arg in cmake_args:
+ print(f" {arg}")
\ No newline at end of file
diff --git a/src/starlet_setup/profiles.py b/src/starlet_setup/profiles.py
index 3140043..fc86897 100644
--- a/src/starlet_setup/profiles.py
+++ b/src/starlet_setup/profiles.py
@@ -2,10 +2,14 @@
import sys
from pathlib import Path
+from typing import Any
from .config import get_config_value, save_config
-def add_profile(config: dict, args_list: list[str]) -> None:
+def add_profile(
+ config: dict[str, Any],
+ args_list: list[str]
+) -> None:
"""
Add a new profile to the configuration.
@@ -44,7 +48,10 @@ def add_profile(config: dict, args_list: list[str]) -> None:
print(f"\nUsage: {Path(sys.argv[0]).name} username/test-repo --profile {name}")
-def remove_profile(config: dict, name: str) -> None:
+def remove_profile(
+ config: dict[str, Any],
+ name: str
+) -> None:
"""
Remove a profile from the configuration.
@@ -68,11 +75,11 @@ def remove_profile(config: dict, name: str) -> None:
del config['profiles'][name]
config_path = save_config(config)
- print(f"Profile '{name}' removed successfully")
- print(f"Configuration saved to: {config_path}")
+ print(f"\nProfile '{name}' removed successfully")
+ print(f"Configuration saved to: {config_path}\n")
-def list_profiles(config: dict) -> None:
+def list_profiles(config: dict[str, Any]) -> None:
"""
List all configured profiles.
diff --git a/tests/test_config.py b/tests/test_config.py
index a3b100f..7b6af34 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -8,7 +8,10 @@
load_config,
save_config,
get_config_value,
- create_default_config
+ create_default_config,
+ add_config,
+ remove_config,
+ list_configs
)
@@ -16,7 +19,9 @@
def valid_config():
"""Sample valid config."""
return {
- "defaults": {"ssh": True, "verbose": False},
+ "configs": {
+ "default": {"ssh": True, "verbose": False}
+ },
"profiles": {"default": ["repo1", "repo2"]}
}
@@ -50,7 +55,7 @@ def test_handles_invalid_json(self, tmp_path, monkeypatch, capsys):
with open(config_path, 'w') as f:
f.write("{invalid json")
- config, path = load_config()
+ config, _ = load_config()
assert config == {}
captured = capsys.readouterr()
assert "Invalid JSON" in captured.out
@@ -80,14 +85,14 @@ def test_uses_default_path_when_none_provided(self, tmp_path, valid_config, monk
class TestGetConfigValue:
def test_retrieves_nested_value(self, valid_config):
"""Should navigate dot-separated keys."""
- assert get_config_value(valid_config, "defaults.ssh", False) is True
- assert get_config_value(valid_config, "defaults.verbose", True) is False
+ assert get_config_value(valid_config, "configs.default.ssh", False) is True
+ assert get_config_value(valid_config, "configs.default.verbose", True) is False
def test_returns_default_when_key_missing(self, valid_config):
"""Should return default for non-existent keys."""
assert get_config_value(valid_config, "fake.key", "default") == "default"
- assert get_config_value(valid_config, "defaults.numbermissing", 42) == 42
+ assert get_config_value(valid_config, "configs.default.numbermissing", 42) == 42
def test_handles_non_dict_intermediate_values(self):
@@ -107,8 +112,8 @@ def test_creates_config_file(self, tmp_path, monkeypatch):
assert config_path.exists()
with open(config_path) as f:
config = json.load(f)
- assert "defaults" in config
- assert "profiles" in config
+ assert 'configs' in config
+ assert 'profiles' in config
def test_prompts_before_overwriting(self, tmp_path, monkeypatch, capsys):
@@ -121,4 +126,102 @@ def test_prompts_before_overwriting(self, tmp_path, monkeypatch, capsys):
create_default_config()
assert "Aborted" in capsys.readouterr().out
- assert config_path.read_text() == "{}"
\ No newline at end of file
+ assert config_path.read_text() == "{}"
+
+
+class TestAddConfig:
+ def test_adds_new_config(self, capsys):
+ """Should add new config to config."""
+ config = {'configs': {}}
+
+ with patch('starlet_setup.config.save_config', return_value=Path('config.json')):
+ add_config(config, 'myconfig', {'ssh': False, 'verbose': True})
+
+ assert 'myconfig' in config['configs']
+ assert config['configs']['myconfig']['ssh'] is False
+ assert config['configs']['myconfig']['verbose'] is True
+ assert "added successfully" in capsys.readouterr().out
+
+
+ def test_creates_configs_key_if_missing(self):
+ """Should create configs dict if not present."""
+ config = {}
+
+ with patch('starlet_setup.config.save_config', return_value=Path('config.json')):
+ add_config(config, 'myconfig', {})
+
+ assert 'configs' in config
+ assert 'myconfig' in config['configs']
+
+
+ def test_overwrites_config_when_confirmed(self):
+ """Should overwrite existing config when user confirms."""
+ config = {'configs': {'myconfig': {'ssh': False}}}
+
+ with patch('starlet_setup.config.save_config', return_value=Path('config.json')), \
+ patch('builtins.input', return_value='y'):
+ add_config(config, 'myconfig', {'ssh': True})
+
+ assert config['configs']['myconfig'].get('ssh') == True
+
+
+ def test_aborts_overwrite_when_not_confirmed(self, capsys):
+ """Should not overwrite when user declines."""
+ config = {'configs': {'myconfig': {'ssh': False}}}
+
+ with patch('starlet_setup.config.save_config'), \
+ patch('builtins.input', return_value='n'):
+ add_config(config, 'myconfig', {'ssh': True})
+
+ assert config['configs']['myconfig'].get('ssh') is False
+ assert "Aborted" in capsys.readouterr().out
+
+
+class TestRemoveConfig:
+ def test_removes_existing_config(self):
+ """Should remove config when confirmed."""
+ config = {'configs': {'myconfig': {}}}
+
+ with patch('starlet_setup.config.save_config', return_value=Path('config.json')), \
+ patch('builtins.input', return_value='y'):
+ remove_config(config, 'myconfig')
+
+ assert 'myconfig' not in config['configs']
+
+
+ def test_aborts_removal_when_not_confirmed(self, capsys):
+ """Should not remove config when declined."""
+ config = {'configs': {'myconfig': {}}}
+
+ with patch('builtins.input', return_value='n'):
+ remove_config(config, 'myconfig')
+
+ assert 'myconfig' in config['configs']
+ assert "Aborted" in capsys.readouterr().out
+
+
+ def test_handles_nonexistent_config(self, capsys):
+ """Should warn when config doesn't exist."""
+ config = {'configs': {}}
+
+ remove_config(config, 'nonexistent')
+ assert "not found" in capsys.readouterr().out
+
+
+class TestListConfigs:
+ def test_list_all_configs(self, capsys):
+ """Should display all configurations."""
+ config = {
+ 'configs': {
+ 'config1': {'ssh': True},
+ 'config2': {'verbose': True}
+ }
+ }
+
+ list_configs(config)
+
+ output = capsys.readouterr().out
+ assert 'config1' in output
+ assert 'config2' in output
+ assert 'SSH: True' in output
+ assert 'Verbose flag: True' in output
diff --git a/tests/test_profiles.py b/tests/test_profiles.py
index bb9ac00..4f34e71 100644
--- a/tests/test_profiles.py
+++ b/tests/test_profiles.py
@@ -15,7 +15,7 @@ def test_adds_new_profile(self, capsys):
"""Should add new profile to config."""
config = {'profiles': {}}
- with patch('starlet_setup.profiles.save_config', return_value=Path('config.json')):
+ with patch('starlet_setup.config.save_config', return_value=Path('config.json')):
add_profile(config, ['myprofile', 'user/repo1', 'user/repo2'])
assert 'myprofile' in config['profiles']
@@ -27,7 +27,7 @@ def test_creates_profiles_key_if_missing(self):
"""Should create profiles dict if not present."""
config = {}
- with patch('starlet_setup.profiles.save_config', return_value=Path('config.json')):
+ with patch('starlet_setup.config.save_config', return_value=Path('config.json')):
add_profile(config, ['myprofile', 'user/repo1'])
assert 'profiles' in config
@@ -38,7 +38,7 @@ def test_overwrites_existing_profile_when_confirmed(self):
"""Should overwrite existing profile when user confirms."""
config = {'profiles': {'myprofile': ['old/repo']}}
- with patch('starlet_setup.profiles.save_config', return_value=Path('config.json')), \
+ with patch('starlet_setup.config.save_config', return_value=Path('config.json')), \
patch('builtins.input', return_value='y'):
add_profile(config, ['myprofile', 'new/repo1', 'new/repo2'])
@@ -49,7 +49,7 @@ def test_aborts_overwrite_when_not_confirmed(self, capsys):
"""Should not overwrite when user declines."""
config = {'profiles': {'myprofile': ['old/repo']}}
- with patch('starlet_setup.profiles.save_config'), \
+ with patch('starlet_setup.config.save_config'), \
patch('builtins.input', return_value='n'):
add_profile(config, ['myprofile', 'new/repo1'])
@@ -62,7 +62,7 @@ def test_errors_on_insufficient_arguments(self):
config = {}
with pytest.raises(SystemExit):
- add_profile(config, ['myprofile'])
+ add_profile(config, ['myprofile'])
class TestRemoveProfile:
@@ -70,7 +70,7 @@ def test_removes_existing_profile(self):
"""Should remove profile when confirmed."""
config = {'profiles': {'myprofile': ['user/repo1', 'user/repo2']}}
- with patch('starlet_setup.profiles.save_config', return_value=Path('config.json')), \
+ with patch('starlet_setup.config.save_config', return_value=Path('config.json')), \
patch('builtins.input', return_value='y'):
remove_profile(config, 'myprofile')