-
Notifications
You must be signed in to change notification settings - Fork 1
/
Packito.js
137 lines (129 loc) · 3.66 KB
/
Packito.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/**
* Copyright (c) Mik BRY
* mik@miklabs.com
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import fs from 'fs';
import path from 'path';
import spawn from './utils/spawn';
const fsp = fs.promises;
export default class Packito {
constructor(outputDir, noPublish, publisherArguments) {
this.outputDir = outputDir;
this.noPublish = noPublish;
this.publisherArguments = publisherArguments;
}
async readJSONFile(fileName, dir = './') {
const f = path.join(dir, fileName);
let filehandle = null;
let result = null;
try {
filehandle = await fsp.open(f, 'r');
const raw = await filehandle.readFile();
result = JSON.parse(raw);
} catch (error) {
this.error = error;
} finally {
if (filehandle) {
await filehandle.close();
}
}
return result;
}
async readOptions(optionsFile = '.packito.json', dir = './') {
let options = await this.readJSONFile(optionsFile, dir);
if (!options) {
// Default options
options = {
remove: {
devDependencies: '*',
script: '*',
},
copy: ['README.md', 'LICENSE'],
};
}
this.options = options;
return options;
}
async transform(_pkg, _options) {
const pkg = _pkg || (await this.readJSONFile('package.json'));
const options = _options || (await this.readOptions());
const { remove, replace } = options;
if (typeof remove === 'object') {
Object.keys(remove).forEach((e) => {
if (remove[e] || remove[e] === '*') {
delete pkg[e];
}
});
}
if (typeof replace === 'object') {
Object.keys(replace).forEach((e) => {
if (replace[e]) {
pkg[e] = replace[e];
}
});
}
if (typeof options.publisher === 'object') {
this.publisher = options.publisher;
} else if (typeof options.publisher === 'string') {
this.publisher = { name: options.publisher };
}
this.pkg = pkg;
this.data = JSON.stringify(this.pkg, null, '\t');
// TODO handle publisher
return this.pkg;
}
async copyRecursive(file, outputDir) {
try {
await fsp.copyFile(file, path.join(outputDir, path.basename(file)));
} catch (error) {
if (error.code === 'EISDIR') {
const files = await fsp.readdir(file);
await Promise.all(files.map((f) => this.copyRecursive(path.join(file, f), path.join(outputDir, file))));
}
}
}
async write(packageFile = 'package.json') {
let filehandle = null;
let outputDir = this.options ? this.options.output : undefined;
this.error = undefined;
if (!outputDir) {
({ outputDir } = this);
}
try {
await fsp.mkdir(outputDir, { recursive: true });
} catch (error) {
//
}
try {
const f = path.join(outputDir, packageFile);
// TODO test if outputDir exist
filehandle = await fsp.open(f, 'w');
if (!this.data) {
await this.transform();
}
await filehandle.writeFile(this.data);
} catch (error) {
this.error = error;
} finally {
if (filehandle) {
await filehandle.close();
}
}
if (this.options && Array.isArray(this.options.copy)) {
await Promise.all(this.options.copy.map((e) => this.copyRecursive(e, outputDir)));
}
}
async publish(con) {
if (!this.noPublish && (this.publisher || this.publisherArguments)) {
let [exe, ...args] = this.publisherArguments || [];
if (!exe) {
[exe, ...args] = this.publisher.name.split(' ');
}
return spawn(exe, args, undefined, con);
}
return { code: -1 };
}
}