gitnexus 1.6.4-rc.40 → 1.6.4-rc.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -66,7 +66,8 @@ export function resolvePythonImportTarget(parsedImport, workspaceIndex) {
|
|
|
66
66
|
* Precedence order:
|
|
67
67
|
* 1. Workspace-root direct hit (`<pathLike>.py`, `<pathLike>/__init__.py`).
|
|
68
68
|
* 2. Closest-ancestor match walking up from the importer's directory.
|
|
69
|
-
* 3. Suffix fallback (
|
|
69
|
+
* 3. Suffix fallback (deterministic: fewest path segments, then
|
|
70
|
+
* lexicographic on the normalized path).
|
|
70
71
|
*
|
|
71
72
|
* Root wins over ancestor by construction — if both `services/sync.py` and
|
|
72
73
|
* `backend/services/sync.py` exist, `backend/routers/cron.py`'s
|
|
@@ -104,18 +105,44 @@ function resolveAbsoluteFromFiles(pathLike, allFilePaths, fromFile) {
|
|
|
104
105
|
return candidatePkg;
|
|
105
106
|
}
|
|
106
107
|
}
|
|
107
|
-
//
|
|
108
|
-
//
|
|
108
|
+
// Suffix-match fallback (preserved for monorepo/nested-repo layouts
|
|
109
|
+
// that don't share a directory ancestor with the importer).
|
|
110
|
+
//
|
|
111
|
+
// Tie-break order when multiple files match the same suffix:
|
|
112
|
+
// 1. Fewest path segments (shorter, more canonical paths win — `lib/x.py`
|
|
113
|
+
// beats `tooling/extras/x.py`).
|
|
114
|
+
// 2. Lexicographic order over the normalized path (final stable
|
|
115
|
+
// tiebreak independent of file-set insertion order).
|
|
116
|
+
//
|
|
117
|
+
// Without an explicit tie-break the previous implementation returned
|
|
118
|
+
// the first match in `Set` iteration order, which depended on file
|
|
119
|
+
// ingestion order and produced non-deterministic edges across runs in
|
|
120
|
+
// multi-directory collision repos.
|
|
109
121
|
const suffixFile = `/${directFile}`;
|
|
110
122
|
const suffixPkg = `/${directPkg}`;
|
|
111
|
-
|
|
123
|
+
const matches = [];
|
|
112
124
|
for (const raw of allFilePaths) {
|
|
113
|
-
const
|
|
114
|
-
if (
|
|
115
|
-
|
|
125
|
+
const norm = raw.replace(/\\/g, '/');
|
|
126
|
+
if (norm.endsWith(suffixFile) || norm.endsWith(suffixPkg)) {
|
|
127
|
+
matches.push({ raw, norm });
|
|
116
128
|
}
|
|
117
129
|
}
|
|
118
|
-
|
|
130
|
+
if (matches.length === 0)
|
|
131
|
+
return null;
|
|
132
|
+
if (matches.length === 1)
|
|
133
|
+
return matches[0].raw;
|
|
134
|
+
matches.sort((a, b) => {
|
|
135
|
+
const aDepth = a.norm.split('/').length;
|
|
136
|
+
const bDepth = b.norm.split('/').length;
|
|
137
|
+
if (aDepth !== bDepth)
|
|
138
|
+
return aDepth - bDepth;
|
|
139
|
+
if (a.norm < b.norm)
|
|
140
|
+
return -1;
|
|
141
|
+
if (a.norm > b.norm)
|
|
142
|
+
return 1;
|
|
143
|
+
return 0;
|
|
144
|
+
});
|
|
145
|
+
return matches[0].raw;
|
|
119
146
|
}
|
|
120
147
|
/**
|
|
121
148
|
* Does the repo contain a module/package named `leadingSegment` somewhere
|
package/package.json
CHANGED