Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,9 @@ zの関数は、関数名の階層とディレクトリ構成を対応させて
- `lib/a/process.zsh` のテストは `test/lib/a/process_test.zsh`
- `lib/a/b/process.zsh` のテストは `test/lib/a/b/process_test.zsh`
- `mod/a/b/operator.zsh` のテストは `test/mod/a/b/operator_test.zsh`

## 失敗処理

`|| return 1`は、コピー失敗後の切替防止や依存関係の循環検出など、失敗時に後続の処理を止める必要がある箇所に置いてください。削除・置換では操作対象の検証と復旧処理を維持し、通常の取得・計算では同じ条件の重複検証を整理してください。

引数取得と代入は、`z.arg.named ... && local ...`などの既存の書式に合わせてください。常に成功する値取得に`|| return 1`を追加する必要はありません。
2 changes: 0 additions & 2 deletions lib/common/is/operator.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ z.is.truthy() {
local value=$1

z.guard; {
z.arg.is.empty $@ && return 1
z.is.false $value && return 1
}

Expand Down Expand Up @@ -68,7 +67,6 @@ z.is.falsy() {
local value=$1

z.guard; {
z.arg.is.empty $@ && return 0
z.is.true $value && return 1
}

Expand Down
6 changes: 0 additions & 6 deletions lib/int/is/operator.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ z.int.is.eq() {
z.int.is.zero() {
local value=$1

z.int.is.match $value || return 1

z.is.eq $value 0
}

Expand All @@ -58,8 +56,6 @@ z.int.is.zero() {
z.int.is.positive() {
local value=$1

z.int.is.match $value || return 1

z.int.is.gt $value 0
}

Expand All @@ -74,8 +70,6 @@ z.int.is.positive() {
z.int.is.negative() {
local value=$1

z.int.is.match $value || return 1

z.int.is.lt $value 0
}

Expand Down
10 changes: 3 additions & 7 deletions lib/update/archive/process.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@
# example:
# z.update.archive._download dir=/tmp/update branch=main
z.update.archive._download() {
z.arg.named dir "$@" || { z.return; return 1; }
z.arg.named dir "$@"
local dir=$REPLY
z.dir.exists "$dir" || { z.return; return 1; }

z.arg.named branch "$@" default=main
local branch=$REPLY
z.is.null "$branch" && { z.return; return 1; }

local file="$dir/source.tar.gz"
z.file.exists "$file" && { z.return; return 1; }
Expand All @@ -26,8 +25,6 @@ z.update.archive._download() {
return 1
fi

z.file.exists "$file" || { z.return; return 1; }

z.return "$file"
}

Expand All @@ -41,15 +38,14 @@ z.update.archive._download() {
# example:
# z.update.archive._extract file=/tmp/source.tar.gz dir=/tmp/update/source
z.update.archive._extract() {
z.arg.named file "$@" || { z.return; return 1; }
z.arg.named file "$@"

local file=$REPLY

z.arg.named dir "$@" || { z.return; return 1; }
z.arg.named dir "$@"
local dir=$REPLY
z.is.null "$dir" && { z.return; return 1; }

z.file.exists "$file" || { z.return; return 1; }
z.dir.exists "$dir" && { z.return; return 1; }

z.dir.make path="$dir" || return 1
Expand Down
13 changes: 3 additions & 10 deletions lib/update/core/process.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,17 @@
# example:
# z.update.core._copy source=/tmp/source dir=/tmp/update/next
z.update.core._copy() {
z.arg.named source "$@" || return 1
z.arg.named source "$@"
local source_dir=$REPLY
z.dir.exists "$source_dir" || return 1

z.arg.named dir "$@" || return 1
z.arg.named dir "$@"
local dir=$REPLY
z.is.null "$dir" && return 1
z.dir.exists "$dir" && return 1

local core_files=(main.zsh install.zsh uninstall.zsh version.zsh help.zsh README.md)

for directory in lib test; do
z.dir.exists "$source_dir/$directory" || return 1
done

for core_file in "${core_files[@]}"; do
z.file.exists "$source_dir/$core_file" || return 1
done

z.dir.make path="$dir" || return 1

for entry in lib test "${core_files[@]}"; do
Expand Down
2 changes: 1 addition & 1 deletion lib/update/installation/is/operator.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# example:
# z.update.installation.is._valid dir=~/.z
z.update.installation.is._valid() {
z.arg.named dir "$@" || return 1
z.arg.named dir "$@"
local dir=$REPLY

z.is.null "$dir" && return 1
Expand Down
10 changes: 5 additions & 5 deletions lib/update/installation/process.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
# example:
# z.update.installation._replace dir=~/.z prepared=/tmp/next backup=/tmp/previous
z.update.installation._replace() {
z.arg.named dir "$@" || return 1
z.arg.named dir "$@"
local dir=$REPLY

z.arg.named prepared "$@" || return 1
z.arg.named prepared "$@"
local prepared=$REPLY

z.arg.named backup "$@" || return 1
z.arg.named backup "$@"
local backup=$REPLY

z.is.null "$backup" && return 1
Expand Down Expand Up @@ -45,15 +45,15 @@ z.update.installation._replace() {
# example:
# z.update.installation._reload dir=~/.z previous=$PWD
z.update.installation._reload() {
z.arg.named dir "$@" || return 1
z.arg.named dir "$@"
local dir=$REPLY
z.file.exists "$dir/main.zsh" || return 1

z.arg.named previous "$@" default="$PWD"
local previous_dir=$REPLY

if (( ${+functions[z.completion.cache._cancel]} )); then
z.completion.cache._cancel || return 1
z.completion.cache._cancel
fi

if z.is.eq "$previous_dir" "$dir" || z.str.start_with "$previous_dir" "$dir/"; then
Expand Down
2 changes: 1 addition & 1 deletion lib/update/mod/analysis.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# example:
# z.update.mod._resolve source=/tmp/source completion
z.update.mod._resolve() {
z.arg.named source "$@" || { z.return; return 1; }
z.arg.named source "$@"
local source_dir=$REPLY
z.dir.exists "$source_dir" || { z.return; return 1; }

Expand Down
10 changes: 3 additions & 7 deletions lib/update/mod/process.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
# example:
# z.update.mod._copy source=/tmp/source current=~/.z dir=/tmp/update/next job
z.update.mod._copy() {
z.arg.named source "$@" || return 1
z.arg.named source "$@"
local source_dir=$REPLY

z.arg.named current "$@" || return 1
z.arg.named current "$@"
local current_dir=$REPLY

z.arg.named dir "$@" || return 1
z.arg.named dir "$@"
local dir=$REPLY

z.dir.exists "$source_dir" || return 1
Expand All @@ -29,10 +29,6 @@ z.update.mod._copy() {
z.arg.named.shift dir "${(@)REPLY}"
local selected=(${(@)REPLY})

for mod_name in "${selected[@]}"; do
z.dir.exists "$source_dir/mod/$mod_name" || return 1
done

if z.dir.exists "$current_dir/mod"; then
z.dir.make path="$dir/mod" || return 1

Expand Down
2 changes: 1 addition & 1 deletion lib/update/process.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ z.update() {
# example:
# z.update._confirm dir=~/.z
z.update._confirm() {
z.arg.named dir "$@" || return 1
z.arg.named dir "$@"
local dir=$REPLY
z.is.null "$dir" && return 1

Expand Down
11 changes: 11 additions & 0 deletions test/lib/arg/process_test.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ z.t.describe "z.arg.named"; {
}
}

z.t.context "指定した名前の引数がない場合"; {
z.t.it "成功して空の値を返す"; {
z.arg.named name other=fuga
local result_code=$?
local result_reply=$REPLY

z.t.expect "$result_code" 0
z.t.expect "$result_reply" ""
}
}

z.t.context "defaultが指定されていて、値がない場合"; {
z.t.it "デフォルト値を返す"; {
z.arg.named name name="" other=fuga default=default_value
Expand Down
4 changes: 2 additions & 2 deletions test/lib/update/archive/process_test.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ z.t.describe "z.update.archive._extract"; {
}

z.t.context "file引数がない場合"; {
z.t.it "展開先を作らない"; {
z.update.archive._extract dir=/tmp/z_t/update_extract_absent
z.t.it "失敗して展開先を残さない"; {
z.update.archive._extract dir=/tmp/z_t/update_extract_absent 2>/dev/null
local extract_status=$?
local result=$REPLY

Expand Down
14 changes: 4 additions & 10 deletions test/lib/update/core/process_test.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -60,37 +60,31 @@ z.t.describe "z.update.core._copy"; {
}

z.t.context "配布元のtest directoryがない場合"; {
z.t.it "コピーを開始しない"; {
z.t.it "コピーの失敗を返す"; {
local dir=/tmp/z_t/update_core/missing_directory
z.dir.make path="$dir/source/lib"

z.update.core._copy source="$dir/source" dir="$dir/prepared"
z.update.core._copy source="$dir/source" dir="$dir/prepared" 2>/dev/null
local copy_status=$?

z.t.expect "$copy_status" 1

z.dir.not.exists "$dir/prepared"
z.t.expect.status.is.true

z.dir.remove path=/tmp/z_t/update_core
}
}

z.t.context "必須fileがない場合"; {
z.t.it "コピーを開始しない"; {
z.t.it "コピーの失敗を返す"; {
local dir=/tmp/z_t/update_core/missing_file
z.dir.make path="$dir/source/lib"
z.dir.make path="$dir/source/test"
z.file.write path="$dir/source/main.zsh" content=main

z.update.core._copy source="$dir/source" dir="$dir/prepared"
z.update.core._copy source="$dir/source" dir="$dir/prepared" 2>/dev/null
local copy_status=$?

z.t.expect "$copy_status" 1

z.dir.not.exists "$dir/prepared"
z.t.expect.status.is.true

z.dir.remove path=/tmp/z_t/update_core
}
}
Expand Down
22 changes: 15 additions & 7 deletions test/lib/update/installation/process_test.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -254,20 +254,28 @@ z.t.describe "z.update.installation._reload"; {
}
}

z.t.context "cancelが失敗した場合"; {
z.t.it "sourceを実行しない"; {
local dir=/tmp/z_t/update_reload/cancel_failure
z.t.context "補完jobが回収済みの場合"; {
z.t.it "IDを破棄して本体の再読込を続ける"; {
local dir=/tmp/z_t/update_reload/collected_job
local z_completion_cache_job_id=collected-job
z.dir.make path="$dir"
z.file.write path="$dir/main.zsh" content="touch \"$dir/loaded\""

z.t.mock name="z.completion.cache._cancel" behavior="return 1"
z.t.mock name="z.job.status" behavior="return 1"
z.t.mock name="z.completion.enable" behavior="return 0"

z.update.installation._reload dir="$dir"
() {
local Z_ROOT=$z_root

z.update.installation._reload dir="$dir"
}
local reload_status=$?
local remaining_id=$z_completion_cache_job_id

z.t.expect "$reload_status" 1
z.t.expect "$reload_status" 0
z.t.expect.is.null "$remaining_id"

z.file.not.exists "$dir/loaded"
z.file.exists "$dir/loaded"
z.t.expect.status.is.true

z.dir.remove path=/tmp/z_t/update_reload
Expand Down
7 changes: 2 additions & 5 deletions test/lib/update/mod/process_test.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -112,24 +112,21 @@ z.t.describe "z.update.mod._copy"; {
}

z.t.context "配布元に選択modがない場合"; {
z.t.it "既存と準備先を変更しない"; {
z.t.it "コピーの失敗を返して現行modを保持する"; {
local dir=/tmp/z_t/update_mod_copy/missing
z.dir.make path="$dir/current/mod/app"
z.dir.make path="$dir/source"
z.dir.make path="$dir/prepared"
z.file.write path="$dir/current/mod/app/value" content=original

z.update.mod._copy source="$dir/source" current="$dir/current" dir="$dir/prepared" missing
z.update.mod._copy source="$dir/source" current="$dir/current" dir="$dir/prepared" missing 2>/dev/null
local copy_status=$?

z.t.expect "$copy_status" 1

z.file.read path="$dir/current/mod/app/value"
z.t.expect.reply original

z.dir.not.exists "$dir/prepared/mod"
z.t.expect.status.is.true

z.dir.remove path=/tmp/z_t/update_mod_copy
}
}
Expand Down
Loading