ww: preserve command package identities
This commit is contained in:
@@ -638,6 +638,37 @@ sep_import_base_valid(const char *path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Go command packages retain their canonical import identity while declaring
|
||||
* package main. An external command-test variant declares main_test. These
|
||||
* declarations classify package kind but never participate in interning. */
|
||||
static int
|
||||
sep_command_declared_name(const struct seppkg *p)
|
||||
{
|
||||
return p->variant == SEP_VARIANT_EXTERNAL
|
||||
? strcmp(p->name, "main_test") == 0
|
||||
: strcmp(p->name, "main") == 0;
|
||||
}
|
||||
static int
|
||||
sep_forbidden_command_import(const struct sepgraph *g, int importer, int dep)
|
||||
{
|
||||
const struct seppkg *from = &g->pkg[importer];
|
||||
const struct seppkg *to = &g->pkg[dep];
|
||||
if (strcmp(to->name, "main") != 0 || to->role != SEP_ROLE_NORMAL)
|
||||
return 0;
|
||||
/* An external test's exact import of its colocated command production is
|
||||
* test-variant wiring, not a general source-importable command edge. */
|
||||
return !(from->variant == SEP_VARIANT_EXTERNAL
|
||||
&& sep_command_declared_name(from)
|
||||
&& strcmp(from->canon, to->canon) == 0);
|
||||
}
|
||||
|
||||
static int
|
||||
sep_command_compiler_marker(const struct sepgraph *g, int pi)
|
||||
{
|
||||
return sep_command_declared_name(&g->pkg[pi])
|
||||
&& !g->pkg[pi].link_entry;
|
||||
}
|
||||
|
||||
/* Bind the canonical ordinary import identity of one provisional directory
|
||||
* action. The action's compiler path is derived from that base and its semantic
|
||||
* variant; neither requested-root state nor artifact naming participates. */
|
||||
@@ -1223,7 +1254,9 @@ sep_scan_file(struct sepgraph *g, int pi, const char *file,
|
||||
}
|
||||
int self = strcmp(canon, g->pkg[pi].canon) == 0;
|
||||
free(canon);
|
||||
if (self && sep_external_production_name(&g->pkg[pi], name, 1))
|
||||
if (self
|
||||
&& (sep_external_production_name(&g->pkg[pi], name, 1)
|
||||
|| sep_command_declared_name(&g->pkg[pi])))
|
||||
external_production = 1;
|
||||
if (self && !external_production) {
|
||||
const char *owner = g->pkg[pi].path[0]
|
||||
@@ -1409,7 +1442,8 @@ sep_load_pkg(struct sepgraph *g, int pi, int context)
|
||||
&& !g->pkg[pi].test_support) {
|
||||
const char *dot = strrchr(g->pkg[pi].path, '.');
|
||||
const char *leaf = dot ? dot + 1 : g->pkg[pi].path;
|
||||
if (strcmp(g->pkg[pi].name, leaf) != 0) {
|
||||
if (strcmp(g->pkg[pi].name, leaf) != 0
|
||||
&& !sep_command_declared_name(&g->pkg[pi])) {
|
||||
fprintf(stderr,
|
||||
"ww: package %s does not match import path %s\n",
|
||||
g->pkg[pi].name, g->pkg[pi].path);
|
||||
@@ -1461,11 +1495,20 @@ sep_load_pkg(struct sepgraph *g, int pi, int context)
|
||||
/* Mark before recursion so a source cycle terminates here; topo emits the
|
||||
* stable cycle diagnostic after all direct bindings are known. */
|
||||
g->pkg[pi].context_state[context] = 2;
|
||||
for (int k = 0; k < g->pkg[pi].ndeps; k++)
|
||||
if (sep_load_pkg(g, g->pkg[pi].deps[k], context) < 0) {
|
||||
for (int k = 0; k < g->pkg[pi].ndeps; k++) {
|
||||
int dep = g->pkg[pi].deps[k];
|
||||
if (sep_load_pkg(g, dep, context) < 0) {
|
||||
g->pkg[pi].failed = 1;
|
||||
return -1;
|
||||
}
|
||||
if (dep != pi && sep_forbidden_command_import(g, pi, dep)) {
|
||||
fprintf(stderr,
|
||||
"ww: package %s is a program, not an importable package\n",
|
||||
g->pkg[dep].path[0] ? g->pkg[dep].path : g->pkg[dep].canon);
|
||||
g->pkg[pi].failed = 1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1677,7 +1720,8 @@ sep_finalize_directory_identities(struct sepgraph *g)
|
||||
int support_alias = p->role == SEP_ROLE_TEST_SUPPORT
|
||||
&& strcmp(p->path, SEP_TEST_SUPPORT_MODULE) == 0
|
||||
&& strcmp(p->name, "test") == 0;
|
||||
if (!support_alias && strcmp(p->name, leaf) != 0) {
|
||||
if (!support_alias && strcmp(p->name, leaf) != 0
|
||||
&& !sep_command_declared_name(p)) {
|
||||
fprintf(stderr, "ww: package %s does not match import path %s\n",
|
||||
p->name, p->path);
|
||||
return -1;
|
||||
@@ -2437,6 +2481,8 @@ build_one_sep_impl(const char *src, int entry_is_dir,
|
||||
if (g->pkg[pi].variant == SEP_VARIANT_SAME_TEST
|
||||
|| g->pkg[pi].variant == SEP_VARIANT_EXTERNAL)
|
||||
cargv[cpos++] = "--test-package";
|
||||
if (sep_command_compiler_marker(g, pi))
|
||||
cargv[cpos++] = "--command-package";
|
||||
if (g->pkg[pi].link_entry)
|
||||
cargv[cpos++] = "--entry";
|
||||
if (g->pkg[pi].test_support) {
|
||||
|
||||
Reference in New Issue
Block a user