Skip to content

Commit

Permalink
Merge pull request #33 from Polymer/config
Browse files Browse the repository at this point in the history
Add command line flags
  • Loading branch information
justinfagnani authored Jun 20, 2017
2 parents f6420ba + 44f9436 commit a1d4f64
Show file tree
Hide file tree
Showing 7 changed files with 252 additions and 38 deletions.
4 changes: 2 additions & 2 deletions bin/html2js.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ process.title = 'analyze';

require('source-map-support').install();

const {convertPackage} = require('../lib/html2js');
const {run} = require('../lib/cli');

process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise ', p, ' reason: ', reason);
});

convertPackage();
run();
21 changes: 21 additions & 0 deletions custom_typings/command-line-args.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
declare module 'command-line-args' {

module commandLineArgs {

interface OptionDefinition {
name: string;
alias?: string;
type?: any;
multiple?: boolean;
defaultOption?: boolean;
defaultValue?: any;
description?: string;
}

}

function commandLineArgs(options: OptionDefinition[], argv?: string[])
: {[name: string]: any};

export = commandLineArgs;
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
"@types/mz": "^0.0.31",
"ast-types": "^0.9.11",
"chai": "^3.5.0",
"command-line-args": "^4.0.6",
"command-line-usage": "^4.0.0",
"esprima": "^3.1.3",
"estraverse": "^4.2.0",
"jscodeshift": "^0.3.30",
Expand Down
83 changes: 83 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/

import { convertPackage } from './html2js';

import commandLineArgs = require('command-line-args')

const optionDefinitions: commandLineArgs.OptionDefinition[] = [
{
name: 'help',
type: Boolean,
description: 'Show this help message.',
},
{
name: 'out',
type: String,
defaultValue: 'html2js_out',
description: 'The directory to write converted files to.'
},
{
name: 'root-module',
type: String,
description: 'Root namespace name to use to detect exports.'
},
{
name: 'exclude',
type: String,
multiple: true,
description: 'Exclude a file from conversion.'
},
{
name: 'package-name',
type: String,
description: 'npm package name to use for package.json'
},
{
name: 'npm-version',
type: String,
description: 'Version string to use for package.json'
},
];

export async function run() {

const options = commandLineArgs(optionDefinitions);

if (options['help']) {
const getUsage = require('command-line-usage');
const usage = getUsage([
{
header: 'html2js',
content: 'Convert HTML Imports to JavaScript modules',
},
{
header: 'Options',
optionList: optionDefinitions,
}
]);
console.log(usage);
return;
}

await convertPackage({
outDir: options['out'],
excludes: options['exclude'],
rootModuleName: options['root-module'],
packageName: options['package-name'],
npmVersion: options['npm-version'],
});

console.log('Done');
}
62 changes: 44 additions & 18 deletions src/html2js.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const isNotExternal = (d: Document) => !_isInBowerRegex.test(d.url) && !_isInNpm
function generatePackageJson(bowerJson: any, npmName: string, npmVersion?: string) {
return {
name: npmName,
private: true,
flat: true,
version: npmVersion || bowerJson.version,
description: bowerJson.description,
Expand Down Expand Up @@ -112,15 +113,31 @@ export interface ModuleIndex {
namespacedExports: Map<string, JsExport>;
}

type ConvertPackageOptions = AnalysisConverterOptions & {

/**
* The directory to write converted JavaScript files to.
*/
outDir?: string;

/**
* The npm package name to use in package.json
*/
packageName?: string;

npmVersion?: string;
};

/**
* Converts an entire package from HTML imports to JS modules
*/
export async function convertPackage() {
const outDir = path.resolve(process.cwd(), 'js_out');
console.log(`Out directory: ${outDir}`);
export async function convertPackage(options: ConvertPackageOptions = {}) {
const outDir = options && (options.outDir) || 'js_out';
const outDirResolved = path.resolve(process.cwd(), outDir);
console.log(`Out directory: ${outDirResolved}`);

try {
await fs.mkdir(outDir);
await fs.mkdir(outDirResolved);
} catch (e) {
if (e.errno !== -17) { // directory exists
console.error(e);
Expand All @@ -131,27 +148,28 @@ export async function convertPackage() {

// TODO(justinfagnani): These setting are only good for Polymer core and should be
// extracted into a config file
const npmPackageName = '@polymer/polymer';
const npmPackageVersion = '3.0.0-pre.2';
const npmPackageName = options.packageName || '@polymer/polymer';
const npmPackageVersion = options.npmVersion;
const converter = new AnalysisConverter(analysis, {
excludes: [
rootModuleName: options.rootModuleName || 'Polymer',
excludes: options.excludes || [
'lib/utils/boot.html',
'lib/elements/dom-module.html',
],
referenceExcludes: [
referenceExcludes: options.referenceExcludes || [
'Polymer.DomModule',
'Polymer.log',
'Polymer.sanitizeDOMValue'
],
mutableExports: {
mutableExports: options.mutableExports || {
'Polymer.telemetry': ['instanceCount'],
},
});

try {
const results = await converter.convert();
for (const [jsUrl, newSource] of results!) {
const outPath = path.resolve(outDir, jsUrl);
const outPath = path.resolve(outDirResolved, jsUrl);
const jsDir = path.dirname(outPath);
// console.log(`writing ${outPath}`);
mkdirp.sync(jsDir);
Expand All @@ -177,6 +195,12 @@ export async function convertPackage() {
}

export interface AnalysisConverterOptions {

/**
* The root namespace name that is used to detect exports.
*/
rootModuleName?: string;

/**
* Files to exclude from conversion (ie lib/utils/boot.html). Imports
* to these files are also excluded.
Expand Down Expand Up @@ -209,18 +233,20 @@ export interface AnalysisConverterOptions {
export class AnalysisConverter {

analysis: Analysis;
options: AnalysisConverterOptions;
rootModuleName: string|undefined;
_excludes: Set<string>;
_referenceExcludes: Set<string>;
_mutableExports?: {[namespaceName: string]: string[]};

modules = new Map<string, JsModule>();
namespacedExports = new Map<string, JsExport>();

constructor(analysis: Analysis, options?: AnalysisConverterOptions) {
constructor(analysis: Analysis, options: AnalysisConverterOptions = {}) {
this.analysis = analysis;
this.options = options || {};
this._excludes = new Set(this.options.excludes);
this._referenceExcludes = new Set(this.options.referenceExcludes);
this.rootModuleName = options.rootModuleName;
this._excludes = new Set(options.excludes);
this._referenceExcludes = new Set(options.referenceExcludes);
this._mutableExports = options.mutableExports;
}

async convert(): Promise<Map<string, string>> {
Expand Down Expand Up @@ -276,7 +302,7 @@ class DocumentConverter {

constructor(analysisConverter: AnalysisConverter, document: Document) {
this.analysisConverter = analysisConverter;
this._mutableExports = <any>Object.assign({}, this.analysisConverter.options.mutableExports);
this._mutableExports = <any>Object.assign({}, this.analysisConverter._mutableExports);
this.document = document;
this.jsUrl = htmlUrlToJs(document.url);
this.module = {
Expand Down Expand Up @@ -340,7 +366,7 @@ class DocumentConverter {
// with module exports.
while (this.currentStatementIndex < this.program.body.length) {
const statement = this.program.body[this.currentStatementIndex] as Statement;
const exported = getExport(statement, 'Polymer');
const exported = getExport(statement, this.analysisConverter.rootModuleName);

if (exported !== undefined) {
const {namespace, value} = exported;
Expand Down Expand Up @@ -822,7 +848,7 @@ function isDeclaration(node: Node) {
*
* @param moduleRoot If specified
*/
function getExport(statement: Statement | ModuleDeclaration, rootModuleName: string): {namespace: string[], value: Expression} |undefined {
function getExport(statement: Statement | ModuleDeclaration, rootModuleName?: string): {namespace: string[], value: Expression} |undefined {
if (!(statement.type === 'ExpressionStatement'
&& statement.expression.type === 'AssignmentExpression')) {
return undefined;
Expand Down
19 changes: 15 additions & 4 deletions src/test/html2js_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ suite('html2js', () => {
})
});

async function getJs(options?: AnalysisConverterOptions) {
async function getJs(partialOptions?: Partial<AnalysisConverterOptions>) {
const options: AnalysisConverterOptions = Object.assign({
rootModuleName: 'Polymer',
}, partialOptions);
const analysis = await analyzer.analyze(['test.html']);
const testDoc = analysis.getDocument('test.html') as Document;
const converter = new AnalysisConverter(analysis, options);
Expand All @@ -37,7 +40,9 @@ suite('html2js', () => {

async function getConverted(): Promise<Map<string, string>> {
const analysis = await analyzer.analyze(['test.html']);
const converter = new AnalysisConverter(analysis);
const converter = new AnalysisConverter(analysis, {
rootModuleName: 'Polymer',
});
return converter.convert();
}

Expand Down Expand Up @@ -579,6 +584,7 @@ export const isDeep = isPath;
});
const analysis = await analyzer.analyze(['test.html']);
const converter = new AnalysisConverter(analysis, {
rootModuleName: 'Polymer',
excludes: ['exclude.html'],
});
const converted = await converter.convert();
Expand All @@ -597,6 +603,7 @@ class MyElement extends $Element {}\n`);
});
const analysis = await analyzer.analyze(['test.html']);
const converter = new AnalysisConverter(analysis, {
rootModuleName: 'Polymer',
referenceExcludes: ['Polymer.DomModule'],
});
const converted = await converter.convert();
Expand Down Expand Up @@ -680,7 +687,9 @@ class TestElement extends Polymer.Element {

test('case-map', async () => {
const analysis = await analyzer.analyze(['case-map/case-map.html']);
const converter = new AnalysisConverter(analysis);
const converter = new AnalysisConverter(analysis, {
rootModuleName: 'Polymer',
});
const converted = await converter.convert();
const caseMapSource = converted.get('./case-map/case-map.js');
assert.include(caseMapSource!, 'export function dashToCamelCase');
Expand All @@ -691,7 +700,9 @@ class TestElement extends Polymer.Element {
const filename = 'polymer-element/polymer-element.html';
const analysis = await analyzer.analyze([filename]);
const doc = analysis.getDocument(filename) as Document;
const converter = new AnalysisConverter(analysis);
const converter = new AnalysisConverter(analysis, {
rootModuleName: 'Polymer',
});
converter.convertDocument(doc);
assert(converter.namespacedExports.has('Polymer.Element'));
});
Expand Down
Loading

0 comments on commit a1d4f64

Please sign in to comment.