aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-05-19 18:05:39 +0900
committerOphestra <cat@gensokyo.uk>2026-05-19 18:10:11 +0900
commit3010a209b52c3103a1f2dea5442aa1e7428855b4 (patch)
treea05e7cb23b6982b6843f748fc82e591262a56326
parente65a3b435ca4a000a41ddbba68a07bf7c3036f06 (diff)
internal/rosa/azalea: pass through source ident
For source handle special case. Signed-off-by: Ophestra <cat@gensokyo.uk>
-rw-r--r--internal/rosa/azalea/evaluate.go25
-rw-r--r--internal/rosa/azalea/evaluate_test.go41
-rw-r--r--internal/rosa/state.go7
3 files changed, 62 insertions, 11 deletions
diff --git a/internal/rosa/azalea/evaluate.go b/internal/rosa/azalea/evaluate.go
index 063471e1..617a1618 100644
--- a/internal/rosa/azalea/evaluate.go
+++ b/internal/rosa/azalea/evaluate.go
@@ -142,10 +142,13 @@ var (
IdentInputs = unique.Make(Ident("inputs"))
// IdentRuntime has the same semantics as [IdentInputs].
IdentRuntime = unique.Make(Ident("runtime"))
+ // IdentSource is a special argument in a package declaration where an
+ // assignment of a [Val] with a single [Ident] passes through the evaluator.
+ IdentSource = unique.Make(Ident("source"))
- // ErrInvalidInputs is panicked for an [IdentInputs] argument to [PF]
- // sharing its value or set for R.
- ErrInvalidInputs = errors.New("inputs must not be common or bound to scope")
+ // ErrInvalidSpecial is panicked for a special [PF] argument sharing its
+ // value or set for R.
+ ErrInvalidSpecial = errors.New("special must not be common or bound to scope")
)
// evaluateAny implements [Evaluate].
@@ -291,7 +294,7 @@ func evaluateAny(d PF, s []Frame, expr, rp any) bool {
} {
if slices.Contains(names, special) {
if len(names) != 1 || len(arg.V) != 1 || arg.R {
- panic(ErrInvalidInputs)
+ panic(ErrInvalidSpecial)
}
farg.K = names[0]
if err := storeE(&farg.V, arg.V[0]); err != nil {
@@ -301,6 +304,20 @@ func evaluateAny(d PF, s []Frame, expr, rp any) bool {
continue args
}
}
+
+ if slices.Contains(names, IdentSource) {
+ if len(names) != 1 || len(arg.V) != 1 || arg.R {
+ panic(ErrInvalidSpecial)
+ }
+ if _, ok = arg.V[0].(Ident); ok {
+ farg.K = names[0]
+ if err := storeE(&farg.V, arg.V[0]); err != nil {
+ panic(err)
+ }
+ fargs = append(fargs, farg)
+ continue args
+ }
+ }
}
if !evaluateAny(d, s, arg.V, &farg.V) {
diff --git a/internal/rosa/azalea/evaluate_test.go b/internal/rosa/azalea/evaluate_test.go
index 26c4e668..b4fa4802 100644
--- a/internal/rosa/azalea/evaluate_test.go
+++ b/internal/rosa/azalea/evaluate_test.go
@@ -32,7 +32,7 @@ func TestEvaluate(t *testing.T) {
name string
data string
s []Frame
- want string
+ want any
err error
}{
{"apply unset", `f { v = unset; }`, makeStackCheck(func(
@@ -110,7 +110,7 @@ func TestEvaluate(t *testing.T) {
}, V: Val{Array(nil)}},
},
},
- Err: ErrInvalidInputs,
+ Err: ErrInvalidSpecial,
}},
{"bound inputs", `package name { inputs* = []; }`, nil, "", EvaluationError{
@@ -122,7 +122,7 @@ func TestEvaluate(t *testing.T) {
{K: []Ident{"inputs"}, V: Val{Array(nil)}, R: true},
},
},
- Err: ErrInvalidInputs,
+ Err: ErrInvalidSpecial,
}},
{"bound runtime", `package name { runtime* = []; }`, nil, "", EvaluationError{
@@ -134,7 +134,7 @@ func TestEvaluate(t *testing.T) {
{K: []Ident{"runtime"}, V: Val{Array(nil)}, R: true},
},
},
- Err: ErrInvalidInputs,
+ Err: ErrInvalidSpecial,
}},
{"concat inputs", `package name { inputs = ""+""; }`, nil, "", EvaluationError{
@@ -146,8 +146,24 @@ func TestEvaluate(t *testing.T) {
{K: []Ident{"inputs"}, V: Val{String(""), String("")}},
},
},
- Err: ErrInvalidInputs,
+ Err: ErrInvalidSpecial,
}},
+
+ {"concat source", `package name { source = ""+""; }`, nil, "", EvaluationError{
+ Expr: Func{
+ Ident: Ident("name"),
+ Package: true,
+
+ Args: []Arg{
+ {K: []Ident{"source"}, V: Val{String(""), String("")}},
+ },
+ },
+ Err: ErrInvalidSpecial,
+ }},
+
+ {"source handle", `package name { source = name; }`, nil, FArgs{
+ {K: unique.Make(Ident("source")), V: Ident("name")},
+ }, nil},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
@@ -161,12 +177,23 @@ func TestEvaluate(t *testing.T) {
} else {
expr = e[0].(Func)
}
- r, set, err := Evaluate[string](nil, tc.s, expr)
+ const rPackage = "\xff\xff\xff\xff"
+ r, set, err := Evaluate[string](func(
+ name Ident,
+ args FArgs,
+ ) (v any, set bool, err error) {
+ v = rPackage
+ if !reflect.DeepEqual(args, tc.want) {
+ err = fmt.Errorf("%#v, want %#v", args, tc.want)
+ }
+ set = true
+ return
+ }, tc.s, expr)
if set != (err == nil) {
t.Error("Evaluate: unexpected unset")
}
- if r != tc.want {
+ if r != rPackage && r != tc.want {
t.Errorf("Evaluate: %q, want %q", r, tc.want)
}
diff --git a/internal/rosa/state.go b/internal/rosa/state.go
index 388a6cc5..2581bb75 100644
--- a/internal/rosa/state.go
+++ b/internal/rosa/state.go
@@ -789,6 +789,13 @@ func (ctx *evalContext) pf(
case deferredGit:
source = ctx.t.newTagRemote(p.url, p.tag, p.checksum)
+ case azalea.Ident:
+ var _meta *Metadata
+ _meta, source = ctx.t.Load(H(string(p)))
+ if meta.Version == "" {
+ meta.Version = _meta.Version
+ }
+
default:
panic(azalea.TypeError{
Concrete: reflect.TypeOf(sourceA),