This commit is contained in:
Ken 2019-01-21 11:56:16 -08:00
Родитель 42065a394d
Коммит 9700d576b7
9 изменённых файлов: 148 добавлений и 55 удалений

Просмотреть файл

@ -1,8 +1,10 @@
import { task, option } from 'just-task'; import { task, option } from 'just-task';
import { addPackageTask } from '../tasks/addPackageTask'; import { addPackageTask } from '../tasks/addPackageTask';
import { upgradeRepoTask } from '../tasks/upgradeRepoTask';
module.exports = function() { module.exports = function() {
option('cwd'); option('cwd');
option('name'); option('name');
task('add-package', addPackageTask); task('add-package', addPackageTask);
task('upgrade-repo', upgradeRepoTask);
}; };

Просмотреть файл

@ -0,0 +1,31 @@
import { paths } from 'just-scripts-utils';
import path from 'path';
import fse from 'fs-extra';
export function findMonoRepoRootPath() {
const { installPath } = paths;
let found = false;
let currentPath = installPath;
const { root } = path.parse(installPath);
while (!found && currentPath !== root) {
const packageJsonFile = path.join(currentPath, 'package.json');
const rushConfigFile = path.join(currentPath, 'rush.json');
// Determine the monorepo by either presence of rush.json or package.json that has a just.stack of just-stack-monorepo
if (fse.existsSync(rushConfigFile)) {
return currentPath;
} else if (fse.existsSync(packageJsonFile)) {
const packageJson = fse.readJsonSync(packageJsonFile);
const stack = packageJson.just && packageJson.just.stack;
if (stack === 'just-stack-monorepo') {
return currentPath;
}
}
currentPath = path.dirname(currentPath);
}
return null;
}

Просмотреть файл

@ -0,0 +1,37 @@
import semver from 'semver';
/**
* Merges an incoming package.json with an original semantically
* - merges dependencies and devDependencies for ranges that look like "^x.y.z" or "~x.y.z" or "x.y.z"
*
* @param original
* @param incoming
*/
export function mergePackageJson(original: any, incoming: any) {
const newPackageJson = { ...original };
if (original.just) {
const depTypes = ['dependencies', 'devDependencies'];
let packageJsonModified = false;
depTypes.forEach(devType => {
if (incoming[devType]) {
Object.keys(incoming[devType]).forEach(dep => {
const strippedOriginalVersion = original[devType][dep] ? original[devType][dep].replace(/^[~^]/, '') : '0.0.0';
const strippedIncomingVersion = incoming[devType][dep].replace(/^[~^]/, '');
// Modify the version if the range is comparable and is greater (skip mod if any space, >, < or = characters are present)
if (semver.gt(strippedIncomingVersion, strippedOriginalVersion) && !incoming[devType][dep].match(/[\s<>=]/)) {
newPackageJson[devType][dep] = incoming[devType][dep];
packageJsonModified = true;
}
});
}
});
if (packageJsonModified) {
return newPackageJson;
}
}
return original;
}

Просмотреть файл

