///
///
///
///
///
import * as sourceMapSupport from 'source-map-support';
sourceMapSupport.install();
import * as fs from "fs";
import * as path from "path";
import * as webpack from "webpack";
const MemoryFileSystem = require("./memoryfs");
const name = 'g6';
export interface IInstance {
location: string;
folder: string;
}
function _requireNotCached(path: string) {
const r = eval("require");
delete r.cache[path];
return r(path);
}
function _require(path: string) {
const r = eval("require");
return r(path);
}
export function resolve(options: { which?: boolean } = {}): Promise {
return new Promise((resolve, reject) => {
const resolve_if_at = (location, folder) => {
const js_path = path.join(folder, 'bin', name + ".js");
const package_path = path.join(folder, 'package.json');
if (!fs.existsSync(folder) || !fs.existsSync(js_path) || !fs.existsSync(package_path))
return false;
resolve({ location, folder } as IInstance);
return true;
};
if (resolve_if_at("command line", path.dirname(process.argv[1]).split(path.delimiter).slice(0, -1).join(path.delimiter)))
return;
try {
const folder = eval("require").resolve(name);
if (resolve_if_at("local", folder.slice(0, -("/bin/" + name + ".js".length))))
return;
} catch (e) { }
if (process.env.NODE_PATH && !process.env.NODE_PATH.split(path.delimiter).every(p =>
!resolve_if_at("global", path.normalize(path.join(p, name)))))
return;
if (resolve_if_at("sibling", path.normalize(path.join(__dirname, '..', '..', name))))
return;
reject('Cannot find ' + name + '.\nPlease install it locally with:\n\n npm install ' + name + ' --save-dev\n\n' +
'Or globally with:\n\n npm install ' + name + ' -g');
});
}
export interface SpecExpectation {
matcherName: string;
message: string;
stack: string;
passed: boolean;
}
export interface SpecResult {
fullName: string;
description: string;
failedExpectations: SpecExpectation[];
passedExpectations: SpecExpectation[];
}
export async function spawnTest(specFile: string) {
return new Promise((resolve, reject) => {
var child_process = require("child_process");
console.log("Testing " + specFile + "...");
const _process = child_process.fork(path.resolve(package_folder, "bin/g6.jasmine.js"), [specFile]);
_process.on("close", (code) => {
console.log("exiting with code " + code);
if (code) {
reject();
return;
}
resolve();
});
});
}
export async function test(from_path = process.cwd()) {
if (!loader_folder)
init((await resolve()).folder);
const workspace = await getWorkspace(from_path);
for (const project of workspace.projects) {
const output_folder = path.join(project.package_folder, "bin");
// console.log("checking " + output_folder);
const fail_file = path.join(output_folder, ".fail");
try {
for (const spec of await find_files(output_folder, null, null, file_info => file_info.file.endsWith(".spec.js")))
await spawnTest(spec.file);
} catch (error) {
fs.writeFileSync(fail_file, error);
throw error;
}
if (fs.existsSync(fail_file))
fs.truncateSync(fail_file);
// const failed_specs: SpecResult[] = [];
// for (const spec_result of await executeSpecs(spec_files, {}))
// if ((spec_result as any).failedExpectations && (spec_result as any).failedExpectations.length)
// failed_specs.push(spec_result);
// if (failed_specs.length) {
// for (const spec of failed_specs) {
// console.log();
// console.log("Spec failed: " + spec.fullName);
// for (const expectataion of spec.failedExpectations) {
// // console.log(expectataion.message)
// console.log(expectataion.stack);
// console.log();
// }
// console.log();
// }
// fs.writeFileSync(fail_file, JSON.stringify(failed_specs));
// throw new Error("failed specs");
// }
}
}
let package_folder: string = null;
let loader_folder: string = null;
export function init(folder: string) {
package_folder = folder;
loader_folder = path.join(folder, "node_modules");
}
function spliceFilenameDottedParts(index: number, delete_count: number, insert: string = undefined) {
return (_path: any) => {
var parts = _path.split('.');
if (insert)
parts.splice(index, delete_count, insert);
else
parts.splice(index, delete_count);
_path = parts.join('.');
return _path;
}
}
export async function clean(from_path = process.cwd()) {
function remove_folder(path: string) {
remove_files(path);
fs.rmdirSync(path);
};
function remove_files(path: string) {
if (!fs.existsSync(path))
return;
for (const full_path of fs.readdirSync(path).map((p: string) => path + "/" + p)) {
if (fs.lstatSync(full_path).isDirectory())
remove_folder(full_path);
else
fs.unlinkSync(full_path);
}
}
remove_files(path.join(from_path, 'bin'));
}
export type EntryPointKind = "web" | "node" | "electron" | "test-web" | "test-node";
export class EntryPoint {
constructor(public project: Project, public kind: EntryPointKind, public file_info: IFileInfo, public build_config: IBuildConfig) { }
}
export interface IProjectReference {
project: Project;
version: string;
}
export type DependencyMap = { [name: string]: IProjectReference[] };
export interface IBuildConfig {
kind: EntryPointKind;
extension: string;
config: (project: Project, entry_point: EntryPoint, entry_points: EntryPoint[]) => { webpack_config: any };
}
export class Project {
public name: string;
public version: string;
public package_json: any;
public package_path: any;
constructor(public package_folder: string) {
try {
this.package_path = path.join(package_folder, "package.json");
try {
this.package_json = JSON.parse(fs.readFileSync(this.package_path).toString());
} catch (error) { }
this.name = this.package_json.name;
this.version = this.package_json.version;
} catch (error) {
}
}
async getLastModified(workspace?: Workspace) {
const files = await find_files(this.package_folder,
(folder_or_file_name: string) =>
folder_or_file_name[0] !== '.' && !ignore_paths[folder_or_file_name],
(filter_from_path: string, file_info: IFileInfo[]) => {
const result = filter_from_path === this.package_folder || file_info.every(f => f.file !== "package.json");
return result;
},
(file_info: IFileInfo) => {
const file_name = file_info.file.toLowerCase();
return file_name.endsWith(".ts")
|| file_name.endsWith(".json")
|| file_name.endsWith(".js");
});
let latest_modified = new Date(0);
for (const file of files)
if (file.stat.mtime.getTime() > latest_modified.getTime())
latest_modified = file.stat.mtime;
if (workspace) {
for (const dep of workspace.getAllDependencies(this)) {
const latest_dep_built = await dep.project.getLastBuilt();
if (latest_dep_built.getTime() > latest_modified.getTime())
latest_modified = latest_dep_built;
}
}
return latest_modified;
}
async getLastBuilt() {
const output_folder = path.join(this.package_folder, "bin");
// console.log("checking " + output_folder);
const files = await find_files(output_folder, null, null, file_info => true);
let oldest_built: Date;
for (const file of files)
if (!oldest_built || oldest_built.getTime() > file.stat.mtime.getTime())
oldest_built = file.stat.mtime;
return oldest_built || new Date(0);
}
getFailedTests() {
return fs.existsSync(path.join(this.package_folder, "bin/.fail"));
}
}
function getProject(from_path: string): Promise {
// console.log("getProject " + from_path);
return new Promise((resolve: (project: Project) => void, reject: Function) => {
let last_candidate_path: string = undefined;
let candidate_path = from_path;
while (candidate_path && candidate_path !== last_candidate_path) {
// console.log("checking " + candidate_path);
const project = new Project(candidate_path);
if (project.package_json) {
resolve(project);
return;
}
last_candidate_path = candidate_path;
candidate_path = path.resolve(candidate_path, "..");
}
// console.log("rejecting");
reject("No package.json file found in this or parent folders");
})
}
const ignore_paths: { [folder_name: string]: boolean } = {
"node_modules": true,
"bin": true
};
export class Workspace {
public projects: Project[];
public dependencies: DependencyMap;
private Workspace() { }
static async create(from_path: string) {
const workspace = new Workspace();
workspace.projects = await getProjects(from_path);
workspace.dependencies = getDependencies(workspace.projects);
return workspace;
}
getAllDependencies(project: Project, except: { [name: string]: boolean } = {}) {
let result = this.dependencies[project.name].filter(p => !except[p.project.name]);
// console.log("getAllDependencies of project: " + project.name + " = " + result.map(r => r.project.name));
for (const dependency of result)
except[dependency.project.name] = true;
for (const dependency of result.slice())
result = result.concat(this.getAllDependencies(dependency.project, except));
return result;
}
getAllDependents(project: Project) {
return this.projects.filter(p => !!this.getAllDependencies(p).find(d => d.project.name == project.name));
}
getProject = (name: string) => this.projects.find(p => p.name === name);
async getEntryPoints(project?: Project): Promise {
if (!project) {
let entry_points = await Promise.all(this.projects.map(p => this.getEntryPoints(p)));
const result = entry_points.reduce((prev, current) => prev.concat(current), []);
// console.log("result: " + JSON.stringify(result));
return result;
}
// console.log("getting entry points for project: " + JSON.stringify(project.package_folder));
const include_file_or_folder = name =>
name[0] !== '.' && !ignore_paths[name];
const include_folder = (from_path, file_info) =>
from_path === project.package_folder || file_info.every(f => f.file !== "package.json");
const build_configs: IBuildConfig[] = [
{ kind: "node", extension: ".entry.ts", config: configNode },
{ kind: "electron", extension: ".entry.electron.ts", config: configElectron },
{ kind: "test-node", extension: ".spec.node.ts", config: configTestNode },
];
const include_file = (file_info: IFileInfo) => {
const file_name = file_info.file.toLowerCase();
return !!build_configs.find(build_config => file_name.endsWith(build_config.extension));
};
const files = await find_files(project.package_folder, include_file_or_folder, include_folder, include_file);
// console.log("entry points: " + JSON.stringify(files.map(f => f.file)));
return files.map(f => new EntryPoint(project, "node", f, build_configs.find(build_config => f.file.endsWith(build_config.extension))));
}
}
function getExternals(entry_point: EntryPoint, entry_points: EntryPoint[]) {
const o = {};
Object.assign(o, getInstalledNodeModules(entry_point.project.package_folder));
Object.assign(o, getOtherEntryPointModules(entry_point, entry_points));
if (entry_point.build_config.kind === "electron")
o["electron"] = "commonjs electron-prebuilt";
// console.log("externals: " + JSON.stringify(o));
return o;
}
function getOtherEntryPointModules(this_entry_point: EntryPoint, entry_points: EntryPoint[]) {
var modules: { [name: string]: string } = {};
for (const entry_point of entry_points.filter(ep => ep !== this_entry_point)) {
let name = path.basename(entry_point.file_info.file, ".ts");
const extension = entry_point.build_config.extension.slice(0, -3);
// console.log("extension: '" + extension + "'")
let new_name = name;
if (new_name.endsWith(extension))
new_name = new_name.slice(0, -extension.length);
// console.log("name: " + name + ", new_name: '" + new_name + "'")
modules[name] = "commonjs " + new_name;
modules["./" + name] = "commonjs " + new_name;
modules["../" + name] = "commonjs " + new_name;
modules["../../" + name] = "commonjs " + new_name;
}
// console.log("OEP: " + JSON.stringify(modules));
return modules;
}
function getInstalledNodeModules(from_path: string) {
var modules: { [name: string]: string } = {};
const node_modules_path = path.join(from_path, 'node_modules');
if (fs.existsSync(node_modules_path))
fs.readdirSync(node_modules_path)
.filter((x: any) => ['.bin'].indexOf(x) === -1)
.forEach((mod: any) => {
modules[mod] = 'commonjs ' + mod;
});
return modules;
}
function configNode(project: Project, entry_point: EntryPoint, entry_points: EntryPoint[]) {
return {
webpack_config: {
target: 'node',
resolve: {
extensions: ['', '.ts', '.tsx', '.json', '.js']
},
entry: entry_point.file_info.file,
devtool: 'source-map',
context: project.package_folder,
output: {
path: path.resolve(project.package_folder, "bin"),
filename: path.basename(entry_point.file_info.file, ".ts") + ".js",
libraryTarget: 'commonjs',
devtoolModuleFilenameTemplate: "[absolute-resource-path]",
devtoolFallbackModuleFilenameTemplate: "[absolute-resource-path]?[hash]"
},
module: {
loaders: [
{ test: /\.tsx?$/, loader: 'awesome-typescript-loader?declaration=true&useBabel=false&forkChecker=false&moduleResolution=node&forceConsistentCasingInFileNames=true' },
{ test: /\.json$/, loader: 'json-loader' }
]
},
devServer: {
port: 80,
inline: true,
hot: true
},
resolveLoader: {
root: loader_folder
},
externals: getExternals(entry_point, entry_points)
}
};
}
function configTestNode(project: Project, entry_point: EntryPoint, entry_points: EntryPoint[]) {
const config = configNode(project, entry_point, entry_points);
config.webpack_config.output.filename = 'tests.node.spec.js';
config.webpack_config.module.loaders = [
{ test: /\.tsx?$/, loader: 'awesome-typescript-loader?useBabel=false&forkChecker=false&moduleResolution=node&forceConsistentCasingInFileNames=true' },
{ test: /\.json$/, loader: 'json-loader' }
];
return config;
}
function configElectron(project: Project, entry_point: EntryPoint, entry_points: EntryPoint[]) {
const config = configNode(project, entry_point, entry_points);
config.webpack_config.target = "electron";
config.webpack_config.module.loaders = [
{ test: /\.tsx?$/, loader: 'awesome-typescript-loader?useBabel=false&forkChecker=false&moduleResolution=node&forceConsistentCasingInFileNames=true' },
{ test: /\.json$/, loader: 'json-loader' }
];
return config;
}
export async function getWorkspace(from_path: string) {
return await Workspace.create(from_path);
}
async function getProjects(from_path: string) {
const package_files = await find_files(from_path,
(folder_or_file_name: string) =>
folder_or_file_name[0] !== '.' && !ignore_paths[folder_or_file_name],
null,
(file_info: IFileInfo) =>
file_info.file === "package.json");
return package_files.map(f =>
new Project(path.dirname(f.file)))
.filter(f => f.package_json);
}
async function find_files(from_path: string, ignore_file_or_folder_predicate: (folder_name: string) => boolean, folder_predicate: (from_path: string, file_infos: IFileInfo[]) => boolean, file_predicate: (file_info: IFileInfo) => boolean): Promise {
var dir = readDir(from_path, ignore_file_or_folder_predicate);
if (folder_predicate && !folder_predicate(from_path, dir))
return Promise.resolve([]);
const files = dir.filter(d => !d.stat.isDirectory() && (!file_predicate || file_predicate(d)))
.map(f => ({ file: path.join(from_path, f.file), stat: f.stat }));
const folders = dir.filter(d => d.stat.isDirectory());
const promises = folders.map(folder =>
find_files(path.join(from_path, folder.file), ignore_file_or_folder_predicate, folder_predicate, file_predicate));
const found_in_folders = await Promise.all(promises);
const files_found_in_folders = found_in_folders.reduce((previous, current) => previous.concat(current), []);
return files.concat(files_found_in_folders);
};
export interface IFileInfo {
file: string;
stat: any;
}
function readDir(from_path: string, predicate: (name: string) => boolean): IFileInfo[] {
try {
return (fs.readdirSync(path.normalize(from_path)) as string[])
.filter(f => !predicate || predicate(f))
.map(file => {
try {
return { file, stat: fs.statSync(path.resolve(from_path, file)) };
} catch (error) {
return null;
}
})
.filter(f => !!f);
} catch (error) {
return [];
}
}
function getFolders(from_path: string, ignore: (folder_name: string) => boolean) {
return readDir(from_path, ignore)
.filter(entry => !!entry && entry.stat && entry.stat.isDirectory());
}
function getDependencies(projects: Project[]) {
var result: DependencyMap = {};
for (const project of projects) {
var dev_dependencies: { [name: string]: string } = project.package_json.devDependencies || {};
// console.log("dependencies: " + JSON.stringify(dev_dependencies));
result[project.name] = [];
for (const name in dev_dependencies)
if (dev_dependencies.hasOwnProperty(name)) {
const referenced = projects.filter(p => p.name === name)[0];
if (referenced)
result[project.name].push({ project: referenced, version: dev_dependencies[name] });
}
}
return result;
}
// return new Promise((resolve: Function, reject: Function) => {
// function endsWith(value: string, ends_with: string) {
// if (value.length < ends_with.length)
// return false;
// return value.slice(-ends_with.length) === ends_with;
// }
// const entry_points: EntryPoint[] = [];
// function check_files(files: string[]) {
// for (var file of files) {
// if (endsWith(file, ".spec.ts"))
// entry_points.push(new EntryPoint("test-web", file))
// if (endsWith(file, ".spec.node.ts"))
// entry_points.push(new EntryPoint("test-node", file))
// if (endsWith(file, ".entry.ts"))
// entry_points.push(new EntryPoint("node", file))
// if (endsWith(file, ".entry.web.ts"))
// entry_points.push(new EntryPoint("web", file))
// }
// }
// // dir.files(__dirname, (err: any, files: string[]) => {
// // if (err)
// // reject(err);
// // else
// // check_files(files)
// // }, () => resolve(entry_points));
// })
// }
const chokidar = require("chokidar");
export async function watch(from_path = process.cwd()) {
const w = await getWorkspace(from_path);
const this_project = w.projects[0];
if (!w || !this_project)
return Promise.resolve();
let buildNeeded = true;
// const p = await getProject(process.cwd());
for (const p of w.projects)
chokidar.watch(p.package_folder, {
ignoreInitial: true,
cwd: p.package_folder,
ignored: [
/[\/\\]\./,
'**/node_modules/**/*',
'**/bin/**/*'
]
})
.on("all", (event: any, path: any) => {
if (event == "addDir")
return;
// console.log("file " + event + " " + path);
buildNeeded = true;
});
let building = false;
async function buildIfNeeded() {
if (buildNeeded && !building) {
// console.log("build needed...");
buildNeeded = false;
building = true;
try {
await build(from_path);
}
catch (error) {
console.log("build errors: " + error);
}
finally {
building = false;
console.log("watch...");
}
}
setTimeout(() => buildIfNeeded().catch(error => console.error(error)));
}
await buildIfNeeded().catch(error => console.log(error));
}
var mkdirSync = function (path) {
if (fs.existsSync(path))
return;
try {
fs.mkdirSync(path);
} catch (e) {
if (e.code != 'EEXIST') throw e;
}
}
var mkdirpSync = function (dirpath) {
var parts = dirpath.split(path.sep);
for (var i = 1; i <= parts.length; i++) {
mkdirSync(path.join.apply(null, parts.slice(0, i)));
}
}
async function buildNode(workspace: Workspace) {
let built: { [name: string]: boolean } = {};
let queued: { [name: string]: Project } = {};
let keys = (o: { [name: string]: any }) => {
const result = [];
for (const key in o)
if (o.hasOwnProperty(key))
result.push(key)
return result;
}
const modified_projects = [];
for (const p of workspace.projects)
if ((await p.getLastModified(workspace)) > (await p.getLastBuilt()))
modified_projects.push(p);
else if (!p.getFailedTests())
built[p.name] = true;
// console.log("modified_projects: " + modified_projects.map(p => p.name).join(", "));
const to_queue = modified_projects.map(p => [p].concat(workspace.getAllDependents(p))).reduce((prev, current) => prev.concat(current), []);
// console.log("to_queue: " + to_queue.map(p => p.name).join(", "));
const to_build = [];
for (const p of to_queue)
if ((await workspace.getEntryPoints(p)).length)
to_build.push(p);
// console.log("to_build: " + to_build.map(p => p.name).join(", "));
if (!to_build.length) {
console.log("everything is up-to-date")
}
for (const project of to_build)
queued[project.name] = project;
// console.log("queued: " + JSON.stringify(queued));
while (true) {
const queued_projects = keys(queued).map(n => queued[n]);
if (!queued_projects.length)
break;
const ready_to_run = queued_projects.filter(p => {
const deps = workspace.getAllDependencies(p);
// console.log("dependencies of " + p.name + " are " + deps.map(d => d.project.name).join(", "));
return deps.every(d =>
built[d.project.name]);
});
if (!ready_to_run.length)
throw new Error("Unmet dependencies - can't build any of:" + queued_projects.map(p => p.name).join(",") + "\nUse 'g6 list' to diagnose.")
// console.log("ready_to_run: " + ready_to_run.map(p => p.name).join(", "));
for (const project of ready_to_run) {
const entry_points = await workspace.getEntryPoints(project);
if (entry_points.length) {
await buildNodeProject(workspace, project, entry_points);
}
built[project.name] = true;
delete queued[project.name];
}
}
}
async function buildNodeProject(workspace: Workspace, project: Project, entry_points: EntryPoint[]) {
// console.log("build '" + project.name + "'...");// with " + entry_points.length + " entry points");
await clean(project.package_folder);
const configs = entry_points.map(entry_point => Object.assign({}, entry_point.build_config.config(entry_point.project, entry_point, entry_points).webpack_config));
// console.log("webpacking: " + JSON.stringify(configs));
process.chdir(project.package_folder);
var memory_fs = new MemoryFileSystem();
var compiler = webpack(configs);
compiler.outputFileSystem = memory_fs;
const build_result = await new Promise((resolve, reject) => {
compiler.run((err, stats) => {
try {
if (err) {
reject(err);
return;
}
if (stats.hasErrors()) {
reject("\n\nError/s: ---------------------------------------------------------\n\n" + stats.toJson({
reasons: true,
errorDetails: true,
timings: true
}).errors.map(e => e.startsWith("(undefined) [default] ") ? e.slice("(undefined) [default] ".length) : e).join("\n") + "\n\n------------------------------------------------------------------\n\n\n");
return;
}
const output_folder = path.resolve(project.package_folder, "bin");
function copy_files(from_folder) {
var files = memory_fs.readdirSync(from_folder);
for (var file of files) {
const file_path = path.join(from_folder, file);
// console.log("checking file_path: " + file_path);
var stat = memory_fs.statSync(file_path);
if (stat.isDirectory()) {
// console.log("found folder: " + file_path);
copy_files(file_path);
} else {
var contents = memory_fs.readfilesync(file_path);
let new_file_path = file_path;
for (const ep of entry_points) {
let config_entry = path.basename(ep.file_info.file, ".ts");
let file_basename = path.basename(file_path);
// console.log("checking config for file: " + file_basename + " vs " + config_entry + ".d.ts");
if (file_basename === config_entry + ".js") {
new_file_path = file_path.slice(0, -ep.build_config.extension.length) + ".js";
const lines: string[] = contents.toString().split(/\r?\n/);
const package_json = project.package_json;
const bin = package_json.bin;
// console.log("checking project.package_json.bin for : " + new_file_path + ", using " + JSON.stringify(package_json));
if (bin)
for (var key in bin)
if (bin.hasOwnProperty(key)) {
const _path = bin[key];
const path_of_command = path.resolve(project.package_folder, _path);
if (path_of_command === new_file_path) {
lines.splice(0, 0, "#!/usr/bin/env/node");
break;
}
}
const last_line = lines[lines.length - 1];
const map_name = ep.build_config.extension.slice(0, -3) + ".js.map";
if (last_line.startsWith("//# sourceMappingURL=") && last_line.endsWith(map_name))
lines[lines.length - 1] = last_line.slice(0, last_line.length - map_name.length) + ".js.map";
lines.push("//# sourceURL=" + config_entry + ".ts");
contents = lines.join("\n");
console.log("building " + ep.build_config.kind + ": " + new_file_path);
} else if (file_basename === config_entry + ".d.ts") {
new_file_path = file_path.slice(0, -(ep.build_config.extension.length + ".d".length)) + ".d.ts";
} else if (file_basename === config_entry + ".js.map") {
new_file_path = file_path.slice(0, -(ep.build_config.extension.length + ".map".length)) + ".js.map";
const map_file = JSON.parse(contents) as {
"version": number,
"file": string,
"sourceRoot": string,
"sources": string[],
"sourcesContent": string[],
"names": string[],
"mappings": string
};
if (map_file.file.endsWith(ep.build_config.extension))
map_file.file = map_file.file.slice(0, -ep.build_config.extension.length) + ".js"
map_file.sourcesContent = map_file.sourcesContent.map(c => null);
map_file.sourceRoot = ""; //path.relative(output_folder, project.package_folder);
map_file.sources = map_file.sources.map(s => {
s = path.isAbsolute(s) ? s : path.resolve(s);
s = path.relative(output_folder, s);
return s.replace(/\\/g, "/");
});
contents = JSON.stringify(map_file);
}
}
if (new_file_path.endsWith(".d.ts")) {
// console.log("filtering triple-slash comment lines from: " + file_basename);
contents = contents.toString().split(/\r?\n/).filter((l: string) => !l.startsWith("///")).join('\n');
// console.log("moving .d.ts");
const name = path.basename(new_file_path);
// console.log("name: " + name);
new_file_path = path.join(output_folder, name);
// console.log("to " + new_file_path);
}
mkdirpSync(path.dirname(new_file_path));
if (!fs.existsSync(new_file_path))
fs.writeFileSync(new_file_path, contents);
}
}
}
if (!memory_fs.existsSync(output_folder))
console.log("no output for: " + project.name);
else
copy_files(output_folder);
resolve(stats);
} catch (error) {
reject(error);
}
});
});
await test(project.package_folder);
return build_result;
}
export async function build(from_path = process.cwd()) {
const webpack = require('webpack');
const ws = await getWorkspace(from_path);
if (!loader_folder)
init((await resolve()).folder);
// function buildWeb(source: any, target: any, renameTo: string | Function): Promise {
// if (!source)
// return Promise.resolve();
// const config = {
// resolve: {
// extensions: ['', '.ts', '.tsx']
// },
// resolveLoader: {
// root: path.join(__dirname, "node_modules")
// },
// // devtool: 'inline-source-map',
// module: {
// loaders: [
// { test: /\.tsx?$/, loader: 'awesome-typescript-loader?useBabel=false&forkChecker=false&moduleResolution=node&forceConsistentCasingInFileNames=true' }
// ]
// },
// devServer: {
// port: 80,
// inline: true,
// hot: true
// },
// target
// };
// console.log("buildWeb: " + JSON.stringify(config));
// return gulp_promise(source
// .pipe(sourcemaps.init())
// .pipe(webpack(config, null, (err: any, stats: string) => {
// if (err)
// throw err;
// // console.log("stats: " + stats);
// }))
// .pipe(rename(renameTo))
// // .pipe(uglify())
// .pipe(sourcemaps.write('.', { sourceRoot: '.' }))
// .pipe(gulp.dest("bin")));
// }
// console.log("building...");
// console.log("building node outputs...");
const promises = [
// buildWeb(src_exists('**/*.entry.web.ts'), "web", removeSegment),
buildNode(ws),
// buildWeb(src_exists('**/*.spec.ts'), "web", "specs.js"),
// buildNode(process.cwd(), src_exists('**/*.spec.node.ts'), "tests/node.spec.js")
];
await Promise.all(promises);
}
export async function testWeb() {
return new Promise(async function (resolve: Function, reject: Function) {
await build();
console.log("Testing...");
const karma = require('karma');
const karma_config = {
basePath: '',
frameworks: ['jasmine'],
files: ['bin/specs.js'],
reporters: ['progress', 'junit'],
port: 9876,
colors: true,
autoWatch: true,
browsers: ['Firefox'],
singleRun: true,
junitReporter: {
outputDir: process.env.CIRCLE_ARTIFACTS || "bin",
outputFile: 'junit.xml'
}
};
new karma.Server(karma_config, () => resolve()).start();
})
}