Skip to content

Commit 477091a

Browse files
authored
Merge pull request #171 from pie-framework/feature/mk-item-app-archiveable
Feature/mk item app archiveable
2 parents 25f3246 + d0c8899 commit 477091a

8 files changed

Lines changed: 743 additions & 10170 deletions

File tree

package-lock.json

Lines changed: 496 additions & 457 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
},
7575
"dependencies": {
7676
"@pie-cli-libs/installer": "^1.5.4",
77+
"@pie-cli-libs/hash": "^1.5.1",
7778
"ajv": "^5.2.1",
7879
"archiver": "^2.0.0",
7980
"babel-core": "^6.24.0",

src/apps/create-archive.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,25 @@ const logger = buildLogger();
1212

1313
export function archiveIgnores(dir: string) {
1414
const gitIgnorePath = join(dir, '.gitignore');
15-
const gitIgnores = existsSync(gitIgnorePath) ?
16-
readFileSync(gitIgnorePath, 'utf8').split('\n').map(s => s.trim()) : [];
17-
18-
return _(gitIgnores).concat([
19-
'.pie',
20-
'\.*',
21-
'package.json',
22-
'*.tar.gz'
23-
]).uniq().value();
15+
const gitIgnores = existsSync(gitIgnorePath)
16+
? readFileSync(gitIgnorePath, 'utf8')
17+
.split('\n')
18+
.map(s => s.trim())
19+
: [];
20+
21+
return _(gitIgnores)
22+
.concat(['.pie', '.*', 'package.json', '*.tar.gz'])
23+
.uniq()
24+
.value();
2425
}
2526

2627
export function createArchive(
2728
name: string,
2829
cwd: string,
2930
ignore: string[],
30-
addExtras: (a: any) => void): Promise<string> {
31+
addExtras?: (a: any) => void
32+
): Promise<string> {
3133
return new Promise<string>((resolve, reject) => {
32-
3334
const archiveName = name.endsWith('.tar.gz') ? name : `${name}.tar.gz`;
3435

3536
const output = createWriteStream(archiveName);
@@ -40,15 +41,17 @@ export function createArchive(
4041
resolve(archiveName);
4142
});
4243

43-
archive.on('error', (err) => {
44+
archive.on('error', err => {
4445
reject(err);
4546
});
4647

4748
archive.pipe(output);
4849

4950
archive.glob('**', { cwd, ignore });
5051

51-
addExtras(archive);
52+
if (addExtras) {
53+
addExtras(archive);
54+
}
5255

5356
archive.finalize();
5457
});

src/apps/default/index.ts

Lines changed: 121 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@ import * as _ from 'lodash';
22
import * as generators from './src-generators';
33
import * as pug from 'pug';
44

5-
import { App, Buildable, DefaultOpts, MakeManifest, ManifestOpts } from '../types';
5+
import {
6+
App,
7+
Buildable,
8+
DefaultOpts,
9+
MakeManifest,
10+
ManifestOpts,
11+
Archivable
12+
} from '../types';
613
import { ElementDeclaration, buildWebpack, writeConfig } from '../../code-gen';
714
import Install, {
815
Dirs,
@@ -16,20 +23,26 @@ import { join, resolve } from 'path';
1623

1724
import { SupportConfig } from '../../framework-support';
1825
import { promise as report } from '../../cli/report';
19-
import { webpackConfig } from '../common';
26+
import { webpackConfig, Out } from '../common';
2027
import { writeFileSync } from 'fs-extra';
28+
import { archiveIgnores, createArchive } from '../create-archive';
29+
import { addExtras } from '../catalog';
30+
import { buildLogger } from 'log-factory';
2131

32+
const logger = buildLogger();
2233
const basicExample = join(__dirname, 'views/example.pug');
2334

2435
const ENCODING = { encoding: 'utf8' };
2536

26-
const writeFile = (name: string, contents: string) => writeFileSync(name, contents, ENCODING);
37+
const writeFile = (name: string, contents: string) =>
38+
writeFileSync(name, contents, ENCODING);
2739

2840
export default class DefaultApp
29-
implements Buildable<string[], DefaultOpts>,
30-
App,
31-
MakeManifest {
32-
41+
implements
42+
Buildable<string[], DefaultOpts>,
43+
App,
44+
MakeManifest,
45+
Archivable<Pkg[]> {
3346
public static generatedFiles: string[] = [
3447
'pie-item.js',
3548
'pie-view.js',
@@ -38,20 +51,29 @@ export default class DefaultApp
3851
'example.html'
3952
];
4053

41-
public static build(args: any, loadSupport: (JsonConfig) => Promise<SupportConfig>): Promise<DefaultApp> {
54+
public static build(
55+
args: any,
56+
loadSupport: (JsonConfig) => Promise<SupportConfig>
57+
): Promise<DefaultApp> {
4258
const dir = resolve(args.dir || args.d || process.cwd());
4359
const config = JsonConfig.build(dir, args);
44-
return loadSupport(config).then(s => new DefaultApp(config, s));
60+
const outNames = Out.build(args);
61+
return loadSupport(config).then(s => new DefaultApp(config, s, outNames));
4562
}
4663

4764
private static CONFIGURE_ENTRY = 'default.configure.entry.js';
4865
private static CONFIGURE_BUNDLE = 'pie-configure.js';
49-
private static CONFIGURE_WEBPACK_CONFIG = 'default.configure.webpack.config.js';
66+
private static CONFIGURE_WEBPACK_CONFIG =
67+
'default.configure.webpack.config.js';
5068

5169
private template: pug.compileTemplate;
5270
private installer: Install;
5371

54-
constructor(readonly config: JsonConfig, private support: SupportConfig) {
72+
constructor(
73+
readonly config: JsonConfig,
74+
private support: SupportConfig,
75+
private outNames: Out
76+
) {
5577
this.template = pug.compileFile(basicExample, { pretty: true });
5678
this.installer = new Install(config.dir, config.raw);
5779
}
@@ -64,13 +86,27 @@ export default class DefaultApp
6486
const forceInstall = opts ? opts.forceInstall : false;
6587

6688
const { pkgs, dirs } = await this.installer.install(forceInstall);
67-
const client = await report('building client', this.buildClient(dirs, pkgs, opts.addPlayerAndControlPanel));
68-
const controllers = await report('building controllers', this.buildControllers(dirs, opts.pieName, pkgs));
69-
const configure = await report('building configure', this.buildConfigure(dirs, pkgs));
70-
const allInOne = opts.includeComplete ?
71-
await report('building all-in-one', this.buildAllInOne(dirs, opts.pieName, pkgs)) : [];
72-
const example = opts.includeComplete ?
73-
await report('building example', this.buildExample()) : [];
89+
const client = await report(
90+
'building client',
91+
this.buildClient(dirs, pkgs, opts.addPlayerAndControlPanel)
92+
);
93+
const controllers = await report(
94+
'building controllers',
95+
this.buildControllers(dirs, opts.pieName, pkgs)
96+
);
97+
const configure = await report(
98+
'building configure',
99+
this.buildConfigure(dirs, pkgs)
100+
);
101+
const allInOne = opts.includeComplete
102+
? await report(
103+
'building all-in-one',
104+
this.buildAllInOne(dirs, opts.pieName, pkgs)
105+
)
106+
: [];
107+
const example = opts.includeComplete
108+
? await report('building example', this.buildExample())
109+
: [];
74110

75111
return _.concat(client, controllers, configure, allInOne, example);
76112
}
@@ -79,17 +115,44 @@ export default class DefaultApp
79115
return Promise.reject(new Error('todo'));
80116
}
81117

82-
private async buildConfigure(dirs: Dirs, pkgs: Pkg[]): Promise<string[]> {
118+
public async createArchive(buildInfo: Pkg[]): Promise<string> {
119+
const archivePath = resolve(join(this.config.dir, this.outNames.archive));
120+
121+
/* TODO: ignore config/markup? */
122+
const ignores = archiveIgnores(this.config.dir);
83123

84-
const js = configureDeclarations(pkgs).map(e => e.js).join('\n');
124+
logger.silly(
125+
'call createArchive',
126+
archivePath,
127+
this.config.dir,
128+
ignores,
129+
addExtras
130+
);
131+
132+
logger.silly('callAddExtras...');
133+
134+
return createArchive(archivePath, this.config.dir, ignores).catch(e => {
135+
const msg = `Error creating the archive: ${e.message}`;
136+
logger.error(msg);
137+
logger.info(e.stack);
138+
throw new Error(msg);
139+
});
140+
}
141+
142+
private async buildConfigure(dirs: Dirs, pkgs: Pkg[]): Promise<string[]> {
143+
const js = configureDeclarations(pkgs)
144+
.map(e => e.js)
145+
.join('\n');
85146

86147
writeFile(join(dirs.root, DefaultApp.CONFIGURE_ENTRY), js);
87148

88-
const config = webpackConfig(dirs,
149+
const config = webpackConfig(
150+
dirs,
89151
this.support,
90152
DefaultApp.CONFIGURE_ENTRY,
91153
DefaultApp.CONFIGURE_BUNDLE,
92-
this.config.dir);
154+
this.config.dir
155+
);
93156

94157
await buildWebpack(config, DefaultApp.CONFIGURE_WEBPACK_CONFIG);
95158
return [DefaultApp.CONFIGURE_BUNDLE];
@@ -98,23 +161,38 @@ export default class DefaultApp
98161
private async buildClient(
99162
dirs: Dirs,
100163
pkgs: Pkg[],
101-
addPlayerAndControlPanel: boolean): Promise<string[]> {
102-
103-
const js = generators.client(toDeclarations(pkgs).concat(addPlayerAndControlPanel ? [
104-
new ElementDeclaration('pie-player'),
105-
new ElementDeclaration('pie-control-panel')
106-
] : []));
164+
addPlayerAndControlPanel: boolean
165+
): Promise<string[]> {
166+
const js = generators.client(
167+
toDeclarations(pkgs).concat(
168+
addPlayerAndControlPanel
169+
? [
170+
new ElementDeclaration('pie-player'),
171+
new ElementDeclaration('pie-control-panel')
172+
]
173+
: []
174+
)
175+
);
107176

108177
writeFile(join(dirs.root, 'client.entry.js'), js);
109-
const config = webpackConfig(dirs, this.support, 'client.entry.js', 'pie-view.js', this.config.dir);
178+
const config = webpackConfig(
179+
dirs,
180+
this.support,
181+
'client.entry.js',
182+
'pie-view.js',
183+
this.config.dir
184+
);
110185

111186
writeConfig(join(dirs.root, 'client.webpack.config.js'), config);
112187
await buildWebpack(config);
113188
return ['pie-view.js'];
114189
}
115190

116-
private async buildControllers(dirs: Dirs, pieName: string, pkgs: Pkg[]): Promise<string[]> {
117-
191+
private async buildControllers(
192+
dirs: Dirs,
193+
pieName: string,
194+
pkgs: Pkg[]
195+
): Promise<string[]> {
118196
const controllers = controllerTargets(pkgs);
119197

120198
const js = generators.controllers(controllers);
@@ -124,7 +202,8 @@ export default class DefaultApp
124202
this.support,
125203
'controllers.entry.js',
126204
'pie-controllers.js',
127-
this.config.dir);
205+
this.config.dir
206+
);
128207

129208
config.output.library = `pie-controller-${pieName}`;
130209
config.output.libraryTarget = 'umd';
@@ -134,10 +213,15 @@ export default class DefaultApp
134213
return ['pie-controllers.js'];
135214
}
136215

137-
private async buildAllInOne(dirs: Dirs, pieName: string, pkgs: Pkg[]): Promise<string[]> {
138-
216+
private async buildAllInOne(
217+
dirs: Dirs,
218+
pieName: string,
219+
pkgs: Pkg[]
220+
): Promise<string[]> {
139221
if (!pieName) {
140-
throw new Error('You must specify a `pieName` in the args when using `--includeComplete`');
222+
throw new Error(
223+
'You must specify a `pieName` in the args when using `--includeComplete`'
224+
);
141225
}
142226

143227
const controllerMap = controllerTargets(pkgs);
@@ -160,7 +244,8 @@ export default class DefaultApp
160244
this.support,
161245
'all-in-one.entry.js',
162246
'pie-item.js',
163-
this.config.dir);
247+
this.config.dir
248+
);
164249

165250
writeConfig(join(dirs.root, 'all-in-one.webpack.config.js'), config);
166251
await buildWebpack(config);

src/cli/pack.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
import {
2-
types as apps,
3-
clean,
4-
loadApp,
5-
} from '../apps';
1+
import { types as apps, clean, loadApp } from '../apps';
62

7-
import { BuildOpts } from "../apps/types";
3+
import { BuildOpts } from '../apps/types';
84
import CliCommand from './cli-command';
95
import { buildLogger } from 'log-factory';
106
import report from './report';
@@ -20,23 +16,34 @@ class PackCommand extends CliCommand {
2016
const a: apps.App = await loadApp(args);
2117

2218
if (apps.isBuildable<T, BuildOpts>(a)) {
23-
2419
const buildOpts = a.buildOpts(args);
2520

2621
if (buildOpts.clean) {
2722
await report.promise('removing files', clean(a.config.dir));
2823
}
2924

25+
if (buildOpts.createArchive && !apps.isArchivable(a)) {
26+
report.failure(
27+
'tried to create an archive but this isnt supported with this app'
28+
);
29+
return;
30+
}
31+
3032
const result: T = await a.build(buildOpts);
3133
this.cliLogger.info('build complete, run manifest...');
3234

3335
if (buildOpts.createArchive) {
3436
if (apps.isArchivable(a)) {
3537
this.cliLogger.info('creating archive...');
36-
const zip = await report.promise('creating archive', a.createArchive(result));
38+
const zip = await report.promise(
39+
'creating archive',
40+
a.createArchive(result)
41+
);
3742
this.cliLogger.info('archive: ', zip);
3843
} else {
39-
logger.warn('tried to create an archive but this app type isnt archivable');
44+
report.failure(
45+
'tried to create an archive but this app type isnt archivable'
46+
);
4047
}
4148
}
4249

@@ -50,7 +57,6 @@ class PackCommand extends CliCommand {
5057
return {
5158
msg: 'pack complete'
5259
};
53-
5460
} else {
5561
logger.warn('this app isnt buildable');
5662
}

0 commit comments

Comments
 (0)