publish [version]

fixes #9
This commit is contained in:
Joao Moreno 2016-02-29 11:11:33 +01:00
parent e03799b2d5
commit 6027e490d7
4 changed files with 63 additions and 29 deletions

View file

@ -23,10 +23,10 @@ module.exports = function (argv: string[]): void {
.action(({ out, baseContentUrl, baseImagesUrl }) => catchFatal(packageCommand({ packagePath: out, baseContentUrl, baseImagesUrl })));
program
.command('publish [package]')
.command('publish [<version>]')
.description('Publishes an extension')
.option('-p, --pat <token>', 'Personal Access Token')
.action((packagePath, { pat }) => catchFatal(publish({ pat, packagePath })));
.action((version, { pat }) => catchFatal(publish({ pat, version })));
program
.command('unpublish <publisher> <name>')

View file

@ -12,13 +12,15 @@ import * as mime from 'mime';
import * as urljoin from 'url-join';
import { validatePublisher, validateExtensionName, validateVersion } from './validation';
import { getDependencies } from './npm';
import * as semver from 'semver';
interface IReadFile {
(filePath: string): Promise<Buffer>;
(filePath: string, encoding?: string): Promise<string>;
}
const readFile: IReadFile = <any> denodeify(fs.readFile);
const readFile = denodeify<string, string, string>(fs.readFile);
const writeFile = denodeify<string, string, string, void>(fs.writeFile);
const unlink = denodeify<string, void>(fs.unlink);
const exec = denodeify<string, { cwd?: string; }, { stdout: string; stderr: string; }>(cp.exec, (err, stdout, stderr) => [err, { stdout, stderr }]);
const glob = denodeify<string, _glob.IOptions, string[]>(_glob);
@ -35,11 +37,11 @@ export interface IFile {
localPath?: string;
}
export function read(file: IFile): Promise<Buffer> {
export function read(file: IFile): Promise<string> {
if (file.contents) {
return Promise.resolve(file.contents);
return Promise.resolve(file.contents).then(b => b.toString('utf8'));
} else {
return readFile(file.localPath);
return readFile(file.localPath, 'utf8');
}
}
@ -56,6 +58,7 @@ export interface IAsset {
export interface IPackageOptions {
cwd?: string;
packagePath?: string;
version?: string;
baseContentUrl?: string;
baseImagesUrl?: string;
}
@ -140,7 +143,6 @@ export class ReadmeProcessor extends BaseProcessor {
}
return read(file)
.then(buffer => buffer.toString('utf8'))
.then(contents => contents.replace(/(!?)\[([^\]]+)\]\(([^\)]+)\)/g, (all, isImage, title, link) => {
const prefix = isImage ? this.baseImagesUrl : this.baseContentUrl;
@ -278,6 +280,11 @@ export function readManifest(cwd: string): Promise<Manifest> {
.then(validateManifest);
}
export function writeManifest(cwd: string, manifest: Manifest): Promise<void> {
const manifestPath = path.join(cwd, 'package.json');
return writeFile(manifestPath, JSON.stringify(manifest, null, 4), 'utf8');
}
export function toVsixManifest(assets: IAsset[], vsix: any, options: IPackageOptions = {}): Promise<string> {
return readFile(vsixManifestTemplatePath, 'utf8')
.then(vsixManifestTemplateStr => _.template(vsixManifestTemplateStr))

View file

@ -1,6 +1,6 @@
import * as fs from 'fs';
import { ExtensionQueryFlags, PublishedExtension, ExtensionQueryFilterType, PagingDirection } from 'vso-node-api/interfaces/GalleryInterfaces';
import { pack, readManifest, IPackageResult } from './package';
import { pack, readManifest, writeManifest, IPackageResult } from './package';
import * as tmp from 'tmp';
import { getPublisher } from './store';
import { getGalleryAPI, getRawGalleryAPI, read } from './util';
@ -8,6 +8,7 @@ import { validatePublisher } from './validation';
import { Manifest } from './manifest';
import * as denodeify from 'denodeify';
import * as yauzl from 'yauzl';
import * as semver from 'semver';
const tmpName = denodeify<string>(tmp.tmpName);
const readFile = denodeify<string, string, string>(fs.readFile);
@ -80,22 +81,58 @@ function _publish(packagePath: string, pat: string, manifest: Manifest): Promise
export interface IPublishOptions {
packagePath?: string;
version?: string;
cwd?: string;
pat?: string;
}
function versionBump(cwd: string = process.cwd(), version?: string): Promise<void> {
if (!version) {
return Promise.resolve(null);
}
return readManifest(cwd)
.then(manifest => {
switch (version) {
case 'major':
case 'minor':
case 'patch':
return { manifest, version: semver.inc(manifest.version, version) };
default:
const updatedVersion = semver.valid(version);
if (!updatedVersion) {
return Promise.reject(`Invalid version ${ version }`);
}
return { manifest, version: updatedVersion };
}
}).then(({ manifest, version }) => {
if (version !== manifest.version) {
manifest.version = version;
return writeManifest(cwd, manifest);
}
});
}
export function publish(options: IPublishOptions = {}): Promise<any> {
let promise: Promise<IPackageResult>;
if (options.packagePath) {
if (options.version) {
return Promise.reject(`Not supported: packagePath and version.`);
}
promise = readManifestFromPackage(options.packagePath)
.then(manifest => ({ manifest, packagePath: options.packagePath }))
} else {
promise = tmpName()
.then(packagePath => pack({ packagePath, cwd: options.cwd }));
promise = versionBump(options.cwd, options.version)
.then(() => tmpName())
.then(packagePath => pack({ packagePath, version: options.version, cwd: options.cwd }));
}
return promise.then(({ manifest, packagePath }) => {
process.exit(1);
const patPromise = options.pat
? Promise.resolve(options.pat)
: getPublisher(manifest.publisher).then(p => p.pat);

View file

@ -442,9 +442,7 @@ describe('ReadmeProcessor', () => {
return processor.onFile(readme)
.then(file => read(file))
.then(actualBuffer => {
const actual = actualBuffer.toString('utf8');
.then(actual => {
return readFile(path.join(root, 'readme.md'), 'utf8')
.then(expected => {
assert.equal(actual, expected);
@ -473,9 +471,7 @@ describe('ReadmeProcessor', () => {
return processor.onFile(readme)
.then(file => read(file))
.then(actualBuffer => {
const actual = actualBuffer.toString('utf8');
.then(actual => {
return readFile(path.join(root, 'readme.expected.md'), 'utf8')
.then(expected => {
assert.equal(actual, expected);
@ -502,9 +498,7 @@ describe('ReadmeProcessor', () => {
return processor.onFile(readme)
.then(file => read(file))
.then(actualBuffer => {
const actual = actualBuffer.toString('utf8');
.then(actual => {
return readFile(path.join(root, 'readme.expected.md'), 'utf8')
.then(expected => {
assert.equal(actual, expected);
@ -531,9 +525,7 @@ describe('ReadmeProcessor', () => {
return processor.onFile(readme)
.then(file => read(file))
.then(actualBuffer => {
const actual = actualBuffer.toString('utf8');
.then(actual => {
return readFile(path.join(root, 'readme.expected.md'), 'utf8')
.then(expected => {
assert.equal(actual, expected);
@ -564,9 +556,7 @@ describe('ReadmeProcessor', () => {
return processor.onFile(readme)
.then(file => read(file))
.then(actualBuffer => {
const actual = actualBuffer.toString('utf8');
.then(actual => {
return readFile(path.join(root, 'readme.images.expected.md'), 'utf8')
.then(expected => {
assert.equal(actual, expected);