openvibers/openvibe.shared Commits
Shared: pin-bump also moves README prose that names the old pinned version (#27)
Changes
@@@ -81,14 +81,24 @@ function refreshLock(dir, file) {}/**-- * STATUS.json's version fields and the README versions block follow the new pins (scripts/docs-status.js, plan D41):-- * the files docs-status rewrote are returned so they join the commit.++ * STATUS.json's version fields and the README versions block follow the new pins (scripts/docs-status.js, plan D41),++ * and so do README prose mentions of the old pinned versions ("`openvibe-sdk` v0.26.0", "openvibe-sdk v0.26.0"): only++ * the bumped library and only the versions it was pinned at, so a sentence about an older release elsewhere stays.++ * The files rewritten are returned so they join the commit.*/--function updateVersionLines(dir) {-- const before = Object.fromEntries(['STATUS.json', 'README.md'].filter((f) => fs.existsSync(path.join(dir, f)))-- .map((f) => [f, fs.readFileSync(path.join(dir, f), 'utf8')]));++function updateVersionLines(dir, library, from = [], tag = null) {++ const files = ['STATUS.json', 'README.md'].filter((f) => fs.existsSync(path.join(dir, f)));++ const before = Object.fromEntries(files.map((f) => [f, fs.readFileSync(path.join(dir, f), 'utf8')]));require('./docs-status').update(dir);-- return Object.keys(before).filter((f) => fs.readFileSync(path.join(dir, f), 'utf8') !== before[f]);++ const readme = path.join(dir, 'README.md');++ if (library && tag && from.length && fs.existsSync(readme)) {++ const olds = from.map((v) => v.replace(/^v/, '').replace(/\./g, '\\.')).join('|');++ const re = new RegExp(`(\`?${library}\`? v)(?:${olds})(?![0-9.]*[0-9])`, 'g');++ const text = fs.readFileSync(readme, 'utf8');++ const next = text.replace(re, `$1${tag.slice(1)}`);++ if (next !== text) fs.writeFileSync(readme, next);++ }++ return files.filter((f) => fs.readFileSync(path.join(dir, f), 'utf8') !== before[f]);}function repositories(only) {@@@ -126,8 +136,8 @@ function main() {const lock = refreshLock(dir, file);if (lock) changed.add(lock);}-- updateVersionLines(dir).forEach((f) => changed.add(f));const from = [...new Set(stale.flatMap((s) => s.from))].sort((a, b) => cmp(parse(a), parse(b)));++ updateVersionLines(dir, library, from, tag).forEach((f) => changed.add(f));const title = `${library} ${tag} (was ${from.join(', ')})`;if (!opts.apply) { summary.push(`${repo}: would open "${title}" changing ${[...changed].join(', ')}`); continue; }run('git', ['-C', dir, 'checkout', '-q', '-b', branch]);@@@ -16,8 +16,9 @@ write('apps/a/package.json', { dependencies: { 'openvibe-contracts': url('OpenViwrite('apps/b/package.json', { dependencies: { 'openvibe-contracts': url('OpenVibe.Contracts', 'v0.90.0') }, peerDependencies: { 'openvibe-shared': '>=2.0.0' } });write('node_modules/x/package.json', { dependencies: { 'openvibe-contracts': url('OpenVibe.Contracts', 'v0.1.0') } });write('STATUS.json', { repository: 'OpenVibers/Example', contracts: 'openvibe-contracts v0.110.0', sdk: 'openvibe-sdk v0.26.0', updated: '2026-01-01' });++write('README.md', '- `openvibe-contracts` v0.110.0, `openvibe-sdk` v0.26.0\n\nThe manifest was first released in openvibe-contracts v0.8.0.\n');cp.execFileSync('git', ['init', '-q', dir]);--cp.execFileSync('git', ['-C', dir, 'add', 'package.json', 'apps', 'STATUS.json']);++cp.execFileSync('git', ['-C', dir, 'add', 'package.json', 'apps', 'STATUS.json', 'README.md']);// Only tracked package.json files count, and only pins below the tag; a current pin and a range are left alone.const stale = stalePins(dir, 'openvibe-contracts', 'v0.112.0').map((s) => s.file).sort();@@@ -29,7 +30,10 @@ assert.deepStrictEqual(stalePins(dir, 'openvibe-shared', 'v2.13.0'), [], 'a peer// STATUS.json follows the pins once package.json moves.const pkg = path.join(dir, 'package.json');fs.writeFileSync(pkg, fs.readFileSync(pkg, 'utf8').replace(url('OpenVibe.Contracts', 'v0.110.0'), pinUrl('openvibe-contracts', 'v0.112.0')));--assert.deepStrictEqual(updateVersionLines(dir), ['STATUS.json']);++assert.deepStrictEqual(updateVersionLines(dir, 'openvibe-contracts', ['v0.110.0'], 'v0.112.0'), ['STATUS.json', 'README.md']);++const readme = fs.readFileSync(path.join(dir, 'README.md'), 'utf8');++assert.ok(readme.includes('`openvibe-contracts` v0.112.0, `openvibe-sdk` v0.26.0'), 'the pinned version in prose follows; the other library stays');++assert.ok(readme.includes('first released in openvibe-contracts v0.8.0'), 'a historical version is not a pin and stays');const status = JSON.parse(fs.readFileSync(path.join(dir, 'STATUS.json'), 'utf8'));assert.match(status.contracts, /v0\.112\.0/);assert.match(status.sdk, /v0\.26\.0/, 'the other library is untouched');
@@ -81,14 +81,24 @@ function refreshLock(dir, file) {
@@ -81,14 +81,24 @@ function refreshLock(dir, file) {
}
}
/**
/**
- * STATUS.json's version fields and the README versions block follow the new pins (scripts/docs-status.js, plan D41):
- * the files docs-status rewrote are returned so they join the commit.
+ * STATUS.json's version fields and the README versions block follow the new pins (scripts/docs-status.js, plan D41),
+ * and so do README prose mentions of the old pinned versions ("`openvibe-sdk` v0.26.0", "openvibe-sdk v0.26.0"): only
+ * the bumped library and only the versions it was pinned at, so a sentence about an older release elsewhere stays.
+ * The files rewritten are returned so they join the commit.
*/
*/
-function updateVersionLines(dir) {
- const before = Object.fromEntries(['STATUS.json', 'README.md'].filter((f) => fs.existsSync(path.join(dir, f)))
- .map((f) => [f, fs.readFileSync(path.join(dir, f), 'utf8')]));
+function updateVersionLines(dir, library, from = [], tag = null) {
+ const files = ['STATUS.json', 'README.md'].filter((f) => fs.existsSync(path.join(dir, f)));
+ const before = Object.fromEntries(files.map((f) => [f, fs.readFileSync(path.join(dir, f), 'utf8')]));
require('./docs-status').update(dir);
require('./docs-status').update(dir);
- return Object.keys(before).filter((f) => fs.readFileSync(path.join(dir, f), 'utf8') !== before[f]);
+ const readme = path.join(dir, 'README.md');
+ if (library && tag && from.length && fs.existsSync(readme)) {
+ const olds = from.map((v) => v.replace(/^v/, '').replace(/\./g, '\\.')).join('|');
+ const re = new RegExp(`(\`?${library}\`? v)(?:${olds})(?![0-9.]*[0-9])`, 'g');
+ const text = fs.readFileSync(readme, 'utf8');
+ const next = text.replace(re, `$1${tag.slice(1)}`);
+ if (next !== text) fs.writeFileSync(readme, next);
+ }
+ return files.filter((f) => fs.readFileSync(path.join(dir, f), 'utf8') !== before[f]);
}
}
function repositories(only) {
function repositories(only) {
@@ -126,8 +136,8 @@ function main() {
@@ -126,8 +136,8 @@ function main() {
const lock = refreshLock(dir, file);
const lock = refreshLock(dir, file);
if (lock) changed.add(lock);
if (lock) changed.add(lock);
}
}
- updateVersionLines(dir).forEach((f) => changed.add(f));
const from = [...new Set(stale.flatMap((s) => s.from))].sort((a, b) => cmp(parse(a), parse(b)));
const from = [...new Set(stale.flatMap((s) => s.from))].sort((a, b) => cmp(parse(a), parse(b)));
+ updateVersionLines(dir, library, from, tag).forEach((f) => changed.add(f));
const title = `${library} ${tag} (was ${from.join(', ')})`;
const title = `${library} ${tag} (was ${from.join(', ')})`;
if (!opts.apply) { summary.push(`${repo}: would open "${title}" changing ${[...changed].join(', ')}`); continue; }
if (!opts.apply) { summary.push(`${repo}: would open "${title}" changing ${[...changed].join(', ')}`); continue; }
run('git', ['-C', dir, 'checkout', '-q', '-b', branch]);
run('git', ['-C', dir, 'checkout', '-q', '-b', branch]);
@@ -16,8 +16,9 @@ write('apps/a/package.json', { dependencies: { 'openvibe-contracts': url('OpenVi
@@ -16,8 +16,9 @@ write('apps/a/package.json', { dependencies: { 'openvibe-contracts': url('OpenVi
write('apps/b/package.json', { dependencies: { 'openvibe-contracts': url('OpenVibe.Contracts', 'v0.90.0') }, peerDependencies: { 'openvibe-shared': '>=2.0.0' } });
write('apps/b/package.json', { dependencies: { 'openvibe-contracts': url('OpenVibe.Contracts', 'v0.90.0') }, peerDependencies: { 'openvibe-shared': '>=2.0.0' } });
write('node_modules/x/package.json', { dependencies: { 'openvibe-contracts': url('OpenVibe.Contracts', 'v0.1.0') } });
write('node_modules/x/package.json', { dependencies: { 'openvibe-contracts': url('OpenVibe.Contracts', 'v0.1.0') } });
write('STATUS.json', { repository: 'OpenVibers/Example', contracts: 'openvibe-contracts v0.110.0', sdk: 'openvibe-sdk v0.26.0', updated: '2026-01-01' });
write('STATUS.json', { repository: 'OpenVibers/Example', contracts: 'openvibe-contracts v0.110.0', sdk: 'openvibe-sdk v0.26.0', updated: '2026-01-01' });
+write('README.md', '- `openvibe-contracts` v0.110.0, `openvibe-sdk` v0.26.0\n\nThe manifest was first released in openvibe-contracts v0.8.0.\n');
cp.execFileSync('git', ['init', '-q', dir]);
cp.execFileSync('git', ['init', '-q', dir]);
-cp.execFileSync('git', ['-C', dir, 'add', 'package.json', 'apps', 'STATUS.json']);
+cp.execFileSync('git', ['-C', dir, 'add', 'package.json', 'apps', 'STATUS.json', 'README.md']);
// Only tracked package.json files count, and only pins below the tag; a current pin and a range are left alone.
// Only tracked package.json files count, and only pins below the tag; a current pin and a range are left alone.
const stale = stalePins(dir, 'openvibe-contracts', 'v0.112.0').map((s) => s.file).sort();
const stale = stalePins(dir, 'openvibe-contracts', 'v0.112.0').map((s) => s.file).sort();
@@ -29,7 +30,10 @@ assert.deepStrictEqual(stalePins(dir, 'openvibe-shared', 'v2.13.0'), [], 'a peer
@@ -29,7 +30,10 @@ assert.deepStrictEqual(stalePins(dir, 'openvibe-shared', 'v2.13.0'), [], 'a peer
// STATUS.json follows the pins once package.json moves.
// STATUS.json follows the pins once package.json moves.
const pkg = path.join(dir, 'package.json');
const pkg = path.join(dir, 'package.json');
fs.writeFileSync(pkg, fs.readFileSync(pkg, 'utf8').replace(url('OpenVibe.Contracts', 'v0.110.0'), pinUrl('openvibe-contracts', 'v0.112.0')));
fs.writeFileSync(pkg, fs.readFileSync(pkg, 'utf8').replace(url('OpenVibe.Contracts', 'v0.110.0'), pinUrl('openvibe-contracts', 'v0.112.0')));
-assert.deepStrictEqual(updateVersionLines(dir), ['STATUS.json']);
+assert.deepStrictEqual(updateVersionLines(dir, 'openvibe-contracts', ['v0.110.0'], 'v0.112.0'), ['STATUS.json', 'README.md']);
+const readme = fs.readFileSync(path.join(dir, 'README.md'), 'utf8');
+assert.ok(readme.includes('`openvibe-contracts` v0.112.0, `openvibe-sdk` v0.26.0'), 'the pinned version in prose follows; the other library stays');
+assert.ok(readme.includes('first released in openvibe-contracts v0.8.0'), 'a historical version is not a pin and stays');
const status = JSON.parse(fs.readFileSync(path.join(dir, 'STATUS.json'), 'utf8'));
const status = JSON.parse(fs.readFileSync(path.join(dir, 'STATUS.json'), 'utf8'));
assert.match(status.contracts, /v0\.112\.0/);
assert.match(status.contracts, /v0\.112\.0/);
assert.match(status.sdk, /v0\.26\.0/, 'the other library is untouched');
assert.match(status.sdk, /v0\.26\.0/, 'the other library is untouched');