Skip to content

Commit

Permalink
cli: Add config subcommand
Browse files Browse the repository at this point in the history
And update Configuration type to use Path types instead of os.path.
  • Loading branch information
cassava committed May 6, 2024
1 parent 3cb7d3a commit 871eb2f
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 15 deletions.
37 changes: 22 additions & 15 deletions cli/cloe_launch/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
import os
import shutil
import subprocess
import sys

from pathlib import Path

from typing import (
List,
Expand All @@ -22,10 +25,9 @@ class ConfigurationError(Exception):
class Configuration:
"""Configuration contains the launcher configuration as read from file."""

config_dir = os.path.expanduser("~/.config/cloe/launcher/")

config_file = os.path.expanduser("~/.config/cloe/launcher/conf.toml")
runtime_dir = os.path.expanduser("~/.cache/cloe/launcher")
config_dir = Path("~/.config/cloe/launcher/").expanduser()
config_file = Path("~/.config/cloe/launcher/conf.toml").expanduser()
runtime_dir = Path("~/.cache/cloe/launcher").expanduser()

conf_version = "1"
_conf = {
Expand All @@ -41,15 +43,17 @@ class Configuration:

def __init__(self):
# Make configuration and runtime directories if needed:
if not os.path.exists(self.config_dir):
if not self.config_dir.exists():
logging.info("Create configuration directory: %s", self.config_dir)
os.makedirs(self.config_dir)
if not os.path.exists(self.runtime_dir):
self.config_dir.mkdir(parents=True)
if not self.runtime_dir.exists():
logging.info("Create runtime directory: %s", self.runtime_dir)
os.makedirs(self.runtime_dir)
self.runtime_dir.mkdir(parents=True)

# Load configuration file:
if os.path.exists(self.config_file):
if self.config_file.exists():
if not self.config_file.is_file():
raise ConfigurationError("configuration file not readable")
conf = toml.load(self.config_file)
if "version" not in conf:
raise ConfigurationError(
Expand All @@ -58,23 +62,26 @@ def __init__(self):
for k in conf.keys():
self._conf[k] = conf[k]

def profile_runtime(self, hash: str) -> str:
def print(self):
toml.dump(self._conf, sys.stdout)

def profile_runtime(self, hash: str) -> Path:
"""Return the path to the runtime directory of the profile."""
return os.path.join(self.runtime_dir, hash)
return self.runtime_dir / hash

def write(self) -> None:
"""Write current configuration to the disk."""
logging.info(f"Write configuration to {self.config_file}:\n {self._conf}")
with open(self.config_file, "w", encoding="utf-8") as file:
toml.dump(self._conf, file)

def edit(self, create: bool = False) -> None:
def edit(self, create: bool = False) -> int:
"""Open the configuration in the user's editor."""
editor = os.getenv("EDITOR")
if editor is None:
raise ConfigurationError("environment variable EDITOR is unset")
if not create and not os.path.exists(self.config_file):
if not create and not self.config_file.exists():
raise ConfigurationError(f"configuration {self.config_file} does not exist")
cmd = [editor, self.config_file]
cmd = editor.split(' ') + [str(self.config_file)]
logging.info("Exec: %s", " ".join(cmd))
subprocess.call(cmd)
return subprocess.call(cmd)
2 changes: 2 additions & 0 deletions cli/cloe_launch/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
from .exec import cli_exec
from .prepare import cli_prepare
from .shell import cli_shell
from .config import cli_config


@click.group(context_settings={"allow_interspersed_args": False})
Expand Down Expand Up @@ -129,6 +130,7 @@ def main():
cli.add_command(cli_deploy)
cli.add_command(cli_prepare)
cli.add_command(cli_shell)
cli.add_command(cli_config)

try:
cli()
Expand Down
71 changes: 71 additions & 0 deletions cli/cloe_launch/commands/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Copyright 2024 Robert Bosch GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0

# pylint: disable=too-many-arguments

"""
Implementation for cloe-launch command config.
Usage: cloe-launch config
"""

import click

from cloe_launch import Configuration
from ._options import cli_command


@cli_command("config")
@click.option("-e", "--edit", is_flag=True, help="Edit configuration file.")
@click.option("-w", "--write", is_flag=True, help="Write current configuration file.")
@click.pass_obj
def cli_config(
conf: Configuration,
edit: bool,
write: bool,
):
"""Manage launcher configuration.
Run without any options, the current configuration will be printed to
stdout. (This is the effective configuration, not the contents of the
configuration file, which may be less.)
When using the --edit flag, the EDITOR environment variable is used
to select the editor to use for the file:
EDITOR="code -w" cloe-launch config -e
The configuration file is located at:
~/.config/cloe/launcher/conf.toml
The runtime directory is located at:
~/.cache/cloe/launcher/
Usage Examples:
\b
cloe-launch config
cloe-launch config -we
"""

if not (write or edit):
conf.print()
if write:
conf.write()
if edit:
conf.edit(create = True)

0 comments on commit 871eb2f

Please sign in to comment.