Skip to content

Commit

Permalink
new: Allow specifying a custom configuration path through environment…
Browse files Browse the repository at this point in the history
… variable (linode#652)
  • Loading branch information
yec-akamai authored Oct 16, 2024
1 parent e7ed7a4 commit 268d689
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 9 deletions.
11 changes: 4 additions & 7 deletions linodecli/configuration/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,10 @@ def update(
):
print(f"User {username} is not configured.")
sys.exit(ExitCodes.USERNAME_ERROR)
if not self.config.has_section(username) or allowed_defaults is None:
if (
not self.config.has_section(username)
and self.config.default_section is None
) or allowed_defaults is None:
return namespace

warn_dict = {}
Expand Down Expand Up @@ -335,12 +338,6 @@ def write_config(self):
to save values they've set, and is used internally to update the config
on disk when a new user if configured.
"""

# Create the config path isf necessary
config_path = f"{os.path.expanduser('~')}/.config"
if not os.path.exists(config_path):
os.makedirs(config_path)

with open(_get_config_path(), "w", encoding="utf-8") as f:
self.config.write(f)

Expand Down
16 changes: 15 additions & 1 deletion linodecli/configuration/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
"XDG_CONFIG_HOME", f"{os.path.expanduser('~')}/.config"
)

ENV_CONFIG_FILE_PATH = "LINODE_CLI_CONFIG"

# this is a list of browser that _should_ work for web-based auth. This is mostly
# intended to exclude lynx and other terminal browsers which could be opened, but
# won't work.
Expand All @@ -38,11 +40,23 @@ def _get_config_path() -> str:
:returns: The path to the local config file.
:rtype: str
"""
custom_path = os.getenv(ENV_CONFIG_FILE_PATH, None)

if custom_path is not None:
custom_path = os.path.expanduser(custom_path)
if not os.path.exists(custom_path):
os.makedirs(os.path.dirname(custom_path), exist_ok=True)
return custom_path

path = f"{LEGACY_CONFIG_DIR}/{LEGACY_CONFIG_NAME}"
if os.path.exists(path):
return path

return f"{CONFIG_DIR}/{CONFIG_NAME}"
path = f"{CONFIG_DIR}/{CONFIG_NAME}"
if not os.path.exists(path):
os.makedirs(CONFIG_DIR, exist_ok=True)

return path


def _get_config(load: bool = True):
Expand Down
2 changes: 2 additions & 0 deletions linodecli/help_pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
"(e.g. 'v4beta')",
"LINODE_CLI_API_SCHEME": "Overrides the target scheme used for API requests. "
"(e.g. 'https')",
"LINODE_CLI_CONFIG": "Overrides the default configuration file path. "
"(e.g '~/.linode/my-cli-config')",
}

HELP_TOPICS = {
Expand Down
23 changes: 23 additions & 0 deletions tests/unit/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,3 +609,26 @@ def test_bool_input_default(self, monkeypatch):
output = stdout_buf.getvalue()
assert "foo [y/N]: " in output
assert result

def test_custom_config_path(self, monkeypatch, tmp_path):
"""
Test use a custom configuration path
"""
conf = self._build_test_config()
custom_path = tmp_path / "test-cli-config"

with (
patch.dict(
os.environ,
{"LINODE_CLI_CONFIG": custom_path.absolute().as_posix()},
),
):
conf.write_config()

configs = custom_path.read_text().splitlines()
expected_configs = self.mock_config_file.splitlines()

assert len(configs) == len(expected_configs) + 1

for i, _ in enumerate(expected_configs):
assert expected_configs[i] == configs[i]
3 changes: 3 additions & 0 deletions wiki/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ environment variable.
If you wish to hide the API Version warning you can use the `LINODE_CLI_SUPPRESS_VERSION_WARNING`
environment variable.

You may also specify a custom configuration path using the `LINODE_CLI_CONFIG` environment variable
to replace the default path `~/.config/linode-cli`.

## Configurable API URL

In some cases you may want to run linode-cli against a non-default Linode API URL.
Expand Down
3 changes: 2 additions & 1 deletion wiki/development/Development - Overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ configure the following:
- Overrides for the target API URL (hostname, version, scheme, etc.)

This command serves as an interactive prompt and outputs a configuration file to `~/.config/linode-cli`.
This file is in a simple INI format and can be easily modified manually by users.
This file is in a simple INI format and can be easily modified manually by users.
You may also specify a custom configuration file path using the `LINODE_CLI_CONFIG` environment variable.

Additionally, multiple users can be created for the CLI which can be designated when running commands using the `--as-user` argument
or using the `default-user` config variable.
Expand Down

0 comments on commit 268d689

Please sign in to comment.