Skip to content

Instantly share code, notes, and snippets.

@heycalmdown heycalmdown/merger.js
Last active Nov 30, 2018

Embed
What would you like to do?
const inHousePackages = [
'@island/auth',
'@island/base',
'@island/garena',
'@island/gateway',
'@island/log',
'@island/mobile-tencent',
'@island/nexon-ngs',
'@island/nexon',
'@island/push',
'@island/session',
'@island/tencent',
'@island/worldchat',
'binary-jwt',
'consul-lb',
'distlock',
'dns-consul',
//'game-publisher',
//'game-publisher-nexon',
//'game-publisher-tencent',
'island',
//'island-base',
'island-di',
//'island-endpoint-tester',
'island-keeper',
'island-loggers',
'island-status-exporter',
'island-status-transfer',
'mongoose-transaction-plugin',
'redis-bluebird'
//'tencent-aas',
//'tencent-c4b',
//'tencent-dirapi',
//'tencent-itc',
//'tencent-oidbcomm',
//'tencent-sigapi',
//'tencent-tss'
];
const fs = require('fs');
const filename = process.argv[2];
if (filename !== 'package.json' && filename !== 'public/package.json') {
return;
}
const file = fs.readFileSync(filename, 'utf-8');
let lines = file.split('\n');
const offsets = { start: -1, mid: -1, end: -1 };
const chunks = { mine: null, theirs: null };
lines.forEach((line, i) => {
if (line.startsWith('<<<<<<<')) {
offsets.start = i;
} else if (line.startsWith('=======')) {
offsets.mid = i;
} else if (line.startsWith('>>>>>>>')) {
offsets.end = i;
chunks.mine = lines.slice(offsets.start + 1, offsets.mid);
chunks.theirs = lines.slice(offsets.mid + 1, offsets.end);
mergePackageJson(offsets, chunks);
}
});
updateDependencies();
fs.writeFileSync(filename, lines.filter(Boolean).join('\n') + '\n');
function mergePackageJson(offsets, chunks) {
chunks.mine.forEach((line, i) => {
if (line.indexOf('version') !== -1) {
chunks.theirs[i] = '';
return;
}
const matched = line.match(/"(.*)": "(.*)"/);
if (!matched) return;
const package = matched[1];
const semver = matched[2];
const version = (semver[0] === '^' || semver[1] === '~') && semver.slice(1) || semver;
if (isInHousePackage(line, true)) {
const j = whichLineIncludeSamePackage(chunks.theirs, line);
if (j !== -1) {
chunks.theirs[j] = '';
}
return;
}
const their = getTheirVersion(chunks.theirs, package);
if (!their) return;
if (0 <= compareVersions(version, their.version)) {
chunks.theirs[their.line] = '';
} else {
chunks.mine[i] = '';
}
});
chunks.theirs.forEach((line, i) => {
if (line.includes('"island-base"')) {
chunks.theirs[i] = '';
}
});
chunks.mine.forEach((line, i) => {
lines[convertLine(i, 'start')] = line;
});
chunks.theirs.forEach((line, i) => {
lines[convertLine(i, 'mid')] = line;
});
lines[offsets.start] = '';
lines[offsets.mid] = '';
lines[offsets.end] = '';
}
function updateDependencies() {
const packageJson = JSON.parse(lines.join(''));
const oldDeps = packageJson.dependencies;
const newDeps = packageJson.dependencies = {};
const depKeys = Object.keys(oldDeps);
depKeys.sort();
depKeys.forEach(d => {
if (d === 'island-base') {
newDeps[d] = 'http://git.sphd.io/island/island-base/repository/archive.tar.gz'
return;
}
if (isInHousePackage(d)) {
newDeps[d] = 'next';
return;
}
newDeps[d] = oldDeps[d];
});
const devDependencies = packageJson.devDependencies;
if (devDependencies) {
Object.keys(devDependencies).forEach(d => {
if (isInHousePackage(d)) {
devDependencies[d] = 'next';
}
});
}
lines = JSON.stringify(packageJson, null, 2).split('\n');
}
function convertLine(offset, type) {
return offset + offsets[type] + 1;
}
function isInHousePackage(line, exactWord = false) {
if (exactWord) {
return inHousePackages.some(p => line.includes(`"${p}"`));
}
return inHousePackages.includes(line);
}
function whichLineIncludeSamePackage(lines, package) {
const inhouse = inHousePackages.findIndex(o => package.includes(`"${o}"`));
if (inhouse === -1) return -1;
const inHousePackageName = inHousePackages[inhouse];
return lines.findIndex(o => o.includes(inHousePackageName));
}
function getTheirVersion(lines, package) {
const found = lines.findIndex(o => o.includes(package));
if (found === -1) return;
const line = lines[found];
const matched = line.match(/"(.*)": "(.*)"/);
if (!matched) return;
const result = {
line: found
};
const semver = matched[2];
result.version = (semver[0] === '^' || semver[1] === '~') && semver.slice(1) || semver;
return result;
}
function compareVersions(left, right) {
const leftDigits = left.split('.').map(Number);
const rightDigits = right.split('.').map(Number);
if (leftDigits[0] > rightDigits[0]) return 1;
if (leftDigits[0] < rightDigits[0]) return -1;
if (leftDigits[1] > rightDigits[1]) return 1;
if (leftDigits[1] < rightDigits[1]) return -1;
if (leftDigits[2] > rightDigits[2]) return 1;
if (leftDigits[2] < rightDigits[2]) return -1;
return 0;
}
// vim: sw=2 sts=2 ts=2 et
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.