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
47 changes: 34 additions & 13 deletions .pnpmfile.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,19 @@ function resolveCacheDir(workspaceRoot, cacheDir) {
return resolvedCacheDir;
}

function isAnyLocalFamilyEnabled() {
return Object.values(STANDARD_FAMILIES).some((family) => process.env[family.envFlag] === 'true');
function packedManifestExists(cacheDir, familyKey) {
return fs.existsSync(path.join(cacheDir, `${familyKey}.json`));
}

function resolveFamilyActivation(family, familyKey, cacheDir) {
const flag = process.env[family.envFlag];
if (flag === 'true') {
return { active: true, packedOnly: false };
}
if (flag === 'false') {
return { active: false, packedOnly: false };
}
return { active: packedManifestExists(cacheDir, familyKey), packedOnly: true };
}

function readProjectConfig(workspaceRoot) {
Expand Down Expand Up @@ -188,7 +199,7 @@ function readPackedManifest(cacheDir, familyKey) {
}
}

function rewriteDependencies(pkg, context, cacheDir, familyKey, family) {
function rewriteDependencies(pkg, context, cacheDir, familyKey, family, packedOnly) {
const packedPackages = readPackedManifest(cacheDir, familyKey);
const workspaceRoot = __dirname;

Expand All @@ -205,6 +216,10 @@ function rewriteDependencies(pkg, context, cacheDir, familyKey, family) {
continue;
}

if (packedOnly) {
continue;
}

const absolutePath = resolvePackageDirectory(workspaceRoot, family, npmName, packagePath);
pkg[depType][npmName] = `file:${absolutePath}`;
context.log(`[local-dev] ${npmName} → ${absolutePath}`);
Expand Down Expand Up @@ -232,12 +247,10 @@ function allowAdapterPrereleases(pkg) {
continue;
const m = range.match(/^\^(\d+)\.(\d+)\.(\d+)$/);
if (!m) continue;
const maj = Number(m[1]), min = Number(m[2]), pat = Number(m[3]);
const upper = maj > 0
? `${maj + 1}.0.0`
: min > 0
? `0.${min + 1}.0`
: `0.0.${pat + 1}`;
const maj = Number(m[1]),
min = Number(m[2]),
pat = Number(m[3]);
const upper = maj > 0 ? `${maj + 1}.0.0` : min > 0 ? `0.${min + 1}.0` : `0.0.${pat + 1}`;
pkg[depType][name] = `>=${maj}.${min}.${pat}-0 <${upper}`;
}
}
Expand Down Expand Up @@ -366,16 +379,24 @@ function readPackage(pkg, context) {

stripMetaMaskDependencies(pkg, context);

if (isAnyLocalFamilyEnabled()) {
const workspaceRoot = __dirname;
const workspaceRoot = __dirname;
if (fs.existsSync(path.join(workspaceRoot, CONFIG_FILE))) {
const projectConfig = readProjectConfig(workspaceRoot);

for (const [familyKey, family] of Object.entries(projectConfig.families)) {
if (process.env[family.envFlag] !== 'true') {
const activation = resolveFamilyActivation(family, familyKey, projectConfig.cacheDir);
if (!activation.active) {
continue;
}

rewriteDependencies(pkg, context, projectConfig.cacheDir, familyKey, family);
rewriteDependencies(
pkg,
context,
projectConfig.cacheDir,
familyKey,
family,
activation.packedOnly
);
}
}

Expand Down
141 changes: 104 additions & 37 deletions .pnpmfile.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -122,19 +122,41 @@ function withPackedManifest(familyKey, packages, fn) {
}
}

function withoutPackedManifest(familyKey, fn) {
const manifestPath = getPackedManifestPath(familyKey);
const previous = fs.existsSync(manifestPath) ? fs.readFileSync(manifestPath, 'utf8') : null;

if (previous !== null) {
fs.unlinkSync(manifestPath);
}

try {
return fn();
} finally {
if (previous !== null) {
fs.mkdirSync(path.dirname(manifestPath), { recursive: true });
fs.writeFileSync(manifestPath, previous);
}
}
}

test('rewrites both UI and adapter dependencies during dev:local flows', () => {
const uiRepo = createUiRepo('role-manager-ui');
const adaptersRepo = createAdaptersRepo('role-manager-adapters');
const { hooks } = loadHook();

const updated = withEnv(
{
LOCAL_UI: 'true',
LOCAL_ADAPTERS: 'true',
LOCAL_UI_PATH: uiRepo,
LOCAL_ADAPTERS_PATH: adaptersRepo,
},
() => hooks.readPackage(createPackage(), { dir: process.cwd(), log: () => {} })
const updated = withoutPackedManifest('ui', () =>
withoutPackedManifest('adapters', () =>
withEnv(
{
LOCAL_UI: 'true',
LOCAL_ADAPTERS: 'true',
LOCAL_UI_PATH: uiRepo,
LOCAL_ADAPTERS_PATH: adaptersRepo,
},
() => hooks.readPackage(createPackage(), { dir: process.cwd(), log: () => {} })
)
)
);

assert.equal(
Expand All @@ -155,13 +177,15 @@ test('supports adapter-only overrides with LOCAL_ADAPTERS_PATH', () => {
const preferredRepo = createAdaptersRepo('role-manager-adapters-preferred');
const { hooks } = loadHook();

const updated = withEnv(
{
LOCAL_UI: undefined,
LOCAL_ADAPTERS: 'true',
LOCAL_ADAPTERS_PATH: preferredRepo,
},
() => hooks.readPackage(createPackage(), { dir: process.cwd(), log: () => {} })
const updated = withoutPackedManifest('adapters', () =>
withEnv(
{
LOCAL_UI: undefined,
LOCAL_ADAPTERS: 'true',
LOCAL_ADAPTERS_PATH: preferredRepo,
},
() => hooks.readPackage(createPackage(), { dir: process.cwd(), log: () => {} })
)
);

assert.equal(
Expand All @@ -180,12 +204,14 @@ test('throws a clear error when the adapter checkout path is invalid', () => {

assert.throws(
() =>
withEnv(
{
LOCAL_ADAPTERS: 'true',
LOCAL_ADAPTERS_PATH: missingRepo,
},
() => hooks.readPackage(createPackage(), { dir: process.cwd(), log: () => {} })
withoutPackedManifest('adapters', () =>
withEnv(
{
LOCAL_ADAPTERS: 'true',
LOCAL_ADAPTERS_PATH: missingRepo,
},
() => hooks.readPackage(createPackage(), { dir: process.cwd(), log: () => {} })
)
),
(error) => {
assert.match(error.message, /openzeppelin-adapters checkout not found/);
Expand Down Expand Up @@ -220,6 +246,43 @@ test('prefers packed local tarballs when a manifest is present', () => {
);
});

test('keeps packed local packages active for incidental installs', () => {
const tarballDir = createTemporaryDirectory('role-manager-packed-ui-');
const tarballPath = path.join(tarballDir, 'openzeppelin-ui-components-1.0.0.tgz');
fs.writeFileSync(tarballPath, 'stub tarball');
const { hooks } = loadHook();

const updated = withPackedManifest('ui', { '@openzeppelin/ui-components': tarballPath }, () =>
withEnv(
{
LOCAL_UI: undefined,
LOCAL_UI_PATH: undefined,
},
() => hooks.readPackage(createPackage(), { dir: process.cwd(), log: () => {} })
)
);

assert.equal(updated.dependencies['@openzeppelin/ui-components'], `file:${tarballPath}`);
});

test('explicit remote mode disables a packed local manifest', () => {
const tarballDir = createTemporaryDirectory('role-manager-packed-ui-remote-');
const tarballPath = path.join(tarballDir, 'openzeppelin-ui-components-1.0.0.tgz');
fs.writeFileSync(tarballPath, 'stub tarball');
const { hooks } = loadHook();

const updated = withPackedManifest('ui', { '@openzeppelin/ui-components': tarballPath }, () =>
withEnv(
{
LOCAL_UI: 'false',
},
() => hooks.readPackage(createPackage(), { dir: process.cwd(), log: () => {} })
)
);

assert.equal(updated.dependencies['@openzeppelin/ui-components'], '^1.0.0');
});

test('throws a clear error when a configured package directory is missing package.json', () => {
const adaptersRepo = createTemporaryDirectory('role-manager-adapters-missing-package-json-');
const vitePackageRoot = path.join(adaptersRepo, 'packages', 'adapters-vite');
Expand All @@ -233,12 +296,14 @@ test('throws a clear error when a configured package directory is missing packag

assert.throws(
() =>
withEnv(
{
LOCAL_ADAPTERS: 'true',
LOCAL_ADAPTERS_PATH: adaptersRepo,
},
() => hooks.readPackage(createPackage(), { dir: process.cwd(), log: () => {} })
withoutPackedManifest('adapters', () =>
withEnv(
{
LOCAL_ADAPTERS: 'true',
LOCAL_ADAPTERS_PATH: adaptersRepo,
},
() => hooks.readPackage(createPackage(), { dir: process.cwd(), log: () => {} })
)
),
(error) => {
assert.match(error.message, /package\.json/);
Expand Down Expand Up @@ -379,16 +444,18 @@ test('canonicalizes symlinked repository roots before rewriting file dependencie
const logs = [];
const { hooks } = loadHook();

const pkg = withEnv(
{
LOCAL_ADAPTERS: 'true',
LOCAL_ADAPTERS_PATH: symlinkRepo,
},
() =>
hooks.readPackage(createPackage(), {
dir: process.cwd(),
log: (message) => logs.push(message),
})
const pkg = withoutPackedManifest('adapters', () =>
withEnv(
{
LOCAL_ADAPTERS: 'true',
LOCAL_ADAPTERS_PATH: symlinkRepo,
},
() =>
hooks.readPackage(createPackage(), {
dir: process.cwd(),
log: (message) => logs.push(message),
})
)
);

const canonicalPackageRoot = fs.realpathSync(path.join(actualRepo, 'packages', 'adapter-evm'));
Expand Down
2 changes: 1 addition & 1 deletion apps/role-manager/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"@openzeppelin/adapter-evm": "^5.0.0",
"@openzeppelin/adapter-polkadot": "^5.0.0",
"@openzeppelin/adapter-stellar": "^4.0.1",
"@openzeppelin/ui-components": "^3.8.3",
"@openzeppelin/ui-components": "3.12.0",
"@openzeppelin/ui-react": "^3.3.2",
"@openzeppelin/ui-renderer": "^3.4.2",
"@openzeppelin/ui-storage": "^1.2.5",
Expand Down

This file was deleted.

Loading
Loading