Accept valid local main module paths

This commit is contained in:
2026-10-10 14:12:50 +00:00
parent c8eb64adec
commit 7eebbbbfc3
4 changed files with 57 additions and 2 deletions

View File

@@ -0,0 +1,44 @@
package main
import (
"bytes"
"context"
"path/filepath"
"strings"
"testing"
"gitea.maximumdirect.net/eric/ReleaseKit/cmd/releasekit/internal/cli"
)
func TestMainModuleWithoutDomainSupportsCheckBuildAndPageDelivery(t *testing.T) {
repository := newDeliveryBuildRepository(t)
writeRepositoryFile(t, repository, "go.mod", "module example\n\ngo 1.26.0\n")
cliGitRun(t, repository, "add", ".")
cliGitRun(t, repository, "commit", "-m", "Use local main module path")
state := &deliveryServerState{}
server := newDeliveryServer(t, state)
defer server.Close()
settings := cli.Settings{Product: "Example Product",
Build: &cli.BuildSettings{MainPackage: ".", BinaryName: "helper", Targets: []string{"linux/amd64"}},
Delivery: &cli.DeliverySettings{BaseURL: server.URL, Owner: "owner", Repository: "example"},
}
writeDeliveryProfile(t, repository, settings)
for _, args := range [][]string{
{"check", "--repo", repository, "v1.2.3"},
{"build", "--repo", repository, "--output", filepath.Join(t.TempDir(), "assets"), "v1.2.3"},
} {
var stdout, stderr bytes.Buffer
if status := run(context.Background(), args, &stdout, &stderr); status != 0 || !strings.Contains(stdout.String(), "module example version v1.2.3 tag v1.2.3") {
t.Fatalf("%s status=%d stdout=%s stderr=%s", args[0], status, stdout.String(), stderr.String())
}
}
settings.Build = nil
writeDeliveryProfile(t, repository, settings)
state.commit = cliGitOutput(t, repository, "rev-parse", "HEAD")
cliGitRun(t, repository, "tag", "v1.2.3")
t.Setenv("RELEASEKIT_GITEA_TOKEN", "fixture-token")
var stdout, stderr bytes.Buffer
if status := run(context.Background(), []string{"deliver", "--repo", repository, "v1.2.3"}, &stdout, &stderr); status != 0 || state.releaseCreates != 1 || state.assetUploads != 0 {
t.Fatalf("page delivery status=%d creates=%d uploads=%d stderr=%s", status, state.releaseCreates, state.assetUploads, stderr.String())
}
}

View File

@@ -195,7 +195,14 @@ and cancellation tests.
## Issue 6: Avoid requiring downloadable module paths for ordinary main modules (P2)
Status: open. Category: unrequested restriction.
Status: complete. Category: unrequested restriction.
**Completion:** Identity derivation uses Go import-path lexical validation and
retains path-major compatibility. A valid non-domain main module now completes
candidate checking, native standalone compilation, and hosted page-only delivery
against a local fixture. Qualified and local major-version derivation, missing
and malformed declarations, and incompatible majors pass their focused offline
regression tests.
**Evidence:** [`Derive`](../../internal/releaseidentity/identity.go) adds
`module.CheckPath`, including its requirement for a dot in the first path element.

View File

@@ -126,7 +126,7 @@ func Derive(selection Selection, declaration []byte, version string) (Identity,
return identity, fmt.Errorf("selected module declaration has no valid module directive")
}
identity.ModulePath = modulePath
if err := module.CheckPath(modulePath); err != nil {
if err := module.CheckImportPath(modulePath); err != nil {
return identity, fmt.Errorf("invalid module path %q: %w", modulePath, err)
}
_, pathMajor, ok := module.SplitPathVersion(modulePath)

View File

@@ -19,6 +19,8 @@ func TestDeriveUsesModuleDeclarationAndPhysicalLayout(t *testing.T) {
wantNote string
}{
{name: "root v1", subdir: ".", modulePath: "example.com/root", version: "v1.2.3", wantTag: "v1.2.3", wantNote: "docs/releases/v1.2.3.md"},
{name: "local main module", subdir: ".", modulePath: "example", version: "v1.2.3", wantTag: "v1.2.3", wantNote: "docs/releases/v1.2.3.md"},
{name: "local major module", subdir: "apps/local/v2", modulePath: "example/v2", version: "v2.3.4", wantTag: "apps/local/v2.3.4", wantNote: "apps/local/v2/docs/releases/v2.3.4.md"},
{name: "nested", subdir: "integrations/check", modulePath: "example.com/check", version: "v1.2.3", wantTag: "integrations/check/v1.2.3", wantNote: "integrations/check/docs/releases/v1.2.3.md"},
{name: "root major path", subdir: ".", modulePath: "example.com/root/v2", version: "v2.3.4", wantTag: "v2.3.4", wantNote: "docs/releases/v2.3.4.md"},
{name: "root physical major directory", subdir: "v2", modulePath: "example.com/root/v2", version: "v2.3.4", wantTag: "v2.3.4", wantNote: "v2/docs/releases/v2.3.4.md"},
@@ -52,6 +54,8 @@ func TestDeriveRejectsInvalidModuleAndVersionIdentity(t *testing.T) {
{name: "missing module directive", declaration: "go 1.26\n", version: "v1.2.3"},
{name: "malformed module path", declaration: "module example.com/../bad\n", version: "v1.2.3"},
{name: "incompatible major", declaration: "module example.com/service/v2\n", version: "v1.2.3"},
{name: "incompatible local major", declaration: "module example/v2\n", version: "v1.2.3"},
{name: "invalid local module path", declaration: "module example/../bad\n", version: "v1.2.3"},
{name: "unstable version", declaration: "module example.com/service\n", version: "v1.2.3-rc.1"},
} {
t.Run(tt.name, func(t *testing.T) {