Skip to content

Commit

Permalink
respect indent of manifest if detectable when modifying - fixes #1091 (
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian McKenzie committed Oct 15, 2016
1 parent 6314244 commit f04b157
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 87 deletions.
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -13,6 +13,7 @@
"death": "^1.0.0",
"debug": "^2.2.0",
"defaults": "^1.0.3",
"detect-indent": "^4.0.0",
"diff": "^2.2.1",
"eslint-plugin-react": "5.2.2",
"github": "2.5.1",
Expand Down
6 changes: 3 additions & 3 deletions src/cli/commands/add.js
Expand Up @@ -92,7 +92,7 @@ export class Add extends Install {
const {dev, exact, tilde, optional, peer} = this.flags;

// get all the different registry manifests in this folder
const jsons = await this.getRootManifests();
const manifests = await this.config.getRootManifests();

// add new patterns to their appropriate registry manifest
for (const pattern of this.resolver.dedupePatterns(this.args)) {
Expand Down Expand Up @@ -134,7 +134,7 @@ export class Add extends Install {
}

// add it to manifest
const object = jsons[ref.registry].object;
const object = manifests[ref.registry].object;
for (const key of targetKeys) {
const target = object[key] = object[key] || {};
target[pkg.name] = version;
Expand All @@ -149,7 +149,7 @@ export class Add extends Install {
this.resolver.removePattern(pattern);
}

await this.saveRootManifests(jsons);
await this.config.saveRootManifests(manifests);
}
}

Expand Down
8 changes: 2 additions & 6 deletions src/cli/commands/init.js
Expand Up @@ -4,8 +4,6 @@ import type {Reporter} from '../../reporters/index.js';
import type Config from '../../config.js';
import {stringifyPerson} from '../../util/normalize-manifest/util.js';
import {registryNames} from '../../registries/index.js';
import Lockfile from '../../lockfile/wrapper.js';
import {Install} from './install.js';
import * as child from '../../util/child.js';
import * as fs from '../../util/fs.js';

Expand All @@ -22,9 +20,7 @@ export async function run(
flags: Object,
args: Array<string>,
): Promise<void> {
const lockfile = new Lockfile();
const install = new Install(flags, config, reporter, lockfile);
const manifests = await install.getRootManifests();
const manifests = await config.getRootManifests();

let gitUrl;
const author = {
Expand Down Expand Up @@ -137,5 +133,5 @@ export async function run(
reporter.success(`Saved ${path.basename(targetManifest.loc)}`);
}

await install.saveRootManifests(manifests);
await config.saveRootManifests(manifests);
}
65 changes: 3 additions & 62 deletions src/cli/commands/install.js
Expand Up @@ -6,7 +6,6 @@ import type {Manifest, DependencyRequestPatterns} from '../../types.js';
import type Config from '../../config.js';
import type {RegistryNames} from '../../registries/index.js';
import normalizeManifest from '../../util/normalize-manifest/index.js';
import {stringify} from '../../util/misc.js';
import {registryNames} from '../../registries/index.js';
import {MessageError} from '../../errors.js';
import Lockfile from '../../lockfile/wrapper.js';
Expand Down Expand Up @@ -42,14 +41,6 @@ export type InstallCwdRequest = [
Object
];

type RootManifests = {
[registryName: RegistryNames]: {
loc: string,
object: Object,
exists: boolean,
}
};

type IntegrityMatch = {
actual: string,
expected: string,
Expand Down Expand Up @@ -129,14 +120,6 @@ function normalizeFlags(config: Config, rawFlags: Object): Flags {
return flags;
}

const sortObject = (object) => {
const sortedObject = {};
Object.keys(object).sort().forEach((item) => {
sortedObject[item] = object[item];
});
return sortedObject;
};

export class Install {
constructor(
flags: Object,
Expand Down Expand Up @@ -445,7 +428,7 @@ export class Install {

// save resolutions to their appropriate root manifest
if (Object.keys(this.resolutions).length) {
const jsons = await this.getRootManifests();
const manifests = await this.config.getRootManifests();

for (const name in this.resolutions) {
const version = this.resolutions[name];
Expand All @@ -467,59 +450,17 @@ export class Install {
const ref = manifest._reference;
invariant(ref, 'expected reference');

const object = jsons[ref.registry].object;
const object = manifests[ref.registry].object;
object.resolutions = object.resolutions || {};
object.resolutions[name] = version;
}

await this.saveRootManifests(jsons);
await this.config.saveRootManifests(manifests);
}

return flattenedPatterns;
}

/**
* Get root manifests.
*/

async getRootManifests(): Promise<RootManifests> {
const manifests: RootManifests = {};
for (const registryName of registryNames) {
const registry = registries[registryName];
const jsonLoc = path.join(this.config.cwd, registry.filename);

let object = {};
let exists = false;
if (await fs.exists(jsonLoc)) {
exists = true;
object = await fs.readJson(jsonLoc);
}
manifests[registryName] = {loc: jsonLoc, object, exists};
}
return manifests;
}

/**
* Save root manifests.
*/

async saveRootManifests(manifests: RootManifests): Promise<void> {
for (const registryName of registryNames) {
const {loc, object, exists} = manifests[registryName];
if (!exists && !Object.keys(object).length) {
continue;
}

for (const field of constants.DEPENDENCY_TYPES) {
if (object[field]) {
object[field] = sortObject(object[field]);
}
}

await fs.writeFile(loc, stringify(object) + '\n');
}
}

/**
* Save updated integrity and lockfiles.
*/
Expand Down
5 changes: 2 additions & 3 deletions src/cli/commands/remove.js
Expand Up @@ -30,8 +30,7 @@ export async function run(

// load manifests
const lockfile = await Lockfile.fromDirectory(config.cwd);
const install = new Install(flags, config, new NoopReporter(), lockfile);
const rootManifests = await install.getRootManifests();
const rootManifests = await config.getRootManifests();
const manifests = [];

for (const name of args) {
Expand Down Expand Up @@ -66,7 +65,7 @@ export async function run(
}

// save manifests
await install.saveRootManifests(rootManifests);
await config.saveRootManifests(rootManifests);

// run hooks - npm runs these one after another
for (const action of ['preuninstall', 'uninstall', 'postuninstall']) {
Expand Down
16 changes: 12 additions & 4 deletions src/cli/commands/version.js
Expand Up @@ -2,9 +2,9 @@

import type {Reporter} from '../../reporters/index.js';
import type Config from '../../config.js';
import {registryNames} from '../../registries/index.js';
import executeLifecycleScript from './_execute-lifecycle-script.js';
import {MessageError} from '../../errors.js';
import {stringify} from '../../util/misc.js';
import {spawn} from '../../util/child.js';
import * as fs from '../../util/fs.js';

Expand Down Expand Up @@ -81,9 +81,17 @@ export async function setVersion(

// update version
reporter.info(`${reporter.lang('newVersion')}: ${newVersion}`);
const json = await fs.readJson(pkgLoc);
pkg.version = json.version = newVersion;
await fs.writeFile(pkgLoc, `${stringify(json)}\n`);
pkg.version = newVersion;

// update versions in manifests
const manifests = await config.getRootManifests();
for (const registryName of registryNames) {
const manifest = manifests[registryName];
if (manifest.exists) {
manifest.object.version = newVersion;
}
}
await config.saveRootManifests(manifests);

return async function(): Promise<void> {
invariant(newVersion, 'expected version');
Expand Down
67 changes: 66 additions & 1 deletion src/config.js
Expand Up @@ -9,9 +9,10 @@ import * as fs from './util/fs.js';
import * as constants from './constants.js';
import ConstraintResolver from './package-constraint-resolver.js';
import RequestManager from './util/request-manager.js';
import {registries} from './registries/index.js';
import {registries, registryNames} from './registries/index.js';
import map from './util/map.js';

const detectIndent = require('detect-indent');
const invariant = require('invariant');
const path = require('path');
const url = require('url');
Expand Down Expand Up @@ -40,6 +41,24 @@ type PackageMetadata = {
package: Manifest
};


type RootManifests = {
[registryName: RegistryNames]: {
loc: string,
indent: ?string,
object: Object,
exists: boolean,
}
};

function sortObject(object: Object): Object {
const sortedObject = {};
Object.keys(object).sort().forEach((item) => {
sortedObject[item] = object[item];
});
return sortedObject;
}

export type ConfigRegistries = {
[name: RegistryNames]: Registry
};
Expand Down Expand Up @@ -372,4 +391,50 @@ export default class Config {
}
return this.registries[registryName].folder;
}

/**
* Get root manifests.
*/

async getRootManifests(): Promise<RootManifests> {
const manifests: RootManifests = {};
for (const registryName of registryNames) {
const registry = registries[registryName];
const jsonLoc = path.join(this.cwd, registry.filename);

let object = {};
let exists = false;
let indent;
if (await fs.exists(jsonLoc)) {
exists = true;

const info = await fs.readJsonAndFile(jsonLoc);
object = info.object;
indent = detectIndent(info.content).indent || undefined;
}
manifests[registryName] = {loc: jsonLoc, object, exists, indent};
}
return manifests;
}

/**
* Save root manifests.
*/

async saveRootManifests(manifests: RootManifests): Promise<void> {
for (const registryName of registryNames) {
const {loc, object, exists, indent} = manifests[registryName];
if (!exists && !Object.keys(object).length) {
continue;
}

for (const field of constants.DEPENDENCY_TYPES) {
if (object[field]) {
object[field] = sortObject(object[field]);
}
}

await fs.writeFile(loc, JSON.stringify(object, null, indent || constants.DEFAULT_INDENT) + '\n');
}
}
}
1 change: 1 addition & 0 deletions src/constants.js
Expand Up @@ -45,6 +45,7 @@ export const METADATA_FILENAME = '.yarn-metadata.json';
export const TARBALL_FILENAME = '.yarn-tarball.tgz';
export const CLEAN_FILENAME = '.yarnclean';

export const DEFAULT_INDENT = ' ';
export const SINGLE_INSTANCE_PORT = 31997;
export const SINGLE_INSTANCE_FILENAME = '.yarn-single-instance';

Expand Down
5 changes: 2 additions & 3 deletions src/fetchers/base-fetcher.js
Expand Up @@ -5,7 +5,6 @@ import type {PackageRemote, FetchedMetadata, FetchedOverride} from '../types.js'
import type {RegistryNames} from '../registries/index.js';
import type Config from '../config.js';
import * as constants from '../constants.js';
import * as util from '../util/misc.js';
import * as fs from '../util/fs.js';

const path = require('path');
Expand Down Expand Up @@ -49,11 +48,11 @@ export default class BaseFetcher {
// load the new normalized manifest
const pkg = await this.config.readManifest(dest, this.registry);

await fs.writeFile(path.join(dest, constants.METADATA_FILENAME), util.stringify({
await fs.writeFile(path.join(dest, constants.METADATA_FILENAME), JSON.stringify({
remote: this.remote,
registry: this.registry,
hash,
}));
}, null, ' '));

return {
resolved,
Expand Down
12 changes: 11 additions & 1 deletion src/util/fs.js
Expand Up @@ -315,9 +315,19 @@ export async function readFileAny(files: Array<string>): Promise<?string> {
}

export async function readJson(loc: string): Promise<Object> {
return (await readJsonAndFile(loc)).object;
}

export async function readJsonAndFile(loc: string): Promise<{
object: Object,
content: string,
}> {
const file = await readFile(loc);
try {
return map(JSON.parse(stripBOM(file)));
return {
object: map(JSON.parse(stripBOM(file))),
content: file,
};
} catch (err) {
err.message = `${loc}: ${err.message}`;
throw err;
Expand Down
4 changes: 0 additions & 4 deletions src/util/misc.js
Expand Up @@ -30,7 +30,3 @@ export function removeSuffix(pattern: string, suffix: string): string {

return pattern;
}

export function stringify(obj: Object): string {
return JSON.stringify(obj, null, ' ');
}
6 changes: 6 additions & 0 deletions yarn.lock
Expand Up @@ -1653,6 +1653,12 @@ detect-file@^0.1.0:
dependencies:
fs-exists-sync "^0.1.0"

detect-indent:
version "4.0.0"
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
dependencies:
repeating "^2.0.0"

detect-indent@^3.0.0, detect-indent@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-3.0.1.tgz#9dc5e5ddbceef8325764b9451b02bc6d54084f75"
Expand Down

0 comments on commit f04b157

Please sign in to comment.