Skip to content

Commit

Permalink
Tenth commit
Browse files Browse the repository at this point in the history
  • Loading branch information
arcanis committed Oct 21, 2018
1 parent cd40c69 commit 93abb68
Show file tree
Hide file tree
Showing 69 changed files with 3,148 additions and 8,880 deletions.
8,002 changes: 0 additions & 8,002 deletions .pnp.js

This file was deleted.

225 changes: 131 additions & 94 deletions berry.lock

Large diffs are not rendered by default.

1,763 changes: 1,439 additions & 324 deletions packages/berry-cli/bin/berry.js

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions packages/berry-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"devDependencies": {
"@berry/builder": "0.0.0",
"@berry/plugin-github": "0.0.0",
"@berry/plugin-http": "0.0.0",
"@berry/plugin-hub": "0.0.0",
"@berry/plugin-npm": "0.0.0",
"@berry/pnp": "0.0.0"
Expand All @@ -26,10 +27,16 @@
"@berry/builder": {
"bundles": {
"light": [
"@berry/plugin-file",
"@berry/plugin-link",
"@berry/plugin-http",
"@berry/plugin-github",
"@berry/plugin-npm"
],
"full": [
"@berry/plugin-file",
"@berry/plugin-link",
"@berry/plugin-http",
"@berry/plugin-github",
"@berry/plugin-npm",
"@berry/plugin-hub"
Expand Down
72 changes: 72 additions & 0 deletions packages/berry-cli/sources/commands/bin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import Joi = require('joi');

import {Configuration, Project, Workspace, Cache, Locator, Manifest} from '@berry/core';
// @ts-ignore: Need to write the definition file
import {UsageError} from '@manaflair/concierge';
import {resolve} from 'path';
import {Readable, Writable} from 'stream';

import {plugins} from '../plugins';

export async function getDependencyBinaries({configuration, project, workspace, cache}: {configuration: Configuration, project: Project, workspace: Workspace, cache: Cache}) {
const fetcher = configuration.makeFetcher();
const binaries: Map<string, [Locator, string]> = new Map();

const descriptors = [
... workspace.manifest.dependencies.values(),
... workspace.manifest.devDependencies.values(),
... workspace.manifest.peerDependencies.values(),
];

for (const descriptor of descriptors) {
const resolution = project.storedResolutions.get(descriptor.descriptorHash);

if (!resolution)
continue;

const pkg = project.storedPackages.get(resolution);

if (!pkg)
continue;

const pkgFs = await fetcher.fetch(pkg, {cache, fetcher, project});

const manifest = new Manifest();
manifest.loadFile(pkgFs);

for (const [binName, file] of manifest.bin.entries()) {
binaries.set(binName, [pkg, file]);
}
}

return binaries;
}

export default (concierge: any) => concierge

.command(`bin <name> [--cwd PATH]`)
.describe(`get the path to a binary script`)

.validate(Joi.object().unknown().keys({
cwd: Joi.string().default(process.cwd()),
}))

.action(async ({cwd, stdin, stdout, stderr, name}: {cwd: string, stdin: Readable, stdout: Writable, stderr: Writable, name: string}) => {
const configuration = await Configuration.find(cwd, plugins);
const {project, workspace} = await Project.find(configuration, cwd);
const cache = await Cache.find(configuration);

const binaries = await getDependencyBinaries({configuration, project, workspace, cache});
const binary = binaries.get(name);

if (!binary)
throw new UsageError(`Couldn't find a binary named "${name}"`);

const [pkg, file] = binary;

const fetcher = configuration.makeFetcher();
const pkgFs = await fetcher.fetch(pkg, {cache, fetcher, project});
const target = resolve(pkgFs.getRealPath(), file);

stdout.write(`${target}\n`);
});
2 changes: 1 addition & 1 deletion packages/berry-cli/sources/commands/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {plugins} from '../plugins';

export default (concierge: any) => concierge

.command(`install [--cwd PATH]`)
.command(`install [-f] [--cwd PATH]`)
.describe(`install the project's dependencies`)

.validate(Joi.object().unknown().keys({
Expand Down
49 changes: 10 additions & 39 deletions packages/berry-cli/sources/commands/run.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,15 @@
import execa = require('execa');

import {Configuration, Project, Workspace, Cache, Locator} from '@berry/core';
import {runShell} from '@berry/shell'
import {Configuration, Project, Workspace, Cache, Locator, Manifest} from '@berry/core';
import {runShell} from '@berry/shell'
// @ts-ignore: Need to write the definition file
import {UsageError} from '@manaflair/concierge';
import {resolve} from 'path';
import {Readable, Writable} from 'stream';
import {UsageError} from '@manaflair/concierge';
import {resolve} from 'path';
import {Readable, Writable} from 'stream';

import {plugins} from '../plugins';
import {plugins} from '../plugins';

async function getDependencyBinaries({configuration, project, workspace, cache}: {configuration: Configuration, project: Project, workspace: Workspace, cache: Cache}) {
const fetcher = configuration.makeFetcher();
const binaries: Map<string, [Locator, string]> = new Map();

const descriptors = [
... workspace.manifest.dependencies.values(),
... workspace.manifest.devDependencies.values(),
... workspace.manifest.peerDependencies.values(),
];

for (const descriptor of descriptors) {
const resolution = project.storedResolutions.get(descriptor.descriptorHash);

if (!resolution)
continue;

const pkg = project.storedPackages.get(resolution);

if (!pkg)
continue;

const manifest = await fetcher.fetchManifest(pkg, {cache, fetcher, project});

for (const [binName, file] of manifest.bin.entries()) {
binaries.set(binName, [pkg, file]);
}
}

return binaries;
}
import {getDependencyBinaries} from './bin';

export default (concierge: any) => concierge

Expand Down Expand Up @@ -67,10 +38,10 @@ export default (concierge: any) => concierge

if (binary) {
const [pkg, file] = binary;

const fetcher = configuration.makeFetcher();
const root = await fetcher.fetch(pkg, {cache, fetcher, project});
const target = resolve(root, file);
const pkgFs = await fetcher.fetch(pkg, {cache, fetcher, project});
const target = resolve(pkgFs.getRealPath(), file);

const stdio: Array<any> = [`pipe`, `pipe`, `pipe`];

Expand Down
54 changes: 30 additions & 24 deletions packages/berry-core/sources/Cache.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import fsx = require('fs-extra');

import {createHmac} from 'crypto';
import {writeFile} from 'fs';
import {lock, unlock} from 'lockfile';
import {resolve} from 'path';
import {promisify} from 'util';
import {FakeFS, ZipFS, NodeFS} from '@berry/zipfs';
import {createHmac} from 'crypto';
import {writeFile} from 'fs';
import {lock, unlock} from 'lockfile';
import {dirname, relative, resolve} from 'path';
import {promisify} from 'util';

import {Archive} from './Archive';
import {Configuration} from './Configuration';
import {Locator} from './types';
import {Archive} from './Archive';
import {Configuration} from './Configuration';
import {Locator} from './types';

const writeFileP = promisify(writeFile);

Expand Down Expand Up @@ -63,36 +64,45 @@ export class Cache {
});
}

async fetchVirtualFolder(locator: Locator) {
const virtualFolder = resolve(this.cwd, `virtual`, locator.locatorHash);
async ensureVirtualLink(locator: Locator, target: string) {
const virtualLink = resolve(this.cwd, `virtual`, locator.locatorHash);

// @ts-ignore: [DefinitelyTyped] The "type" parameter is missing
await fsx.ensureSymlink(`/`, virtualFolder, `junction`);
await fsx.ensureSymlink(relative(dirname(virtualLink), target), virtualLink);

return virtualFolder;
return virtualLink;
}

async fetchFromCache(locator: Locator, loader?: () => Promise<Archive>) {
async fetchFromCache(locator: Locator, loader?: () => Promise<FakeFS>) {
const key = this.getCacheKey(locator);
const file = this.getFilePath(key);

return await this.writeFileIntoCache(file, async () => {
let archive;
return await this.writeFileIntoCache<FakeFS>(file, async () => {
let fs;

try {
archive = await Archive.load(file);
fs = new ZipFS(file, {baseFs: new NodeFS()});
this.cacheHitCount += 1;
} catch (error) {
this.cacheMissCount += 1;

if (!loader)
throw error;

archive = await loader();
await archive.move(file);
fs = await loader();

if (!(fs instanceof ZipFS))
throw new Error(`The fetchers plugged into the cache must return a ZipFS instance`);

const source = fs.close();

await fsx.chmod(source, 0o644);
await fsx.move(source, file);

fs = new ZipFS(file);
}

return archive;
return fs;
});
}

Expand All @@ -105,14 +115,10 @@ export class Cache {
throw new Error(`Couldn't obtain a lock on ${file}`);
}

let entity: T;

try {
entity = await generator(file);
return await generator(file);
} finally {
await unlockP(lock);
}

return {file, entity};
}
}
28 changes: 6 additions & 22 deletions packages/berry-core/sources/CacheFetcher.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Fetcher, FetchOptions} from './Fetcher';
import {Manifest} from './Manifest';
import {Locator} from './types';
import {Fetcher, FetchOptions, MinimalFetchOptions} from './Fetcher';
import {Manifest} from './Manifest';
import {Locator} from './types';

export class CacheFetcher implements Fetcher {
private readonly next: Fetcher;
Expand All @@ -9,29 +9,13 @@ export class CacheFetcher implements Fetcher {
this.next = next;
}

supports(locator: Locator) {
return this.next.supports(locator);
}

async fetchManifest(locator: Locator, opts: FetchOptions) {
const {entity} = await opts.cache.fetchFromCache(locator, () => {
return this.next.fetch(locator, opts);
});

const manifest = new Manifest();
manifest.load(await entity.readJson(`package.json`));

// Since it comes from an archive, it's immutable and we freeze its content
Object.freeze(manifest);

return manifest;
supports(locator: Locator, opts: MinimalFetchOptions) {
return this.next.supports(locator, opts);
}

async fetch(locator: Locator, opts: FetchOptions) {
const {file} = await opts.cache.fetchFromCache(locator, () => {
return await opts.cache.fetchFromCache(locator, () => {
return this.next.fetch(locator, opts);
});

return file;
}
}
2 changes: 1 addition & 1 deletion packages/berry-core/sources/Configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class Configuration {

public registryServer: string | null = null;

public pnpShebang: string = `/usr/bin/env node`;
public pnpShebang: string = `#!/usr/bin/env node`;
public pnpIgnorePattern: string | null = null;
public pnpVirtualFolder: string = `./.pnp/virtual`;
public pnpPath: string = `./.pnp.js`;
Expand Down
18 changes: 10 additions & 8 deletions packages/berry-core/sources/Fetcher.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import {Archive} from './Archive';
import {FakeFS} from '@berry/zipfs';

import {Cache} from './Cache';
import {Manifest} from './Manifest';
import {Project} from './Project';
import {Locator} from './types';

export type FetchOptions = {
cache: Cache,
fetcher: Fetcher,
export type MinimalFetchOptions = {
project: Project,
fetcher: Fetcher,
};

export interface Fetcher {
supports(locator: Locator): boolean;
export type FetchOptions = MinimalFetchOptions & {
cache: Cache,
};

fetchManifest(locator: Locator, opts: FetchOptions): Promise<Manifest>;
export interface Fetcher {
supports(locator: Locator, opts: MinimalFetchOptions): boolean;

fetch(locator: Locator, opts: FetchOptions): Promise<any>;
fetch(locator: Locator, opts: FetchOptions): Promise<FakeFS>;
}
4 changes: 4 additions & 0 deletions packages/berry-core/sources/LockfileResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ export class LockfileResolver implements Resolver {
return false;
}

async normalizeDescriptor(descriptor: Descriptor, fromLocator: Locator, opts: ResolveOptions) {
return descriptor;
}

async getCandidates(descriptor: Descriptor, opts: ResolveOptions) {
let pkg = opts.project.storedPackages.get(structUtils.convertDescriptorToLocator(descriptor).locatorHash);

Expand Down
9 changes: 9 additions & 0 deletions packages/berry-core/sources/Manifest.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import {FakeFS} from '@berry/zipfs';

import * as structUtils from './structUtils';
import {Ident, Descriptor} from './types';

Expand All @@ -18,6 +20,13 @@ export class Manifest {

public workspaceDefinitions: Array<WorkspaceDefinition> = [];

loadFile(fakeFs: FakeFS, path: string = `package.json`) {
const content = fakeFs.readFile(path, `utf8`);
const data = JSON.parse(content);

this.load(data);
}

load(data: any) {
if (typeof data !== `object` || data === null)
throw new Error(`Utterly invalid manifest data`);
Expand Down
Loading

0 comments on commit 93abb68

Please sign in to comment.