diff --git a/src/package.ts b/src/package.ts index 13a4be0..63cbd02 100644 --- a/src/package.ts +++ b/src/package.ts @@ -1,17 +1,18 @@ -import { readFile, createWriteStream } from 'fs'; +import * as fs from 'fs'; import * as path from 'path'; import * as _ from 'lodash'; import * as yazl from 'yazl'; import { Manifest } from './manifest'; -import { nfcall, Promise, reject, resolve } from 'q'; +import { nfcall, Promise, reject, resolve, all } from 'q'; +import * as glob from 'glob'; const resourcesPath = path.join(path.dirname(__dirname), 'resources'); const vsixManifestTemplatePath = path.join(resourcesPath, 'extension.vsixmanifest'); -function readManifest(root: string): Promise { - const manifestPath = path.join(root, 'package.json'); +function readManifest(cwd: string): Promise { + const manifestPath = path.join(cwd, 'package.json'); - return nfcall(readFile, manifestPath, 'utf8') + return nfcall(fs.readFile, manifestPath, 'utf8') .catch(() => reject(`Extension manifest not found: ${ manifestPath }`)) .then(manifestStr => { try { @@ -47,7 +48,7 @@ function validateManifest(manifest: Manifest): Promise { } function toVsixManifest(manifest: Manifest): Promise { - return nfcall(readFile, vsixManifestTemplatePath, 'utf8') + return nfcall(fs.readFile, vsixManifestTemplatePath, 'utf8') .then(vsixManifestTemplateStr => _.template(vsixManifestTemplateStr)) .then(vsixManifestTemplate => vsixManifestTemplate({ id: manifest.name, @@ -59,33 +60,39 @@ function toVsixManifest(manifest: Manifest): Promise { })); } -function writeVsix(packagePath: string, vsixManifest: string): Promise { - return Promise((c, e) => { - const zip = new yazl.ZipFile(); - zip.addBuffer(new Buffer(vsixManifest, 'utf8'), 'extension.vsixmanifest'); - zip.addFile(path.join(resourcesPath, '[Content_Types].xml'), '[Content_Types].xml'); - zip.addBuffer(new Buffer('hello world', 'utf8'), 'hello.txt'); - zip.end(); - - const zipStream = createWriteStream(packagePath); - zip.outputStream.pipe(zipStream); - zip.outputStream.once('error', e); - zip.outputStream.once('end', c); - }); +function collectFiles(cwd: string): Promise { + return nfcall(glob, '**', { cwd, nodir: true }); } -function defaultPackagePath(root: string, manifest: Manifest) { - return path.join(root, `${ manifest.name }-${ manifest.version }.vsix`); -} - -export = function (packagePath?: string, root = process.cwd()): Promise { - return readManifest(root) - .then(validateManifest) - .then(manifest => { - packagePath = packagePath || defaultPackagePath(root, manifest); - - return toVsixManifest(manifest) - .then(vsixManifest => writeVsix(packagePath, vsixManifest)) - .then(() => console.log(`Package created: ${ path.resolve(packagePath) }`)); +function writeVsix(cwd: string, manifest: Manifest, packagePath: string): Promise { + packagePath = packagePath || defaultPackagePath(cwd, manifest); + + return nfcall(fs.unlink, packagePath) + .catch(err => err.code !== 'ENOENT' ? reject(err) : resolve(null)) + .then(() => { + return all([toVsixManifest(manifest), collectFiles(cwd)]) + .spread((vsixManifest: string, files: string[]) => Promise((c, e) => { + const zip = new yazl.ZipFile(); + zip.addBuffer(new Buffer(vsixManifest, 'utf8'), 'extension.vsixmanifest'); + zip.addFile(path.join(resourcesPath, '[Content_Types].xml'), '[Content_Types].xml'); + files.forEach(file => zip.addFile(path.join(cwd, file), 'extension/' + file)); + zip.end(); + + const zipStream = fs.createWriteStream(packagePath); + zip.outputStream.pipe(zipStream); + zip.outputStream.once('error', e); + zip.outputStream.once('end', () => c(packagePath)); + })); }); +} + +function defaultPackagePath(cwd: string, manifest: Manifest): string { + return path.join(cwd, `${ manifest.name }-${ manifest.version }.vsix`); +} + +export = function (packagePath?: string, cwd = process.cwd()): Promise { + return readManifest(cwd) + .then(validateManifest) + .then(manifest => writeVsix(cwd, manifest, packagePath)) + .then(packagePath => console.log(`Package created: ${ packagePath }`)); }; \ No newline at end of file