@ -3,13 +3,11 @@ import { paths, logger, transform, rushAddPackage, rushUpdate, prettyPrintMarkdo
import prompts from 'prompts'; import prompts from 'prompts';
import fse from 'fs-extra'; import fse from 'fs-extra';
import { argv } from 'just-task'; import { argv } from 'just-task';
import { findMonoRepoRootPath } from '../package/findMonoRepoRootPath';
export async function addPackageTask() { export async function addPackageTask() {
const args = argv(); const args = argv();
const rootPath = findMonoRepoRootPath();
if (args.cwd) {
process.chdir(args.cwd);
}
const name = const name =
args.name || args.name ||
@ -21,38 +19,40 @@ export async function addPackageTask() {
logger.info(`Creating a package called: ${name}`); logger.info(`Creating a package called: ${name}`);
const { installPath } = paths; if (rootPath) {
// TODO: do validation that the path is indeed a monorepo
// TODO: do validation that the path is indeed a monorepo // TODO: autosuggest just-stack-* packages from npmjs.org
let response = await prompts({
// TODO: autosuggest just-stack-* packages from npmjs.org type: 'select',
let response = await prompts({ name: 'type',
type: 'select', message: 'What type of package to add to the repo?',
name: 'type', choices: [
message: 'What type of package to add to the repo?', { title: 'Library', value: 'just-stack-single-lib' },
choices: [ { title: 'UI Fabric Web Application (React)', value: 'just-stack-uifabric' }
{ title: 'Library', value: 'just-stack-single-lib' }, ]
{ title: 'UI Fabric Web Application (React)', value: 'just-stack-uifabric' }
]
});
const packagePath = path.join(installPath, 'packages', name);
const templatePath = await downloadPackage(response.type);
if (templatePath) {
transform(templatePath, packagePath, {
name
}); });
rushAddPackage(name, installPath); const packagePath = path.join(rootPath, 'packages', name);
logger.info('Running rush update'); const templatePath = await downloadPackage(response.type);
rushUpdate(installPath);
logger.info('All Set!'); if (templatePath) {
transform(templatePath, packagePath, {
name
});
const readmeFile = path.join(packagePath, 'README.md'); rushAddPackage(name, rootPath);
if (fse.existsSync(readmeFile)) { logger.info('Running rush update');
logger.info('\n' + prettyPrintMarkdown(fse.readFileSync(readmeFile).toString())); rushUpdate(rootPath);
logger.info('All Set!');
const readmeFile = path.join(packagePath, 'README.md');
if (fse.existsSync(readmeFile)) {
logger.info('\n' + prettyPrintMarkdown(fse.readFileSync(readmeFile).toString()));
}
} }
} else {
logger.warn('Cannot determine the root path to the mono repo');
} }
} }

Просмотреть файл

@ -0,0 +1,20 @@
import fse from 'fs-extra';
import path from 'path';
import { upgradeStackPackageJsonFile } from './upgradeStackTask';
import { findMonoRepoRootPath } from '../package/findMonoRepoRootPath';
export async function upgradeRepoTask() {
const rootPath = findMonoRepoRootPath();
if (rootPath) {
process.chdir(rootPath);
const rushConfig = fse.readJsonSync(path.join(rootPath, 'rush.json'));
// uses Array.reduce to sequentially loop through promise
rushConfig.projects.reduce(async (previousPromise: Promise<void>, project: any) => {
await previousPromise;
const projectPath = path.join(rootPath, project.projectFolder);
return upgradeStackPackageJsonFile(projectPath);
}, Promise.resolve());
}
}

Просмотреть файл

@ -1,13 +1,19 @@
import fse from 'fs-extra'; import fse from 'fs-extra';
import path from 'path'; import path from 'path';
import semver from 'semver'; import chalk from 'chalk';
import { logger } from 'just-task'; import { logger } from 'just-task';
import { paths, downloadPackage, transform } from 'just-scripts-utils'; import { paths, downloadPackage, transform } from 'just-scripts-utils';
import { mergePackageJson } from '../package/mergePackageJson';
export async function upgradeStackTask() { export function upgradeStackTask() {
const { installPath, tempPath } = paths; const { installPath } = paths;
const packageJsonFile = path.join(installPath, 'package.json'); return upgradeStackPackageJsonFile(installPath);
}
export async function upgradeStackPackageJsonFile(projectPath: string) {
const packageJsonFile = path.join(projectPath, 'package.json');
const packageJson = fse.readJsonSync(packageJsonFile); const packageJson = fse.readJsonSync(packageJsonFile);
const { tempPath } = paths;
if (packageJson.just) { if (packageJson.just) {
const stack = packageJson.just.stack; const stack = packageJson.just.stack;
@ -16,32 +22,24 @@ export async function upgradeStackTask() {
if (stackPath) { if (stackPath) {
const templatePath = tempPath(packageJson.name); const templatePath = tempPath(packageJson.name);
transform(stackPath, templatePath, { name: packageJson.name }); transform(stackPath, templatePath, { name: packageJson.name });
// Update package.json deps // Update package.json deps
const stackPackageJson = fse.readJsonSync(path.join(templatePath, 'package.json')); const stackPackageJson = fse.readJsonSync(path.join(templatePath, 'package.json'));
const depTypes = ['dependencies', 'devDependencies'];
let packageJsonModified = false;
depTypes.forEach(devType => {
if (stackPackageJson[devType]) {
Object.keys(stackPackageJson[devType]).forEach(dep => {
const strippedPackageVersion = packageJson[devType][dep] ? packageJson[devType][dep].replace(/^[~^]/, '') : '0.0.0';
const strippedStackPackageVersion = stackPackageJson[devType][dep].replace(/^[~^]/, '');
if (semver.gt(strippedStackPackageVersion, strippedPackageVersion)) { // If modified, the reference would be different
logger.info(`Dependency ${dep} should be updated to ${stackPackageJson[devType][dep]}`); const newPackageJson = mergePackageJson(packageJson, stackPackageJson);
packageJson[devType][dep] = stackPackageJson[devType][dep];
packageJsonModified = true;
}
});
}
});
if (packageJsonModified) { logger.info(`Checking if package ${packageJson.name} should be upgraded...`);
fse.writeFileSync(packageJsonFile, JSON.stringify(packageJson, null, 2)); if (newPackageJson !== packageJson) {
logger.info(`Package ${chalk.cyan(packageJson.name)} is being upgraded.`);
fse.writeFileSync(packageJsonFile, JSON.stringify(newPackageJson, null, 2));
} else {
logger.info(`Package ${chalk.cyan(packageJson.name)} upgrade not needed.`);
} }
} else { } else {
logger.error(`Cannot read or retrieve the stack package.json for ${stack}`); logger.error(`Cannot read or retrieve the stack package.json for ${stack}`);
} }
} else { } else {
logger.info(`Package ${packageJson} does not have a "just" key. Not self-upgradeable through this task.`); logger.info(`Package ${chalk.cyan(packageJson.name)} does not have a "just" key. Skipping upgrade.`);
} }
} }

Просмотреть файл

@ -9,7 +9,8 @@
"test": "node common/scripts/install-run-rush.js test", "test": "node common/scripts/install-run-rush.js test",
"update": "node common/scripts/install-run-rush.js update", "update": "node common/scripts/install-run-rush.js update",
"postinstall": "node common/scripts/install-run-rush.js install", "postinstall": "node common/scripts/install-run-rush.js install",
"add-package": "cd scripts && npm run add-package" "add-package": "cd scripts && npm run add-package",
"upgrade-repo": "cd scripts && npm run upgrade-repo"
}, },
"just": { "just": {
"stack": "just-stack-monorepo" "stack": "just-stack-monorepo"

Просмотреть файл

@ -6,6 +6,7 @@
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"add-package": "just add-package --cwd ../", "add-package": "just add-package --cwd ../",
"upgrade-repo": "just upgrade-repo --cwd ../",
"build": "" "build": ""
}, },
"keywords": [], "keywords": [],
@ -15,5 +16,8 @@
"just-task": ">=0.7.5 <1.0.0", "just-task": ">=0.7.5 <1.0.0",
"just-task-preset": ">=0.6.5 <1.0.0", "just-task-preset": ">=0.6.5 <1.0.0",
"just-scripts": "^0.4.0" "just-scripts": "^0.4.0"
},
"just": {
"stack": "just-stack-monorepo"
} }
} }

Просмотреть файл

@ -19,7 +19,7 @@
"dependencies": { "dependencies": {
"react": "^16.7.0", "react": "^16.7.0",
"react-dom": "^16.7.0", "react-dom": "^16.7.0",
"office-ui-fabric-react": "^6.128.0" "office-ui-fabric-react": "^6.129.0"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^23.3.13", "@types/jest": "^23.3.13",