npm-pkgbuild 10.0.1 → 10.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -36,17 +36,18 @@ You can specify the package content in package.json.
36
36
  {
37
37
  "pkgbuild": {
38
38
  "content": {
39
- "/some/location" : { "base": "build" },
39
+ "/some/location/" : { "base": "build" },
40
40
  "/etc/myconfig.json" : "sample-config.json",
41
- "/opt/myapp": [
42
- {
43
- "type": "npm-pack"
44
- },
45
- {
46
- "type": "node-modules",
47
- "withoutDevelpmentDependencies": true
48
- }
49
- ]
41
+ "/erc/secret" : { "name": "secret", "mode": "600" },
42
+ "/opt/myapp": [
43
+ {
44
+ "type": "npm-pack"
45
+ },
46
+ {
47
+ "type": "node-modules",
48
+ "withoutDevelpmentDependencies": true
49
+ }
50
+ ]
50
51
  },
51
52
  "hooks" : "pkg/hooks",
52
53
  "output": {
@@ -61,7 +62,7 @@ You can specify the package content in package.json.
61
62
 
62
63
  # content providers
63
64
 
64
- # files (default)
65
+ ## files (default)
65
66
 
66
67
  content from the file system
67
68
 
@@ -76,6 +77,10 @@ content of all (production) dependencies
76
77
  options:
77
78
  - withoutDevelpmentDependencies when to stip away dev dependencies (defaults to true)
78
79
 
80
+ # shared configuration
81
+
82
+ You can import common configuration from other packages
83
+ see mf-hosting module as an example
79
84
 
80
85
  # API
81
86
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "npm-pkgbuild",
3
- "version": "10.0.1",
3
+ "version": "10.1.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -52,10 +52,10 @@
52
52
  "ini": "^3.0.0",
53
53
  "iterable-string-interceptor": "^2.0.0",
54
54
  "key-value-transformer": "^3.0.0",
55
- "node-fetch": "^3.2.3",
55
+ "node-fetch": "^3.2.4",
56
56
  "npm-package-walker": "^5.0.6",
57
- "npm-packlist": "^5.0.2",
58
- "pacote": "^13.1.1",
57
+ "npm-packlist": "^5.0.3",
58
+ "pacote": "^13.3.0",
59
59
  "pkg-dir": "^6.0.1",
60
60
  "tar-stream": "^2.2.0"
61
61
  },
@@ -33,6 +33,18 @@ export class FileContentProvider extends ContentProvider {
33
33
  }
34
34
 
35
35
  this.entryProperties = entryProperties;
36
+
37
+ if(this.entryProperties) {
38
+ for(const a of ["mode"]) {
39
+ if(this.entryProperties[a] !== undefined) {
40
+ if(!this.baseProperties) {
41
+ this.baseProperties = {};
42
+ }
43
+ this.baseProperties[a] = { value: this.entryProperties[a] };
44
+ delete this.entryProperties[a];
45
+ }
46
+ }
47
+ }
36
48
  }
37
49
 
38
50
  toString() {
@@ -46,10 +58,12 @@ export class FileContentProvider extends ContentProvider {
46
58
  for (const name of await globby(definitions.pattern, {
47
59
  cwd: base
48
60
  })) {
49
- yield Object.assign(
61
+ const entry = Object.assign(
50
62
  new FileSystemEntry(name, base),
51
63
  this.entryProperties
52
64
  );
65
+
66
+ yield this.baseProperties ? Object.create(entry, this.baseProperties) : entry;
53
67
  }
54
68
  }
55
69
  }
@@ -1,4 +1,3 @@
1
- import { arch as hostArch } from "process";
2
1
  import { packageWalker } from "npm-package-walker";
3
2
  import { createContext } from "expression-expander";
4
3
  import { asArray } from "./util.mjs";
@@ -12,29 +11,52 @@ import { RPM } from "./output/rpm.mjs";
12
11
  export const allInputs = [NPMPackContentProvider, NodeModulesContentProvider];
13
12
  export const allOutputs = [DEBIAN, ARCH, RPM];
14
13
 
14
+ /**
15
+ * Node architecture name to os native name mapping
16
+ * {@see https://nodejs.org/dist/latest-v18.x/docs/api/process.html#processargv}
17
+ */
15
18
  export const npmArchMapping = {
16
19
  arm64: "aarch64",
17
20
  arm: "armv7h",
18
- x64: "x86_64"
21
+ mips: "mips",
22
+ mipsel: "mipsel",
23
+ ppc: "ppc",
24
+ s390: "s390",
25
+ s390x: "s390x",
26
+ ia32: "x32",
27
+ x64: "x86_64",
28
+ ppc64: "ppc64"
19
29
  };
20
30
 
21
- export const archMapping = Object.fromEntries(
22
- Object.entries(npmArchMapping).map(a => [a[1], a[0]])
23
- );
31
+ const entryAttributeNames = ["owner", "group", "mode"];
32
+
33
+ /**
34
+ * @typedef {Object} PackageDefinition
35
+ * @property {Object} properties values describing the package attributes
36
+ * @property {ContentProvider[]} sources content providers
37
+ * @property {Object} dependencies
38
+ * @property {Object} output package type
39
+ * @property {string} variant identifier of the variant
40
+ */
24
41
 
25
42
  /**
26
43
  * Extract package definition from package.json.
44
+ * - for each architecture deliver a new result
45
+ * - if not architecture is given one result set is provided nethertheless
46
+ * - architectures are taken from cpu (node arch ids) and from pkgbuild.arch (raw arch ids)
27
47
  * @param {Object} pkg package.json content
28
48
  * @param {string} dir
29
- * @returns {Object}
49
+ * @returns {AsyncIter<PackageDefinition>}
30
50
  */
31
- export async function extractFromPackage(json, dir) {
51
+ export async function* extractFromPackage(json, dir) {
32
52
  const properties = Object.fromEntries(
33
53
  ["name", "version", "description", "homepage", "license"]
34
54
  .map(key => [key, json[key]])
35
55
  .filter(([k, v]) => v !== undefined)
36
56
  );
37
57
 
58
+ let variant = "default";
59
+
38
60
  if (json.bugs) {
39
61
  if (json.bugs.url) {
40
62
  properties.bugs = json.bugs.url;
@@ -86,6 +108,10 @@ export async function extractFromPackage(json, dir) {
86
108
  }
87
109
 
88
110
  if (pkg.abstract || !modulePath) {
111
+ if (pkg.variant) {
112
+ variant = pkg.variant;
113
+ }
114
+
89
115
  if (pkg.arch) {
90
116
  for (const a of asArray(pkg.arch)) {
91
117
  arch.add(a);
@@ -99,31 +125,39 @@ export async function extractFromPackage(json, dir) {
99
125
  .forEach(([k, v]) => (properties[k] = v));
100
126
 
101
127
  if (pkg.content && !modulePath) {
102
- Object.entries(pkg.content).forEach(
103
- ([destination, definitions]) => {
104
- destination = context.expand(destination);
105
- definitions = context.expand(definitions);
106
- for (const definition of asArray(definitions)) {
107
- const entryProperties = { destination };
108
-
109
- if (definition.type) {
110
- const type = allInputs.find(i => i.name === definition.type);
111
- if (type) {
112
- delete definition.type;
113
- sources.push(
114
- new type({ ...definition, dir }, entryProperties)
115
- );
116
- } else {
117
- console.error(`Unknown type '${type}'`);
118
- }
119
- } else {
128
+ Object.entries(pkg.content).forEach(([destination, definitions]) => {
129
+ destination = context.expand(destination);
130
+ definitions = context.expand(definitions);
131
+
132
+ const allEntryProperties = {};
133
+
134
+ for (const a of entryAttributeNames) {
135
+ if (definitions[a] !== undefined) {
136
+ allEntryProperties[a] = definitions[a];
137
+ delete definitions[a];
138
+ }
139
+ }
140
+
141
+ for (const definition of asArray(definitions)) {
142
+ const entryProperties = { ...allEntryProperties, destination };
143
+
144
+ if (definition.type) {
145
+ const type = allInputs.find(i => i.name === definition.type);
146
+ if (type) {
147
+ delete definition.type;
120
148
  sources.push(
121
- new FileContentProvider(definition, entryProperties)
149
+ new type({ ...definition, dir }, entryProperties)
122
150
  );
151
+ } else {
152
+ console.error(`Unknown type '${type}'`);
123
153
  }
154
+ } else {
155
+ sources.push(
156
+ new FileContentProvider(definition, entryProperties)
157
+ );
124
158
  }
125
159
  }
126
- );
160
+ });
127
161
  }
128
162
  }
129
163
  Object.assign(dependencies, pkg.depends);
@@ -139,9 +173,16 @@ export async function extractFromPackage(json, dir) {
139
173
 
140
174
  processPkg(json, dir);
141
175
 
176
+ properties.variant = variant;
177
+
142
178
  if (arch.size > 0) {
143
- properties.arch = [...arch].filter(a => a === npmArchMapping[hostArch]);
179
+ // provide each arch separadly
180
+ for (const a of arch) {
181
+ properties.arch = [a];
182
+ yield { properties, sources, dependencies, output, variant };
183
+ }
184
+ } else {
185
+ // or one set if no arch is given
186
+ yield { properties, sources, dependencies, output, variant };
144
187
  }
145
-
146
- return { properties, sources, dependencies, output };
147
188
  }
@@ -75,73 +75,82 @@ program
75
75
  console.log(`pkgdir: ${pkgDir}`);
76
76
  }
77
77
 
78
- const { properties, sources, output, dependencies } =
79
- await extractFromPackage(
80
- JSON.parse(
81
- await readFile(join(pkgDir, "package.json"), utf8StreamOptions)
82
- ),
83
- pkgDir
84
- );
85
-
86
- for (const inputFactory of allInputs.filter(
87
- inputFactory => options[inputFactory.name] === true
78
+ for await (const {
79
+ properties,
80
+ sources,
81
+ output,
82
+ dependencies,
83
+ variant
84
+ } of extractFromPackage(
85
+ JSON.parse(
86
+ await readFile(join(pkgDir, "package.json"), utf8StreamOptions)
87
+ ),
88
+ pkgDir
88
89
  )) {
89
- sources.push(new inputFactory());
90
- }
91
-
92
- for (const outputFactory of allOutputs.filter(
93
- o => options[o.name] === true || output[o.name] !== undefined
94
- )) {
95
- if (options.available && !(await outputFactory.available)) {
96
- continute;
90
+ for (const inputFactory of allInputs.filter(
91
+ inputFactory => options[inputFactory.name] === true
92
+ )) {
93
+ sources.push(new inputFactory());
97
94
  }
98
95
 
99
- Object.assign(properties, { type: outputFactory.name }, options.define);
100
-
101
- sources.push(
102
- ...[...options.content, ...options.meta]
103
- .filter(x => x)
104
- .map(
105
- source =>
106
- new FileContentProvider({
107
- base: source
108
- })
96
+ for (const outputFactory of allOutputs.filter(
97
+ o => options[o.name] === true || output[o.name] !== undefined
98
+ )) {
99
+ if (options.available && !(await outputFactory.available)) {
100
+ continute;
101
+ }
102
+
103
+ Object.assign(
104
+ properties,
105
+ { type: outputFactory.name },
106
+ options.define
107
+ );
108
+
109
+ sources.push(
110
+ ...[...options.content, ...options.meta]
111
+ .filter(x => x)
112
+ .map(
113
+ source =>
114
+ new FileContentProvider({
115
+ base: source
116
+ })
117
+ )
118
+ );
119
+
120
+ const context = createContext({ properties });
121
+ const output = new outputFactory(context.expand(properties));
122
+ const transformer = [
123
+ createExpressionTransformer(
124
+ nameExtensionMatcher([
125
+ ".conf",
126
+ ".json",
127
+ ".html",
128
+ ".txt",
129
+ ".webmanifest",
130
+ ".service",
131
+ ".socket",
132
+ ".rules"
133
+ ]),
134
+ context.expand(properties)
109
135
  )
110
- );
111
-
112
- const context = createContext({ properties });
113
- const output = new outputFactory(context.expand(properties));
114
- const transformer = [
115
- createExpressionTransformer(
116
- nameExtensionMatcher([
117
- ".conf",
118
- ".json",
119
- ".html",
120
- ".txt",
121
- ".webmanifest",
122
- ".service",
123
- ".socket",
124
- ".rules"
125
- ]),
126
- context.expand(properties)
127
- )
128
- ];
129
-
130
- if (options.verbose) {
131
- console.log(output.properties);
132
- console.log(`sources: ${sources.join("\n ")}`);
133
- console.log(`dependencies: ${JSON.stringify(dependencies)}`);
136
+ ];
137
+
138
+ if (options.verbose) {
139
+ console.log(output.properties);
140
+ console.log(`sources: ${sources.join("\n ")}`);
141
+ console.log(`dependencies: ${JSON.stringify(dependencies)}`);
142
+ }
143
+
144
+ const fileName = await output.execute(
145
+ sources.map(c => c[Symbol.asyncIterator]()),
146
+ transformer,
147
+ dependencies,
148
+ options,
149
+ path => context.expand(path)
150
+ );
151
+
152
+ await publish(fileName, options.publish, properties);
134
153
  }
135
-
136
- const fileName = await output.execute(
137
- sources.map(c => c[Symbol.asyncIterator]()),
138
- transformer,
139
- dependencies,
140
- options,
141
- path => context.expand(path)
142
- );
143
-
144
- await publish(fileName, options.publish, properties);
145
154
  }
146
155
  } catch (e) {
147
156
  console.error(e);
package/src/util.mjs CHANGED
@@ -144,7 +144,7 @@ export function fieldProvider(properties, fields) {
144
144
 
145
145
  /**
146
146
  * Copy content from source into destinationDirectory.
147
- * Destination paths a generated without leading '/' (as for as entry names too).
147
+ * Destination paths a generated without leading '/' (as for entry names too).
148
148
  * @param {AsyncIterator<ContentEntry>} source
149
149
  * @param {string} destinationDirectory
150
150
  * @param {Expander} expander