v0.1.0
This commit is contained in:
38
README.md
38
README.md
@@ -29,8 +29,8 @@ Typically a context directory looks like this.
|
|||||||
In the above example, context "Goldfish" contains configs for apps "sway" and "wofi".
|
In the above example, context "Goldfish" contains configs for apps "sway" and "wofi".
|
||||||
These configs will be applied when you apply context "Goldfish".
|
These configs will be applied when you apply context "Goldfish".
|
||||||
|
|
||||||
When a context is applied the app configs from context directory are
|
When a context is applied the app configs from context directory are get
|
||||||
symlinked you ~/.config/ folder for each managed app. Goldfish/wofi/style.css symlinks to
|
symlinked to youe ~/.config/ folder for each managed app. Goldfish/wofi/style.css symlinks to
|
||||||
\~/.config/wofi/style.css, Goldfish/sway/theme.conf symlinks to \~/.config/sway/theme.conf etc.
|
\~/.config/wofi/style.css, Goldfish/sway/theme.conf symlinks to \~/.config/sway/theme.conf etc.
|
||||||
|
|
||||||
This default behaviour can be changed and specific actions or customizations
|
This default behaviour can be changed and specific actions or customizations
|
||||||
@@ -41,7 +41,7 @@ The default location for the config is ~/.config/userctx/config.toml.
|
|||||||
reload configs etc. For a detailed overview of all config options see below.
|
reload configs etc. For a detailed overview of all config options see below.
|
||||||
|
|
||||||
There are two commands **userctx** understands: *list* and *apply*.
|
There are two commands **userctx** understands: *list* and *apply*.
|
||||||
- *list* lists available contexts in a manner suitable for dmenu-like menu apps
|
- *list* lists available contexts in a manner suitable for dmenu-like apps
|
||||||
- *apply* \<context\> applies named context
|
- *apply* \<context\> applies named context
|
||||||
|
|
||||||
To test your configuration run:
|
To test your configuration run:
|
||||||
@@ -54,7 +54,33 @@ anything in your home directory.
|
|||||||
For a quickstart and simple examples jump to "Examples" section below.
|
For a quickstart and simple examples jump to "Examples" section below.
|
||||||
|
|
||||||
## Configuring userctx
|
## Configuring userctx
|
||||||
TODO: full description of config options.
|
**userctx** is configured through a TOML file located at `~/.config/userctx/config.toml` by default. The configuration is split into two main sections: `[general]` and `[apps]`.
|
||||||
|
|
||||||
|
### The `[general]` section
|
||||||
|
This section contains global settings for **userctx**.
|
||||||
|
|
||||||
|
- `dry_run` (boolean, optional): If set to `true`, **userctx** will only print the actions it would take without making any changes to the filesystem. This is useful for testing your configuration. The command-line flag `--nop` overrides this setting.
|
||||||
|
- `apps` (array of strings, required): A list of application names that **userctx** should manage. For each application in this list, **userctx** will look for a corresponding configuration section in the `[apps]` table.
|
||||||
|
- `source_path` (string, optional): The base path where your contexts are stored. Defaults to `$XDG_CONFIG_HOME/userctx` or `~/.config/userctx`.
|
||||||
|
- `target_path` (string, optional): The base path where application configurations are located. Defaults to `$XDG_CONFIG_HOME` or `~/.config`.
|
||||||
|
|
||||||
|
### The `[apps]` section
|
||||||
|
For each application defined in the `general.apps` array, you can have a dedicated section to specify its configuration.
|
||||||
|
|
||||||
|
You can create '[apps.<you_app>]' section in the config to specify **userctx** behaviour for the app. The following option are supported.
|
||||||
|
|
||||||
|
- `source_path` (string, optional): Overrides the global `source_path` for this specific application.
|
||||||
|
- `target_path` (string, optional): Overrides the global `target_path` for this specific application. The final destination path for an application's configuration will be `<target_path>/<app_name>`.
|
||||||
|
- `actions` (array of strings, optional): A list of actions to perform for the application. The available actions are `symlink`, `script`, `exec`, and `reload`. If not specified, the default actions are `[symlink, script, exec, reload]` if the corresponding keys (`symlink`, `script`, `exec`, `reload`) are present in the app's configuration.
|
||||||
|
- `symlink` (table, optional): A map of source files to destination files for creating symlinks. The source is relative to the context's application directory (e.g., `<source_path>/<context_name>/<app_name>`), and the destination is relative to the application's `target_path`. You can use `*` as a wildcard to match all files in the source directory.
|
||||||
|
- `exec` (string, optional): A shell command or script to execute. The script is executed in a shell environment with the following environment variables set:
|
||||||
|
- `CONTEXT_NAME`: The name of the context being applied.
|
||||||
|
- `CONTEXT_SRC`: The source directory for the current application's context.
|
||||||
|
- `CONTEXT_DST`: The target directory for the current application's configuration.
|
||||||
|
- `script` (array of strings, optional): A list of script files to execute. The scripts are looked for in the application's context directory. If the list is empty or not provided, **userctx** will look for and execute any file ending with `.sh` in the context directory.
|
||||||
|
- `reload` (string, optional): A shell command to execute to reload the application's configuration. This is typically used to make the application aware of the changes applied by **userctx**.
|
||||||
|
|
||||||
|
TODO: a more detailed explanation of wildcard symlinking.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
### Basic usecase: we only need symlinks
|
### Basic usecase: we only need symlinks
|
||||||
@@ -62,7 +88,7 @@ Let's add configuration for "foot" terminal emulator, which
|
|||||||
will be applied when we apply context "Goldfish" assuming
|
will be applied when we apply context "Goldfish" assuming
|
||||||
we would like to switch foot's visual theme when swithching context.
|
we would like to switch foot's visual theme when swithching context.
|
||||||
|
|
||||||
1. First we need to create a separate file for visuals config in out
|
1. First we need to create a separate file for visuals config in our
|
||||||
context directory.
|
context directory.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -143,7 +169,7 @@ inherits = "github_light"
|
|||||||
```
|
```
|
||||||
Now edit ~/.config/userctx/config.toml.
|
Now edit ~/.config/userctx/config.toml.
|
||||||
|
|
||||||
Add the "helix" to "general" section.
|
Add "helix" to "general" section.
|
||||||
```toml
|
```toml
|
||||||
[general]
|
[general]
|
||||||
apps = [
|
apps = [
|
||||||
|
|||||||
73
config.toml
73
config.toml
@@ -1,7 +1,7 @@
|
|||||||
[general]
|
[general]
|
||||||
# if dry run is set to true
|
# if dry run is set to true
|
||||||
# userctx will only validate config
|
# userctx will only validate config
|
||||||
# and tell you what it will do to execute
|
# and tell you what it will do to apply context
|
||||||
# tasks
|
# tasks
|
||||||
dry_run = true
|
dry_run = true
|
||||||
|
|
||||||
@@ -10,16 +10,16 @@ dry_run = true
|
|||||||
# set, then userctx will do nothing.
|
# set, then userctx will do nothing.
|
||||||
# Uncomment apps below.
|
# Uncomment apps below.
|
||||||
apps = [
|
apps = [
|
||||||
#"niri",
|
"niri",
|
||||||
#"fuzzel",
|
"fuzzel",
|
||||||
#"gtk",
|
"gtk",
|
||||||
#"helix",
|
"helix",
|
||||||
#"kitty",
|
"kitty",
|
||||||
#"mako",
|
"mako",
|
||||||
#"sway",
|
"sway",
|
||||||
#"swaybg",
|
"swaybg",
|
||||||
#"waybar",
|
"waybar",
|
||||||
#"wofi",
|
"wofi",
|
||||||
]
|
]
|
||||||
|
|
||||||
# target directory where managed configs
|
# target directory where managed configs
|
||||||
@@ -30,24 +30,11 @@ target_path = "~/.config"
|
|||||||
|
|
||||||
# directory where contexts are stored
|
# directory where contexts are stored
|
||||||
# default is "~/.config/userctx"
|
# default is "~/.config/userctx"
|
||||||
source_path = "~/code/userctx/test"
|
source_path = "~/.config/userctx"
|
||||||
|
|
||||||
# section that demonstrates all the available
|
# section that demonstrates all the available
|
||||||
# features of userctx
|
# features of userctx
|
||||||
[apps.example]
|
[apps.example]
|
||||||
# Path to appliaction configs is read from
|
|
||||||
# general.source_path. The default source path is
|
|
||||||
# ~/.config/userctx/<context_name>/example for this
|
|
||||||
# app.
|
|
||||||
# Individual path for app can be provided via
|
|
||||||
# "source_path" for particular app. Then userctx will try to lookup
|
|
||||||
# app settings in /source_path/<context_name>
|
|
||||||
# Default is general.source_path/<context_name>/<app_name>.
|
|
||||||
# For this example it will expand to
|
|
||||||
# ~/.config/userctx/<context_name/example.
|
|
||||||
# TODO: do we really need this?
|
|
||||||
source_path = "~/tmp/contexts"
|
|
||||||
|
|
||||||
# The default path to apply your context to is
|
# The default path to apply your context to is
|
||||||
# ~/.config/example (for app name "example")
|
# ~/.config/example (for app name "example")
|
||||||
# if not overridden with general.target_path.
|
# if not overridden with general.target_path.
|
||||||
@@ -60,7 +47,7 @@ target_path = "~/.config/example/configs"
|
|||||||
# "symlink" map defines
|
# "symlink" map defines
|
||||||
# which files will be symlinked to users home
|
# which files will be symlinked to users home
|
||||||
# directory.
|
# directory.
|
||||||
# Names of files in thes mapping are relative to
|
# Names of files in this mapping are relative to
|
||||||
# context directory and target directory
|
# context directory and target directory
|
||||||
# by default source is ~/.config/userctx/<context_name>/example
|
# by default source is ~/.config/userctx/<context_name>/example
|
||||||
# and target directory is ~/.config/example
|
# and target directory is ~/.config/example
|
||||||
@@ -76,6 +63,18 @@ symlink."context_file.conf" = "symlink_to_context_file.conf"
|
|||||||
symlink."other_file.conf" = "subdir/other_file.conf"
|
symlink."other_file.conf" = "subdir/other_file.conf"
|
||||||
symlink."subdir/yet_another_file.conf" = "yet_another_file.conf"
|
symlink."subdir/yet_another_file.conf" = "yet_another_file.conf"
|
||||||
|
|
||||||
|
# If symlinks mapping is not empty then only instructions from the map
|
||||||
|
# will be applied. If you want to redefine linking rules only for single
|
||||||
|
# file and symlink others according to default rules then add the following
|
||||||
|
# rule as well.
|
||||||
|
symlink."*" = "*"
|
||||||
|
|
||||||
|
# As a special case, providing the following mapping symlinks
|
||||||
|
# a SINGLE file (the first one found) from context directory
|
||||||
|
# to a specified name (see helix section below).
|
||||||
|
# This reads "symlinks ANY file you find to this path".
|
||||||
|
# symlink."*" = "some/destination.conf"
|
||||||
|
|
||||||
|
|
||||||
# "exec" let's you write a reload command or
|
# "exec" let's you write a reload command or
|
||||||
# even a bigger custom script that will apply contents of
|
# even a bigger custom script that will apply contents of
|
||||||
@@ -96,7 +95,8 @@ exec = """
|
|||||||
echo "$CONTEXT_NAME"
|
echo "$CONTEXT_NAME"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# scripts array will try to find
|
# if "script" array is not empty
|
||||||
|
# then userctx will try to find
|
||||||
# named files in $CONTEXT_SRC and
|
# named files in $CONTEXT_SRC and
|
||||||
# execute them with $SHELL <script>
|
# execute them with $SHELL <script>
|
||||||
# IMPORTANT: if array is empty
|
# IMPORTANT: if array is empty
|
||||||
@@ -104,13 +104,30 @@ exec = """
|
|||||||
# "actions" array above then all files
|
# "actions" array above then all files
|
||||||
# in $CONTEXT_SRC will be treated as scripts
|
# in $CONTEXT_SRC will be treated as scripts
|
||||||
# (note the "apps.gtk section below")
|
# (note the "apps.gtk section below")
|
||||||
scripts = [
|
script = [
|
||||||
"script1.sh",
|
"script1.sh",
|
||||||
"script2.sh",
|
"script2.sh",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# if "reload" is present, the command will be executed after everythong alse is done
|
||||||
reload = "pkill -USR1 example"
|
reload = "pkill -USR1 example"
|
||||||
|
|
||||||
|
# "actions" array specifies the order of actions when
|
||||||
|
# applying context. If omitted, the default behaviour
|
||||||
|
# it to symlink, run scripts, run exec part then run reload
|
||||||
|
# command (if relevant actions are specified).
|
||||||
|
# If nothig has been customized in apps configuration here
|
||||||
|
# (no commands array, not symlinks mapping etc.) then userctx
|
||||||
|
# will just symlink anythong it finds to target_path.
|
||||||
|
# If actions array is declared empty (actions = []) then
|
||||||
|
# userctx will do nothig.
|
||||||
|
actions = [
|
||||||
|
"symlink",
|
||||||
|
"exec",
|
||||||
|
"script",
|
||||||
|
"reload",
|
||||||
|
]
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
# settings for some
|
# settings for some
|
||||||
# commonly used apps
|
# commonly used apps
|
||||||
|
|||||||
@@ -232,10 +232,10 @@ class ContextManager(object):
|
|||||||
def __init__(self, config: ContextManagerConfig):
|
def __init__(self, config: ContextManagerConfig):
|
||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
def print_contexts_list(self) -> None:
|
def list_contexts(self) -> None:
|
||||||
print('\n'.join(self.config.get_contexts_list()))
|
print('\n'.join(self.config.get_contexts_list()))
|
||||||
|
|
||||||
def load_context(self, context_name: str) -> None:
|
def apply_context(self, context_name: str) -> None:
|
||||||
print(f'loading and applying context: "{context_name}"')
|
print(f'loading and applying context: "{context_name}"')
|
||||||
try:
|
try:
|
||||||
tasks = self.config.get_tasks_for_context(context_name)
|
tasks = self.config.get_tasks_for_context(context_name)
|
||||||
@@ -284,9 +284,9 @@ class Runner(object):
|
|||||||
try:
|
try:
|
||||||
ctxmgr = ContextManager(config)
|
ctxmgr = ContextManager(config)
|
||||||
if args.command == COMMAND_LIST:
|
if args.command == COMMAND_LIST:
|
||||||
ctxmgr.print_contexts_list()
|
ctxmgr.list_contexts()
|
||||||
elif args.command == COMMAND_APPLY:
|
elif args.command == COMMAND_APPLY:
|
||||||
ctxmgr.load_context(args.__dict__[COMMAND_CTX_NAME]) # guaranteed to be present by argparse
|
ctxmgr.apply_context(args.__dict__[COMMAND_CTX_NAME]) # guaranteed to be present by argparse
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f'error executing command:', e)
|
print(f'error executing command:', e)
|
||||||
return 3
|
return 3
|
||||||
|
|||||||
Reference in New Issue
Block a user