npm-pkgbuild 7.3.13 → 7.4.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "npm-pkgbuild",
3
- "version": "7.3.13",
3
+ "version": "7.4.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -46,7 +46,7 @@
46
46
  "expression-expander": "^7.0.9",
47
47
  "globby": "^12.0.2",
48
48
  "iterable-string-interceptor": "^1.0.8",
49
- "key-value-transformer": "^1.1.0",
49
+ "key-value-transformer": "^2.0.0",
50
50
  "npm-packlist": "^3.0.0",
51
51
  "pacote": "^12.0.2",
52
52
  "pkg-dir": "^6.0.1",
@@ -6,6 +6,9 @@ import { ContentProvider } from "./content-provider.mjs";
6
6
 
7
7
  /**
8
8
  * Content provided form the file system.
9
+ * @param {Object|string} definitions
10
+ * @param {string|string[]} definitions.pattern
11
+ * @param {string} definitions.base base directory where to find the files
9
12
  */
10
13
  export class FileContentProvider extends ContentProvider {
11
14
  constructor(definitions) {
@@ -15,7 +18,7 @@ export class FileContentProvider extends ContentProvider {
15
18
  const base = dirname(definitions);
16
19
  this.definitions = {
17
20
  base,
18
- pattern: [definitions.substring(base.length)]
21
+ pattern: [definitions.substring(base.length + 1)]
19
22
  };
20
23
  } else {
21
24
  this.definitions = { pattern: ["**/*"], ...definitions };
@@ -1,7 +1,7 @@
1
1
  import { ContentProvider } from "./content-provider.mjs";
2
2
 
3
3
  /**
4
- * content from node_modules
4
+ * Content from node_modules
5
5
  */
6
6
  export class NodeModulesContentProvider extends ContentProvider {
7
7
  }
@@ -6,7 +6,7 @@ import { ContentProvider } from "./content-provider.mjs";
6
6
  import { BufferContentEntry } from "content-entry";
7
7
 
8
8
  /**
9
- * content from npm pack
9
+ * Content from npm pack.
10
10
  */
11
11
  export class NPMPackContentProvider extends ContentProvider {
12
12
  async *[Symbol.asyncIterator]() {
@@ -21,7 +21,8 @@ export class DEB extends Packager {
21
21
  }
22
22
 
23
23
  get packageFileName() {
24
- return `${this.properties.name}_${this.properties.version}_${this.properties.arch}${this.constructor.fileNameExtension}`;
24
+ const p = this.properties;
25
+ return `${p.name}_${p.version}_${p.arch}${this.constructor.fileNameExtension}`;
25
26
  }
26
27
 
27
28
  async execute(sources, options) {
@@ -92,7 +93,7 @@ const fields = {
92
93
  Breaks: { type: "packageList" },
93
94
  Replaces: { type: "packageList" },
94
95
 
95
- Source: {},
96
+ Source: { alias: "source", type: "string" },
96
97
  Uploaders: { mandatory: false },
97
98
  "Installed-Size": {}
98
99
  };
@@ -36,7 +36,7 @@ export class Packager {
36
36
  properties[k] = e;
37
37
  } else {
38
38
  if (v.default !== undefined) {
39
- properties[v.alias] = v.default;
39
+ properties[v.alias || k] = v.default;
40
40
  }
41
41
  }
42
42
  });
@@ -1,13 +1,35 @@
1
1
  import { join } from "path";
2
- import { createWriteStream } from "fs";
3
- import { tmpdir } from "os";
4
- import { finished } from "stream";
5
- import { promisify } from "util";
6
- import { mkdtemp, mkdir, chmod } from "fs/promises";
7
2
  import { execa } from "execa";
3
+ import { EmptyContentEntry, ReadableStreamContentEntry } from "content-entry";
4
+ import {
5
+ keyValueTransformer,
6
+ equalSeparatedKeyValuePairOptions
7
+ } from "key-value-transformer";
8
8
  import { Packager } from "./packager.mjs";
9
+ import { copyEntries, transform } from "../util.mjs";
9
10
  import { quote } from "../util.mjs";
10
11
 
12
+ /**
13
+ * @type KeyValueTransformOptions
14
+ * Options to describe key value pair separated by an equal sign '='
15
+ */
16
+ export const pkgKeyValuePairOptions = {
17
+ ...equalSeparatedKeyValuePairOptions,
18
+
19
+ extractKeyValue: line => {
20
+ const m = line.match(/^(\w+)=\s*\((.*)\)|(.*)/);
21
+ if (m) {
22
+ return [m[1], m[2] ? [m[2].split(/\s*,\s*/)] : m[3]];
23
+ }
24
+ },
25
+ keyValueLine: (key, value, lineEnding) =>
26
+ `${key}=${
27
+ Array.isArray(value)
28
+ ? "(" + value.map(v => quote(v)).join(",") + ")"
29
+ : quote(value)
30
+ }${lineEnding}`
31
+ };
32
+
11
33
  export class PKG extends Packager {
12
34
  static get name() {
13
35
  return "pkg";
@@ -21,32 +43,62 @@ export class PKG extends Packager {
21
43
  return fields;
22
44
  }
23
45
 
24
- async execute(sources,options) {
46
+ get packageFileName() {
47
+ const p = this.properties;
48
+ return `${p.name}-${p.version}-${p.release}.${p.arch}${this.constructor.fileNameExtension}`;
49
+ }
50
+
51
+ async execute(sources, options) {
25
52
  const properties = this.properties;
53
+
54
+ //properties.depends = makeDepends({ ...pkg.engines });
55
+
26
56
  const mandatoryFields = this.mandatoryFields;
27
57
  const staging = await this.tmpdir;
28
58
 
29
- const pkgbuildFileName = join(tmp, "PKGBUILD");
30
-
31
- this.writePkbuild(pkgbuildFileName);
59
+ function* controlProperties(k, v, presentKeys) {
60
+ if (k === undefined) {
61
+ for (const p of mandatoryFields) {
62
+ if (!presentKeys.has(p)) {
63
+ const v = properties[p];
64
+ yield [p, v === undefined ? fields[p].default : v];
65
+ }
66
+ }
67
+ } else {
68
+ yield [k, properties[k] || v];
69
+ }
70
+ }
32
71
 
33
- const transformers = [];
72
+ async function* trailingLines() {
73
+ yield `
74
+ package() {
75
+ cp -r $srcdir/* "$pkgdir"
76
+ }
77
+ `;
78
+ }
34
79
 
35
- await copyEntries(transform(sources, transformers), staging);
80
+ await copyEntries(transform(sources, []), join(staging, "src"));
36
81
 
37
- await execa("makepkg", [], { cwd: tmp });
38
- }
82
+ const metaTransformers = [
83
+ {
84
+ match: entry => entry.name === "PKGBUILD",
85
+ transform: async entry =>
86
+ new ReadableStreamContentEntry(
87
+ entry.name,
88
+ keyValueTransformer(await entry.readStream, controlProperties, {
89
+ ...pkgKeyValuePairOptions,
90
+ trailingLines
91
+ })
92
+ ),
93
+ createEntryWhenMissing: () => new EmptyContentEntry("PKGBUILD")
94
+ }
95
+ ];
39
96
 
40
- writePkbuild(pkgbuildFileName) {
41
- const out = createWriteStream(pkgbuildFileName, { encoding: "utf8" });
97
+ await copyEntries(transform(sources, metaTransformers, true), staging);
42
98
 
43
- out.write(`
44
- package() {
45
- cp -r $srcdir/* "$pkgdir"
46
- }
47
- `);
99
+ await execa("makepkg", ["-f"], { cwd: staging });
48
100
 
49
- out.end();
101
+ return join(options.destination, this.packageFileName);
50
102
  }
51
103
  }
52
104
 
@@ -55,18 +107,22 @@ package() {
55
107
  * https://www.archlinux.org/pacman/PKGBUILD.5.html
56
108
  */
57
109
  const fields = {
58
- pkgname: { alias: "name", type: "string[]" },
59
- license: { type: "string[]" },
60
- source: { type: "string[]" },
110
+ pkgname: { alias: "name", type: "string[]", mandatory: true },
111
+ pkgver: { alias: "version", type: "string", mandatory: true },
112
+ pkgrel: { alias: "release", type: "integer", default: 0, mandatory: true },
113
+ pkgdesc: { alias: "description", type: "string", mandatory: true },
114
+ arch: { default: ["any"], type: "string[]", mandatory: true },
115
+
116
+ license: { default: [], type: "string[]", mandatory: true },
117
+ source: { default: [], type: "string[]" },
61
118
  validpgpkeys: { type: "string[]" },
62
119
  noextract: { type: "string[]" },
63
- md5sums: { type: "string[]" },
120
+ md5sums: { /*default: ["SKIP"],*/ type: "string[]" },
64
121
  sha1sums: { type: "string[]" },
65
122
  sha256sums: { type: "string[]" },
66
123
  sha384sums: { type: "string[]" },
67
124
  sha512sums: { type: "string[]" },
68
125
  groups: { type: "string[]" },
69
- arch: { type: "string[]" },
70
126
  backup: { type: "string[]" },
71
127
  depends: { type: "string[]" },
72
128
  makedepends: { type: "string[]" },
@@ -77,80 +133,13 @@ const fields = {
77
133
  replaces: { type: "string[]" },
78
134
  options: { type: "string[]" },
79
135
 
80
- pkgver: {},
81
- pkgrel: {},
82
136
  epoch: {},
83
- pkgdesc: {},
84
- url: {},
137
+ url: { alias: "homepage", type: "string" },
85
138
  install: {},
86
139
  changelog: {}
87
140
  };
88
141
 
89
142
  /*
90
- export async function pkgbuild(context, stagingDir, out, options = {}) {
91
- const pkg = { contributors: [], pacman: {}, ...context.pkg };
92
-
93
- let md5sums;
94
- let source;
95
- let directory = "";
96
-
97
- if (pkg.repository) {
98
- source = pkg.repository.url;
99
- if (!source.startsWith("git+")) {
100
- source = "git+" + source;
101
- }
102
-
103
- md5sums = "SKIP";
104
-
105
- directory = pkg.repository.directory ? "/" + pkg.repository.directory : "";
106
- }
107
-
108
- const properties = {
109
- url: pkg.homepage,
110
- pkgdesc: pkg.description,
111
- license: pkg.license,
112
- pkgrel: context.properties.pkgrel,
113
- pkgver: context.properties.pkgver.replace(/\-.*$/, ""),
114
- pkgname: pkg.name,
115
- arch: "any",
116
- makedepends: "git",
117
- source,
118
- md5sums
119
- };
120
-
121
- optionsPKGBUILD.forEach(k => {
122
- const v = pkg.pacman[k];
123
- if (v !== undefined) {
124
- properties[k] = v;
125
- }
126
- });
127
-
128
- properties.depends = makeDepends({ ...pkg.engines });
129
-
130
- if (properties.install !== undefined || properties.hooks !== undefined) {
131
- properties.install = `${pkg.name}.install`;
132
- }
133
-
134
- const installdir = context.properties.installdir;
135
-
136
- arrayOptionsPKGBUILD.forEach(k => {
137
- const v = properties[k];
138
- if (v !== undefined && !Array.isArray(v)) {
139
- properties[k] = [v];
140
- }
141
- });
142
-
143
- let pkgver = "";
144
-
145
- if (context.properties.pkgver === "0.0.0-semantic-release") {
146
- pkgver = `
147
- pkgver() {
148
- cd "$pkgname"
149
- printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
150
- }
151
- `;
152
- }
153
-
154
143
  out.write(
155
144
  `# ${pkg.contributors
156
145
  .map(
@@ -182,22 +171,8 @@ package() {
182
171
  }
183
172
  `
184
173
  );
174
+ */
185
175
 
186
- await promisify(finished);
187
- }
188
-
189
- function makeDepends(d) {
190
- if (d === undefined) {
191
- return [];
192
- }
193
-
194
- return Object.keys(d).reduce((a, c) => {
195
- const mapping = {
196
- node: "nodejs"
197
- };
198
-
199
- a.push(`${mapping[c] ? mapping[c] : c}${d[c].replace(/\-([\w\d]+)$/, "")}`);
200
- return a;
201
- }, []);
202
- }
203
- */
176
+ const mapping = {
177
+ node: "nodejs"
178
+ };
@@ -1,5 +1,13 @@
1
- import { globby } from "globby";
1
+ import { join } from "path";
2
+ import { mkdir } from "fs/promises";
3
+ import { execa } from "execa";
4
+ import { EmptyContentEntry, ReadableStreamContentEntry } from "content-entry";
5
+ import {
6
+ keyValueTransformer,
7
+ colonSeparatedKeyValuePairOptions
8
+ } from "key-value-transformer";
2
9
  import { Packager } from "./packager.mjs";
10
+ import { copyEntries, transform } from "../util.mjs";
3
11
 
4
12
  export class RPM extends Packager {
5
13
  static get name() {
@@ -10,36 +18,98 @@ export class RPM extends Packager {
10
18
  return ".rpm";
11
19
  }
12
20
 
21
+ get packageFileName() {
22
+ const p = this.properties;
23
+ return `${p.name}-${p.version}-${p.release}.${p.arch}${this.constructor.fileNameExtension}`;
24
+ }
25
+
13
26
  static get fields() {
14
27
  return fields;
15
28
  }
16
29
 
17
- async execute(sources,options) {
30
+ async execute(sources, options) {
18
31
  const properties = this.properties;
19
32
  const mandatoryFields = this.mandatoryFields;
20
- const staging = await this.tmpdir;
21
-
22
- let specFileName = `${properties.name}.spec`;
33
+ const tmp = await this.tmpdir;
23
34
 
24
- const transformers = [];
25
-
26
- await copyEntries(
27
- transform(sources, transformers),
28
- staging
35
+ await Promise.all(
36
+ ["staging", "RPMS", "SRPMS", "SOURCES", "SPECS"].map(d =>
37
+ mkdir(join(tmp, d))
38
+ )
29
39
  );
30
40
 
31
- await execa("rpmbuild", ["-ba", specFileName]);
41
+ const staging = join(tmp, "staging");
42
+
43
+ function* controlProperties(k, v, presentKeys) {
44
+ if (k === undefined) {
45
+ for (const p of mandatoryFields) {
46
+ if (!presentKeys.has(p)) {
47
+ const v = properties[p];
48
+ yield [p, v === undefined ? fields[p].default : v];
49
+ }
50
+ }
51
+ } else {
52
+ yield [k, properties[k] || v];
53
+ }
54
+ }
55
+
56
+ const specFileName = `${properties.name}.spec`;
57
+
58
+ async function* trailingLines() {
59
+ for (const [name, options] of Object.entries(sections)) {
60
+ yield `%${name}\n\n`;
61
+ }
62
+ }
63
+
64
+ const transformers = [
65
+ {
66
+ match: entry => entry.name === specFileName,
67
+ transform: async entry =>
68
+ new ReadableStreamContentEntry(
69
+ entry.name,
70
+ keyValueTransformer(await entry.readStream, controlProperties, {
71
+ ...colonSeparatedKeyValuePairOptions,
72
+ trailingLines
73
+ })
74
+ ),
75
+ createEntryWhenMissing: () => new EmptyContentEntry(specFileName)
76
+ }
77
+ ];
78
+
79
+ await copyEntries(transform(sources, transformers), staging);
80
+
81
+ await execa("rpmbuild", [
82
+ "--define",
83
+ `_topdir ${tmp}`,
84
+ "-vv",
85
+ "-bb",
86
+ join(staging, specFileName)
87
+ ]);
88
+
89
+ return join(options.destination, this.packageFileName);
32
90
  }
33
91
  }
34
92
 
93
+ /**
94
+ * @see https://rpm-packaging-guide.github.io
95
+ */
35
96
  const fields = {
36
- Name: { alias: "name", type: "string" },
37
- Summary: { alias: "description", type: "string" },
38
- License: { alias: "license", type: "string" },
39
- Version: { alias: "version", type: "string" },
40
- Release: { type: "integer", default: 0 },
97
+ Name: { alias: "name", type: "string", mandatory: true },
98
+ Summary: { alias: "description", type: "string", mandatory: true },
99
+ License: { alias: "license", type: "string", mandatory: true },
100
+ Version: { alias: "version", type: "string", mandatory: true },
101
+ Release: { alias: "release", type: "integer", default: 1, mandatory: true },
102
+ Source0: { alias: "source", type: "string" },
103
+ Group: { alias: "group", type: "string" },
41
104
  Packager: { type: "string" },
42
- URL: { alias: "homepage", type: "string" }
105
+ BuildArch: {
106
+ alias: "arch",
107
+ default: "noarch",
108
+ type: "string",
109
+ mandatory: true
110
+ },
111
+ URL: { alias: "homepage", type: "string" },
112
+ Requires: { type: "string[]" }
43
113
  };
44
114
 
45
115
  const sections = {
@@ -47,50 +117,7 @@ const sections = {
47
117
  prep: {},
48
118
  build: {},
49
119
  install: {},
120
+ check: {},
50
121
  files: {},
51
122
  changelog: {}
52
123
  };
53
-
54
- export async function rpmspec(context, stagingDir, out, options = {}) {
55
- const pkg = { contributors: [], pacman: {}, ...context.pkg };
56
-
57
- const installdir = context.properties.installdir;
58
- let directory = "";
59
-
60
- const npmDistPackage = options.npmDist
61
- ? `( cd %{_sourcedir}${installdir}
62
- tar -x --transform="s/^package\\///" -f %{buildroot}${directory}/${pkg.name}-${context.properties.pkgver}.tgz)`
63
- : "";
64
-
65
- const npmModulesPackage = options.npmModules
66
- ? `( cd %{_sourcedir}/${directory}
67
- tar cf - node_modules)|(cd %{buildroot}${installdir};tar xf - )`
68
- : "";
69
-
70
- out.write(`${Object.keys(properties)
71
- .filter(k => properties[k] !== undefined)
72
- .map(k => `${k}: ${properties[k]}`)
73
- .join("\n")}
74
-
75
- %description
76
- ${pkg.description}
77
-
78
- %build
79
- npm install
80
- mkdir -p %{buildroot}${installdir}
81
- ${npmDistPackage}
82
- ${npmModulesPackage}
83
-
84
- %install
85
-
86
- %files
87
- ${installdir}bin/*
88
- ${installdir}node_modules/*
89
- `);
90
-
91
- for (const name of await globby("**/*", { cwd: stagingDir })) {
92
- out.write(name + "\n");
93
- }
94
-
95
- out.end();
96
- }
package/src/util.mjs CHANGED
@@ -24,7 +24,7 @@ export function asArray(o) {
24
24
  }
25
25
 
26
26
  /**
27
- *
27
+ * Extract package definition from package.json.
28
28
  * @param {Object} pkg package.json content
29
29
  * @returns {Object}
30
30
  */
@@ -49,21 +49,30 @@ export function extractFromPackage(pkg) {
49
49
  )[0];
50
50
  }
51
51
 
52
+ if (pkg.repository) {
53
+ properties.source = pkg.repository.url;
54
+ }
55
+
56
+ let dependencies = { ...pkg.engines };
52
57
  let sources = [];
53
58
 
54
59
  if (pkg.pkgbuild) {
55
- Object.entries(pkg.pkgbuild)
60
+ const pkgbuild = pkg.pkgbuild;
61
+ Object.entries(pkgbuild)
56
62
  .filter(([k, v]) => typeof v === "string")
57
63
  .forEach(([k, v]) => (properties[k] = v));
58
64
 
59
- if (pkg.pkgbuild.content) {
60
- sources = Object.entries(pkg.pkgbuild.content).map(
61
- ([destination, value]) => [new FileContentProvider(value), destination]
62
- );
65
+ if (pkgbuild.content) {
66
+ sources = Object.entries(pkgbuild.content).map(([destination, value]) => [
67
+ new FileContentProvider(value),
68
+ destination
69
+ ]);
63
70
  }
71
+
72
+ Object.assign(dependencies,pkgbuild.depends)
64
73
  }
65
74
 
66
- return { properties, sources };
75
+ return { properties, sources, dependencies};
67
76
  }
68
77
 
69
78
  /**
@@ -71,7 +80,7 @@ export function extractFromPackage(pkg) {
71
80
  * @param {AsyncIterator<ContentEntry>} source
72
81
  * @param {Transformer[]} transformers
73
82
  */
74
- export async function* transform(source, transformers) {
83
+ export async function* transform(source, transformers=[], onlyMatching) {
75
84
  const usedTransformers = new Set();
76
85
 
77
86
  for await (let entry of source) {
@@ -79,10 +88,16 @@ export async function* transform(source, transformers) {
79
88
  if (t.match(entry)) {
80
89
  entry = await t.transform(entry);
81
90
  usedTransformers.add(t);
91
+
92
+ if(onlyMatching) {
93
+ yield entry;
94
+ }
82
95
  }
83
96
  }
84
97
 
85
- yield entry;
98
+ if(!onlyMatching) {
99
+ yield entry;
100
+ }
86
101
  }
87
102
 
88
103
  for (const t of transformers) {
@@ -114,6 +129,7 @@ export async function copyEntries(
114
129
  }
115
130
  }
116
131
 
132
+ console.log(destName);
117
133
  await pipeline(
118
134
  await entry.readStream,
119
135
  createWriteStream(destName, options)