Prefix plugin clones with the username so shared clones don't collide
Clones of omarchy.clock become dhh.clock instead of local.clock, so a published clone carries its author's namespace. The clone command owns the id derivation and gains --edit to open the result in $EDITOR, and the shell exposes clonedFrom in listPlugins so the plugin menu no longer reconstructs clone ids. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
2050f28d55
commit
1bc89105d2
@@ -12,7 +12,7 @@ PLUGIN_ICON=$'\U000f0431'
|
||||
case "${1:-}" in
|
||||
enable) filter='(.enabled | not)' ;;
|
||||
disable) filter='.canDisable and .enabled' ;;
|
||||
clone) filter='.firstParty and ((.id | sub("^omarchy\\."; "local.")) as $clone_id | ($plugins | map(.id) | index($clone_id)) == null)' ;;
|
||||
clone) filter='.firstParty and (.id as $id | ($plugins | map(.clonedFrom // "") | index($id)) == null)' ;;
|
||||
remove) filter='(.firstParty | not)' ;;
|
||||
*)
|
||||
echo "Usage: omarchy-menu-plugin <enable|disable|clone|remove>" >&2
|
||||
@@ -40,10 +40,8 @@ id=$(awk -F'\t' -v label="$name" '$2 == label { print $3; exit }' <<<"$rows")
|
||||
[[ -n $id ]] || exit 1
|
||||
|
||||
if [[ $1 == "clone" ]]; then
|
||||
new_id="local.${id#omarchy.}"
|
||||
target="$HOME/.config/omarchy/plugins/$new_id"
|
||||
omarchy-launch-floating-terminal-with-presentation \
|
||||
"omarchy-plugin-clone $(printf '%q' "$id") && exec \$EDITOR $(printf '%q' "$target")"
|
||||
"omarchy-plugin-clone --edit $(printf '%q' "$id")"
|
||||
elif [[ $1 == "remove" ]]; then
|
||||
omarchy-launch-floating-terminal-with-presentation "omarchy-plugin-remove $(printf '%q' "$id")"
|
||||
else
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# omarchy:summary=Clone a built-in Omarchy shell plugin into your own config
|
||||
# omarchy:group=plugin
|
||||
# omarchy:args=<source-id>
|
||||
# omarchy:args=<source-id> [--edit]
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@@ -81,16 +81,19 @@ update_manifest() {
|
||||
|
||||
usage() {
|
||||
cat <<USAGE
|
||||
Usage: omarchy plugin clone <source-id>
|
||||
Usage: omarchy plugin clone <source-id> [--edit]
|
||||
|
||||
Copies a built-in plugin into ~/.config/omarchy/plugins/local.<id>/ so you can
|
||||
edit it freely. The clone keeps all of the source plugin's files and kinds and
|
||||
uses "My <name>" as its display name, then replaces the built-in with the clone.
|
||||
Copies a built-in plugin into ~/.config/omarchy/plugins/<username>.<id>/ so you
|
||||
can edit it freely. The clone keeps all of the source plugin's files and kinds
|
||||
and uses "My <name>" as its display name, then replaces the built-in with the
|
||||
clone. The username prefix keeps the id yours, so a shared clone does not
|
||||
collide with anyone else's. --edit opens the clone in \$EDITOR afterwards.
|
||||
|
||||
USAGE
|
||||
}
|
||||
|
||||
source_id=""
|
||||
edit_clone=0
|
||||
if (( $# > 0 )) && [[ $1 != --* ]]; then
|
||||
source_id="$1"
|
||||
shift
|
||||
@@ -98,6 +101,10 @@ fi
|
||||
|
||||
while (( $# > 0 )); do
|
||||
case "$1" in
|
||||
--edit)
|
||||
edit_clone=1
|
||||
shift
|
||||
;;
|
||||
-h | --help)
|
||||
usage
|
||||
exit 0
|
||||
@@ -121,7 +128,7 @@ source_info=$(omarchy-plugin-catalog | jq -r --arg id "$source_id" '
|
||||
[[ -n $source_info ]] || fail "unknown built-in plugin: $source_id"
|
||||
IFS=$'\t' read -r source_dir source_manifest source_name <<<"$source_info"
|
||||
|
||||
new_id="local.${source_id#omarchy.}"
|
||||
new_id="${USER:-$(id -un)}.${source_id#omarchy.}"
|
||||
display_name="My $source_name"
|
||||
target_dir="$PLUGINS_DIR/$new_id"
|
||||
[[ ! -e $target_dir && ! -L $target_dir ]] || fail "$target_dir already exists"
|
||||
@@ -155,3 +162,7 @@ omarchy-notification-send -g \
|
||||
"Editing Cloned Plugin" \
|
||||
"Original plugin has been replace by clone."
|
||||
echo "Cloned $source_id to $target_dir and switched to $new_id"
|
||||
if (( edit_clone )); then
|
||||
# Word-splitting is deliberate: EDITOR may carry flags.
|
||||
exec $EDITOR "$target_dir"
|
||||
fi
|
||||
|
||||
@@ -184,7 +184,7 @@ Clone it into the user plugin directory instead:
|
||||
|
||||
```bash
|
||||
omarchy plugin clone omarchy.workspaces
|
||||
# Edit ~/.config/omarchy/plugins/local.workspaces/; saved changes reload automatically.
|
||||
# Edit ~/.config/omarchy/plugins/<username>.workspaces/; saved changes reload automatically.
|
||||
```
|
||||
|
||||
**Commands:** `omarchy restart shell`, `omarchy refresh shell`
|
||||
@@ -419,6 +419,6 @@ This skill intentionally does not cover Omarchy source development. Do not use t
|
||||
- "Clear all reminders" -> `omarchy reminder clear`
|
||||
- "Customize the catppuccin theme colors" -> Create `~/.config/omarchy/themes/catppuccin-custom/` by copying from stock, then edit
|
||||
- "Run a script every time I change themes" -> Install it with `omarchy hook install theme-set <script>`
|
||||
- "Change how workspace labels are rendered" -> Clone `omarchy.workspaces`, which switches the bar to `local.workspaces`, then edit the clone
|
||||
- "Change how workspace labels are rendered" -> Clone `omarchy.workspaces`, which switches the bar to `<username>.workspaces`, then edit the clone
|
||||
- "Lock after ten minutes" -> Set `idle.lock` to `600` in `~/.config/omarchy/shell.json`
|
||||
- "Reset shell/bar to defaults" -> `omarchy refresh shell`
|
||||
|
||||
@@ -59,10 +59,11 @@ no checkout to delete. Add, Clone, and Remove open a terminal so their warning,
|
||||
editor, confirmation, and output stay visible.
|
||||
|
||||
Cloning `omarchy.clock`, for example, creates and switches to
|
||||
`~/.config/omarchy/plugins/local.clock/`, names it `My Clock`, and preserves
|
||||
the built-in IPC identity so existing shortcuts keep working. Saving files in
|
||||
any installed plugin reloads its code automatically, and removing an active clone
|
||||
switches back to its built-in source.
|
||||
`~/.config/omarchy/plugins/<username>.clock/` (e.g. `dhh.clock`), names it
|
||||
`My Clock`, and preserves the built-in IPC identity so existing shortcuts keep
|
||||
working. The username prefix keeps a shared clone from colliding with anyone
|
||||
else's. Saving files in any installed plugin reloads its code automatically,
|
||||
and removing an active clone switches back to its built-in source.
|
||||
|
||||
For a bar widget, on and off means its place in the bar. Everything else is
|
||||
loaded by default when it is built in, so `shell.json` records only the
|
||||
|
||||
+5
-3
@@ -143,15 +143,17 @@ The `omarchy plugin` commands wrap those calls. `omarchy bar move` and
|
||||
To hack on a built-in plugin safely, clone it into user config instead of
|
||||
editing the built-in source. The complete plugin directory is copied, including
|
||||
every declared kind and local dependency. A built-in id such as
|
||||
`omarchy.clock` becomes `local.clock`, with `My Clock` as its display name.
|
||||
`omarchy.clock` becomes `<username>.clock` (e.g. `dhh.clock`), with `My Clock`
|
||||
as its display name. The username prefix keeps shared clones from colliding
|
||||
with each other or with other plugin authors.
|
||||
|
||||
```bash
|
||||
omarchy plugin clone omarchy.clock
|
||||
```
|
||||
|
||||
Cloning switches from the built-in to the new local plugin, preserving an
|
||||
Cloning switches from the built-in to the new personal plugin, preserving an
|
||||
existing bar widget's position and settings. Setup > Plugins > Clone provides
|
||||
the interactive picker, then opens the new `local.*` directory in `$EDITOR`.
|
||||
the interactive picker, then opens the new `<username>.*` directory in `$EDITOR`.
|
||||
Existing shortcuts and shell IPC calls made to the built-in id are routed to
|
||||
the enabled clone, so cloning does not require changing its callers. Removing
|
||||
an active clone switches back to its built-in source.
|
||||
|
||||
+4
-1
@@ -938,6 +938,8 @@ ShellRoot {
|
||||
var isBarOption = Array.isArray(kinds) && kinds.indexOf("bar") !== -1
|
||||
var isBarWidget = Array.isArray(kinds) && kinds.indexOf("bar-widget") !== -1
|
||||
var active = isBarOption && shell.isActiveBarOption(id)
|
||||
var metadata = plugins[id].omarchy
|
||||
var clonedFrom = Util.isPlainObject(metadata) ? String(metadata.clonedFrom || "") : ""
|
||||
out.push({
|
||||
id: id,
|
||||
name: plugins[id].name,
|
||||
@@ -952,7 +954,8 @@ ShellRoot {
|
||||
// that a caller offering the verbs does not have to read kinds and
|
||||
// work it out again.
|
||||
canDisable: !isBarOption,
|
||||
firstParty: !!plugins[id].__isFirstParty
|
||||
firstParty: !!plugins[id].__isFirstParty,
|
||||
clonedFrom: clonedFrom
|
||||
})
|
||||
}
|
||||
// Consumers should not each invent their own presentation order.
|
||||
|
||||
@@ -70,15 +70,15 @@ pick() {
|
||||
cat >"$TMPDIR/plugins.json" <<'JSON'
|
||||
[
|
||||
{"id": "omarchy.clock", "name": "Clock", "kinds": ["bar-widget"], "enabled": false, "active": false, "canDisable": true, "firstParty": true},
|
||||
{"id": "local.clock", "name": "Clock", "kinds": ["bar-widget"], "enabled": false, "active": false, "canDisable": true, "firstParty": false}
|
||||
{"id": "tester.clock", "name": "Clock", "kinds": ["bar-widget"], "enabled": false, "active": false, "canDisable": true, "firstParty": false}
|
||||
]
|
||||
JSON
|
||||
|
||||
pick enable "Clock (local.clock)"
|
||||
[[ $ROWS == *"Clock (omarchy.clock)"* && $ROWS == *"Clock (local.clock)"* ]] \
|
||||
pick enable "Clock (tester.clock)"
|
||||
[[ $ROWS == *"Clock (omarchy.clock)"* && $ROWS == *"Clock (tester.clock)"* ]] \
|
||||
|| fail "picker tells two plugins of the same name apart" "$ROWS"
|
||||
pass "picker tells two plugins of the same name apart"
|
||||
[[ $CALLS == *"omarchy-plugin-enable local.clock"* ]] \
|
||||
[[ $CALLS == *"omarchy-plugin-enable tester.clock"* ]] \
|
||||
|| fail "picker acts on the row that was picked, not the one that shares its name" "$CALLS"
|
||||
pass "picker acts on the row that was picked, not the one that shares its name"
|
||||
|
||||
@@ -87,19 +87,19 @@ pass "picker acts on the row that was picked, not the one that shares its name"
|
||||
cat >"$TMPDIR/plugins.json" <<'JSON'
|
||||
[
|
||||
{"id": "omarchy.clock", "name": "Clock", "kinds": ["bar-widget"], "enabled": true, "active": false, "canDisable": true, "firstParty": true},
|
||||
{"id": "local.clock", "name": "Clock", "kinds": ["bar-widget"], "enabled": false, "active": false, "canDisable": true, "firstParty": false}
|
||||
{"id": "tester.clock", "name": "Clock", "kinds": ["bar-widget"], "enabled": false, "active": false, "canDisable": true, "firstParty": false}
|
||||
]
|
||||
JSON
|
||||
|
||||
pick enable "Clock"
|
||||
[[ $ROWS != *"("* ]] || fail "picker adorns a row only when its name is taken twice over" "$ROWS"
|
||||
pass "picker adorns a row only when its name is taken twice over"
|
||||
[[ $CALLS == *"omarchy-plugin-enable local.clock"* ]] \
|
||||
[[ $CALLS == *"omarchy-plugin-enable tester.clock"* ]] \
|
||||
|| fail "picker resolves a lone row to the plugin the verb offered, not a namesake it filtered out" "$CALLS"
|
||||
pass "picker resolves a lone row to the plugin the verb offered, not a namesake it filtered out"
|
||||
|
||||
pick remove "Clock"
|
||||
[[ $CALLS == *"omarchy-plugin-remove local.clock"* ]] \
|
||||
[[ $CALLS == *"omarchy-plugin-remove tester.clock"* ]] \
|
||||
|| fail "picker removes the plugin whose row was picked" "$CALLS"
|
||||
pass "picker removes the plugin whose row was picked"
|
||||
|
||||
@@ -118,8 +118,8 @@ pass "picker leaves an unambiguous name unadorned"
|
||||
|| fail "picker delegates plugin enablement to the plugin command" "$CALLS"
|
||||
pass "picker delegates plugin enablement to the plugin command"
|
||||
|
||||
# Clone offers only first-party plugins without an existing local counterpart,
|
||||
# then performs the clone and opens its deterministic path in $EDITOR.
|
||||
# Clone offers only first-party plugins that no installed clone points back at,
|
||||
# then hands the pick to the clone command, which opens the result in $EDITOR.
|
||||
cat >"$TMPDIR/plugins.json" <<'JSON'
|
||||
[
|
||||
{"id": "omarchy.clock", "name": "Clock", "kinds": ["bar-widget"], "enabled": true, "active": false, "canDisable": true, "firstParty": true},
|
||||
@@ -131,15 +131,16 @@ pick clone "Clock"
|
||||
[[ $ROWS == *"Clock"* && $ROWS != *"Weather"* ]] ||
|
||||
fail "clone picker offers only built-in plugins" "$ROWS"
|
||||
pass "clone picker offers built-in plugins"
|
||||
[[ $CALLS == *'terminal: omarchy-plugin-clone omarchy.clock && exec $EDITOR '*"/.config/omarchy/plugins/local.clock" ]] ||
|
||||
fail "clone picker opens the cloned path in EDITOR" "$CALLS"
|
||||
pass "clone picker clones and opens the local plugin"
|
||||
[[ $CALLS == *"terminal: omarchy-plugin-clone --edit omarchy.clock"* ]] ||
|
||||
fail "clone picker delegates cloning and editing to the clone command" "$CALLS"
|
||||
pass "clone picker clones and opens the personal plugin"
|
||||
|
||||
# Once local.<id> is discovered, the source no longer belongs in Clone.
|
||||
# Once a clone pointing back at the source is discovered, whatever it is named,
|
||||
# the source no longer belongs in Clone.
|
||||
cat >"$TMPDIR/plugins.json" <<'JSON'
|
||||
[
|
||||
{"id": "omarchy.clock", "name": "Clock", "kinds": ["bar-widget"], "enabled": true, "active": false, "canDisable": true, "firstParty": true},
|
||||
{"id": "local.clock", "name": "My Clock", "kinds": ["bar-widget"], "enabled": false, "active": false, "canDisable": true, "firstParty": false}
|
||||
{"id": "tester.clock", "name": "My Clock", "kinds": ["bar-widget"], "enabled": false, "active": false, "canDisable": true, "firstParty": false, "clonedFrom": "omarchy.clock"}
|
||||
]
|
||||
JSON
|
||||
|
||||
@@ -179,7 +180,7 @@ pass "picker keeps a bar out of disable"
|
||||
cat >"$TMPDIR/plugins.json" <<'JSON'
|
||||
[
|
||||
{"id": "omarchy.bar", "name": "Bar", "kinds": ["bar"], "enabled": false, "active": false, "canDisable": false, "firstParty": true},
|
||||
{"id": "local.neon-bar", "name": "Neon Bar", "kinds": ["bar"], "enabled": true, "active": true, "canDisable": false, "firstParty": false}
|
||||
{"id": "tester.neon-bar", "name": "Neon Bar", "kinds": ["bar"], "enabled": true, "active": true, "canDisable": false, "firstParty": false}
|
||||
]
|
||||
JSON
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ fi
|
||||
exit 0
|
||||
SH
|
||||
|
||||
for command in omarchy-plugin-enable omarchy-notification-send; do
|
||||
for command in omarchy-plugin-enable omarchy-notification-send fake-editor; do
|
||||
cat >"$TMPDIR/bin/$command" <<'SH'
|
||||
#!/bin/bash
|
||||
printf '%s %s\n' "${0##*/}" "$*" >>"$FAKE_CALLS"
|
||||
@@ -49,14 +49,14 @@ clone_plugin() {
|
||||
}
|
||||
}
|
||||
}'
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" PATH="$TMPDIR/bin:$ROOT/bin:$PATH" \
|
||||
HOME="$TMPDIR/home" USER=tester OMARCHY_PATH="$ROOT" PATH="$TMPDIR/bin:$ROOT/bin:$PATH" \
|
||||
FAKE_CALLS="$CALLS" OMARCHY_TEST_ROOT="$ROOT" \
|
||||
FAKE_SHELL_CONFIG="${FAKE_CLONE_CONFIG:-$default_config}" \
|
||||
omarchy-plugin-clone "$@"
|
||||
}
|
||||
|
||||
clone_plugin omarchy.clock >/dev/null
|
||||
clock="$TMPDIR/home/.config/omarchy/plugins/local.clock"
|
||||
clock="$TMPDIR/home/.config/omarchy/plugins/tester.clock"
|
||||
|
||||
for file in manifest.json BarWidget.qml Panel.qml Model.js; do
|
||||
[[ -f $clock/$file ]] || fail "clock clone is missing $file"
|
||||
@@ -73,7 +73,7 @@ rg -qF "omarchy.clock" "$clock" -g '*.qml' -g '*.js' ||
|
||||
pass "clone preserves the built-in runtime IPC id"
|
||||
|
||||
jq -e '
|
||||
.id == "local.clock" and
|
||||
.id == "tester.clock" and
|
||||
.name == "My Clock" and
|
||||
.barWidget.displayName == "My Clock" and
|
||||
.omarchy.clonedFrom == "omarchy.clock" and
|
||||
@@ -82,53 +82,53 @@ jq -e '
|
||||
' "$clock/manifest.json" >/dev/null || fail "clock clone manifest is incorrect"
|
||||
pass "clone updates identity without replacing the manifest"
|
||||
|
||||
grep -qx 'omarchy-plugin-enable local.clock' "$CALLS" ||
|
||||
grep -qx 'omarchy-plugin-enable tester.clock' "$CALLS" ||
|
||||
fail "clone does not enable the editable copy"
|
||||
grep -qx 'omarchy-notification-send -g Editing Cloned Plugin Original plugin has been replace by clone.' "$CALLS" ||
|
||||
fail "clone does not notify that the editable clone is active"
|
||||
pass "clone enables bar widgets and confirms the editable clone"
|
||||
|
||||
clone_plugin omarchy.keyboard-layout >/dev/null
|
||||
grep -qx 'omarchy-plugin-enable local.keyboard-layout' "$CALLS" ||
|
||||
grep -qx 'omarchy-plugin-enable tester.keyboard-layout' "$CALLS" ||
|
||||
fail "clone does not enable a clone of a legacy string-form bar entry"
|
||||
pass "clone enables clones of legacy string-form bar entries"
|
||||
|
||||
clone_plugin omarchy.menu >/dev/null
|
||||
menu="$TMPDIR/home/.config/omarchy/plugins/local.menu"
|
||||
menu="$TMPDIR/home/.config/omarchy/plugins/tester.menu"
|
||||
|
||||
for file in manifest.json Menu.qml MenuModel.js BarWidget.qml; do
|
||||
[[ -f $menu/$file ]] || fail "menu clone is missing $file"
|
||||
done
|
||||
jq -e '
|
||||
.id == "local.menu" and
|
||||
.id == "tester.menu" and
|
||||
.kinds == ["menu", "bar-widget"] and
|
||||
.entryPoints.menu == "Menu.qml" and
|
||||
.entryPoints.barWidget == "BarWidget.qml"
|
||||
' "$menu/manifest.json" >/dev/null || fail "menu clone loses plugin kinds"
|
||||
grep -qx 'omarchy-plugin-enable local.menu' "$CALLS" ||
|
||||
grep -qx 'omarchy-plugin-enable tester.menu' "$CALLS" ||
|
||||
fail "clone does not enable a multi-kind plugin"
|
||||
pass "clone preserves and enables multi-kind plugins"
|
||||
|
||||
remove_output=$(HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" PATH="$TMPDIR/bin:$ROOT/bin:$PATH" \
|
||||
FAKE_CALLS="$CALLS" OMARCHY_TEST_ROOT="$ROOT" \
|
||||
omarchy-plugin-remove local.menu --yes)
|
||||
grep -qx 'omarchy-shell shell setPluginEnabled local.menu false' "$CALLS" ||
|
||||
omarchy-plugin-remove tester.menu --yes)
|
||||
grep -qx 'omarchy-shell shell setPluginEnabled tester.menu false' "$CALLS" ||
|
||||
fail "removing an enabled clone does not disable it first"
|
||||
grep -q 'Restored omarchy.menu.' <<<"$remove_output" ||
|
||||
fail "removing a clone does not report its restored source"
|
||||
pass "removing an enabled clone goes through plugin disable and reports its source"
|
||||
|
||||
clone_plugin omarchy.active-window >/dev/null
|
||||
[[ -f $TMPDIR/home/.config/omarchy/plugins/local.active-window/ActiveWindow.qml ]] ||
|
||||
[[ -f $TMPDIR/home/.config/omarchy/plugins/tester.active-window/ActiveWindow.qml ]] ||
|
||||
fail "flat bar plugin clone is incomplete"
|
||||
pass "flat bar plugins clone from adjacent manifests"
|
||||
|
||||
grep -qx 'omarchy-plugin-enable local.active-window' "$CALLS" ||
|
||||
grep -qx 'omarchy-plugin-enable tester.active-window' "$CALLS" ||
|
||||
fail "clone does not activate a bar widget whose source is absent"
|
||||
pass "clone activates an absent bar widget"
|
||||
|
||||
clone_plugin omarchy.indicators >/dev/null
|
||||
indicators="$TMPDIR/home/.config/omarchy/plugins/local.indicators"
|
||||
indicators="$TMPDIR/home/.config/omarchy/plugins/tester.indicators"
|
||||
for file in Indicators.qml indicators/Dnd.qml indicators/Reminder.qml; do
|
||||
[[ -f $indicators/$file ]] || fail "indicators clone is missing $file"
|
||||
done
|
||||
@@ -137,20 +137,26 @@ grep -q 'Qt.resolvedUrl("indicators/"' "$indicators/Indicators.qml" ||
|
||||
pass "flat bar plugins declare extra clone dependencies"
|
||||
|
||||
clone_plugin omarchy.tray >/dev/null
|
||||
[[ -f $TMPDIR/home/.config/omarchy/plugins/local.tray/TrayModel.js ]] ||
|
||||
[[ -f $TMPDIR/home/.config/omarchy/plugins/tester.tray/TrayModel.js ]] ||
|
||||
fail "tray clone is missing its model"
|
||||
pass "flat bar plugins keep local script dependencies"
|
||||
|
||||
clone_plugin omarchy.bar >/dev/null
|
||||
grep -qx 'omarchy-plugin-enable local.bar' "$CALLS" ||
|
||||
grep -qx 'omarchy-plugin-enable tester.bar' "$CALLS" ||
|
||||
fail "clone does not select a cloned bar"
|
||||
pass "clone switches full bars"
|
||||
|
||||
clone_plugin omarchy.background >/dev/null
|
||||
grep -qx 'omarchy-plugin-enable local.background' "$CALLS" ||
|
||||
grep -qx 'omarchy-plugin-enable tester.background' "$CALLS" ||
|
||||
fail "clone does not enable an ordinary cloned plugin"
|
||||
pass "clone switches ordinary plugins"
|
||||
|
||||
EDITOR=fake-editor clone_plugin omarchy.weather --edit >/dev/null
|
||||
grep -qx "fake-editor $TMPDIR/home/.config/omarchy/plugins/tester.weather" "$CALLS" ||
|
||||
fail "clone --edit does not open the clone in EDITOR"
|
||||
pass "clone --edit opens the clone in EDITOR"
|
||||
rm -rf "$TMPDIR/home/.config/omarchy/plugins/tester.weather"
|
||||
|
||||
mkdir -p "$TMPDIR/home/.config/omarchy/plugins/acme.example"
|
||||
cat >"$TMPDIR/home/.config/omarchy/plugins/acme.example/manifest.json" <<'JSON'
|
||||
{"id":"acme.example","name":"Example","kinds":["bar-widget"],"entryPoints":{"barWidget":"Widget.qml"}}
|
||||
@@ -163,14 +169,14 @@ pass "clone is limited to built-in plugins"
|
||||
if clone_plugin omarchy.weather custom.weather >/dev/null 2>&1; then
|
||||
fail "clone accepts a custom id"
|
||||
fi
|
||||
[[ ! -e $TMPDIR/home/.config/omarchy/plugins/local.weather ]] ||
|
||||
[[ ! -e $TMPDIR/home/.config/omarchy/plugins/tester.weather ]] ||
|
||||
fail "rejected custom id leaves a clone behind"
|
||||
pass "clone derives the local id"
|
||||
pass "clone derives the personal id from the username"
|
||||
|
||||
if clone_plugin omarchy.weather --replace >/dev/null 2>&1; then
|
||||
fail "clone still accepts bar layout actions"
|
||||
fi
|
||||
[[ ! -e $TMPDIR/home/.config/omarchy/plugins/local.weather ]] ||
|
||||
[[ ! -e $TMPDIR/home/.config/omarchy/plugins/tester.weather ]] ||
|
||||
fail "rejected bar action leaves a clone behind"
|
||||
pass "clone does not accept manual switch options"
|
||||
|
||||
@@ -182,6 +188,6 @@ pass "clone requires an explicit source id"
|
||||
if FAKE_NO_DISCOVERY=1 clone_plugin omarchy.osd >/dev/null 2>&1; then
|
||||
fail "clone succeeds before the shell discovers it"
|
||||
fi
|
||||
[[ ! -e $TMPDIR/home/.config/omarchy/plugins/local.osd ]] ||
|
||||
[[ ! -e $TMPDIR/home/.config/omarchy/plugins/tester.osd ]] ||
|
||||
fail "failed clone discovery leaves a partial clone behind"
|
||||
pass "clone removes a partial clone when switching fails"
|
||||
|
||||
@@ -132,7 +132,7 @@ done
|
||||
jq -e '
|
||||
map(.id) as $ids |
|
||||
all(["omarchy.menu", "omarchy.notifications", "omarchy.clock", "omarchy.osd"][]; $ids | index(.)) and
|
||||
all(.[]; (.kinds | type == "array") and (.enabled | type == "boolean") and (.canDisable | type == "boolean") and (.firstParty | type == "boolean")) and
|
||||
all(.[]; (.kinds | type == "array") and (.enabled | type == "boolean") and (.canDisable | type == "boolean") and (.firstParty | type == "boolean") and (.clonedFrom | type == "string")) and
|
||||
([.[].name] == ([.[].name] | sort))
|
||||
' <<<"$plugins" >/dev/null || {
|
||||
printf 'Plugins:\n%s\n' "$plugins" | jq . >&2
|
||||
|
||||
Reference in New Issue
Block a user