npm-pkgbuild 7.3.14 → 7.4.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "npm-pkgbuild",
3
- "version": "7.3.14",
3
+ "version": "7.4.0",
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",
@@ -92,7 +92,7 @@ const fields = {
92
92
  Breaks: { type: "packageList" },
93
93
  Replaces: { type: "packageList" },
94
94
 
95
- Source: {},
95
+ Source: { alias: "source", type: "string" },
96
96
  Uploaders: { mandatory: false },
97
97
  "Installed-Size": {}
98
98
  };
@@ -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,34 @@
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
1
  import { execa } from "execa";
2
+ import { EmptyContentEntry, ReadableStreamContentEntry } from "content-entry";
3
+ import {
4
+ keyValueTransformer,
5
+ equalSeparatedKeyValuePairOptions
6
+ } from "key-value-transformer";
8
7
  import { Packager } from "./packager.mjs";
8
+ import { copyEntries, transform } from "../util.mjs";
9
9
  import { quote } from "../util.mjs";
10
10
 
11
+ /**
12
+ * @type KeyValueTransformOptions
13
+ * Options to describe key value pair separated by an equal sign '='
14
+ */
15
+ export const pkgKeyValuePairOptions = {
16
+ ...equalSeparatedKeyValuePairOptions,
17
+
18
+ extractKeyValue: line => {
19
+ const m = line.match(/^(\w+)=\s*\((.*)\)|(.*)/);
20
+ if (m) {
21
+ return [m[1], m[2] ? [m[2]] : m[3]];
22
+ }
23
+ },
24
+ keyValueLine: (key, value, lineEnding) =>
25
+ `${key}=${
26
+ Array.isArray(value)
27
+ ? "(" + value.map(v => quote(v)).join(",") + ")"
28
+ : quote(value)
29
+ }${lineEnding}`
30
+ };
31
+
11
32
  export class PKG extends Packager {
12
33
  static get name() {
13
34
  return "pkg";
@@ -26,27 +47,45 @@ export class PKG extends Packager {
26
47
  const mandatoryFields = this.mandatoryFields;
27
48
  const staging = await this.tmpdir;
28
49
 
29
- const pkgbuildFileName = join(tmp, "PKGBUILD");
50
+ function* controlProperties(k, v, presentKeys) {
51
+ if (k === undefined) {
52
+ for (const p of mandatoryFields) {
53
+ if (!presentKeys.has(p)) {
54
+ const v = properties[p];
55
+ yield [p, v === undefined ? fields[p].default : v];
56
+ }
57
+ }
58
+ } else {
59
+ yield [k, properties[k] || v];
60
+ }
61
+ }
30
62
 
31
- this.writePkbuild(pkgbuildFileName);
63
+ async function* trailingLines() {
64
+ yield `
65
+ package() {
66
+ cp -r $srcdir/* "$pkgdir"
67
+ }
68
+ `;
69
+ }
32
70
 
33
- const transformers = [];
71
+ const transformers = [
72
+ {
73
+ match: entry => entry.name === "PKGBUILD",
74
+ transform: async entry =>
75
+ new ReadableStreamContentEntry(
76
+ entry.name,
77
+ keyValueTransformer(await entry.readStream, controlProperties, {
78
+ ...pkgKeyValuePairOptions,
79
+ trailingLines
80
+ })
81
+ ),
82
+ createEntryWhenMissing: () => new EmptyContentEntry("PKGBUILD")
83
+ }
84
+ ];
34
85
 
35
86
  await copyEntries(transform(sources, transformers), staging);
36
87
 
37
- await execa("makepkg", [], { cwd: staging });
38
- }
39
-
40
- writePkbuild(pkgbuildFileName) {
41
- const out = createWriteStream(pkgbuildFileName, { encoding: "utf8" });
42
-
43
- out.write(`
44
- package() {
45
- cp -r $srcdir/* "$pkgdir"
46
- }
47
- `);
48
-
49
- out.end();
88
+ await execa("makepkg", ["-f"], { cwd: staging });
50
89
  }
51
90
  }
52
91
 
@@ -55,18 +94,22 @@ package() {
55
94
  * https://www.archlinux.org/pacman/PKGBUILD.5.html
56
95
  */
57
96
  const fields = {
58
- pkgname: { alias: "name", type: "string[]" },
59
- license: { type: "string[]" },
60
- source: { type: "string[]" },
97
+ pkgname: { alias: "name", type: "string[]", mandatory: true },
98
+ pkgver: { alias: "version", type: "string", mandatory: true },
99
+ pkgrel: { alias: "release", type: "integer", default: 0, mandatory: true },
100
+ pkgdesc: { alias: "description", type: "string", mandatory: true },
101
+ arch: { default: ["any"], type: "string[]", mandatory: true },
102
+
103
+ license: { type: "string[]", mandatory: true },
104
+ source: { default: [], type: "string[]" },
61
105
  validpgpkeys: { type: "string[]" },
62
106
  noextract: { type: "string[]" },
63
- md5sums: { type: "string[]" },
107
+ md5sums: { /*default: ["SKIP"],*/ type: "string[]" },
64
108
  sha1sums: { type: "string[]" },
65
109
  sha256sums: { type: "string[]" },
66
110
  sha384sums: { type: "string[]" },
67
111
  sha512sums: { type: "string[]" },
68
112
  groups: { type: "string[]" },
69
- arch: { type: "string[]" },
70
113
  backup: { type: "string[]" },
71
114
  depends: { type: "string[]" },
72
115
  makedepends: { type: "string[]" },
@@ -77,80 +120,28 @@ const fields = {
77
120
  replaces: { type: "string[]" },
78
121
  options: { type: "string[]" },
79
122
 
80
- pkgver: {},
81
- pkgrel: {},
82
123
  epoch: {},
83
- pkgdesc: {},
84
- url: {},
124
+ url: { alias: "homepage", type: "string" },
85
125
  install: {},
86
126
  changelog: {}
87
127
  };
88
128
 
89
129
  /*
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
130
  if (pkg.repository) {
98
131
  source = pkg.repository.url;
99
132
  if (!source.startsWith("git+")) {
100
133
  source = "git+" + source;
101
134
  }
102
135
 
103
- md5sums = "SKIP";
104
-
105
136
  directory = pkg.repository.directory ? "/" + pkg.repository.directory : "";
106
137
  }
107
138
 
108
139
  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
140
+ makedepends: "git"
119
141
  };
120
142
 
121
- optionsPKGBUILD.forEach(k => {
122
- const v = pkg.pacman[k];
123
- if (v !== undefined) {
124
- properties[k] = v;
125
- }
126
- });
127
-
128
143
  properties.depends = makeDepends({ ...pkg.engines });
129
144
 
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
145
  out.write(
155
146
  `# ${pkg.contributors
156
147
  .map(
@@ -183,9 +174,6 @@ package() {
183
174
  `
184
175
  );
185
176
 
186
- await promisify(finished);
187
- }
188
-
189
177
  function makeDepends(d) {
190
178
  if (d === undefined) {
191
179
  return [];
@@ -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,99 @@ 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
+ // `--target=${properties.arch}`,
87
+ join(staging, specFileName)
88
+ ]);
89
+
90
+ return join(options.destination, this.packageFileName);
32
91
  }
33
92
  }
34
93
 
94
+ /**
95
+ * @see https://rpm-packaging-guide.github.io
96
+ */
35
97
  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 },
98
+ Name: { alias: "name", type: "string", mandatory: true },
99
+ Summary: { alias: "description", type: "string", mandatory: true },
100
+ License: { alias: "license", type: "string", mandatory: true },
101
+ Version: { alias: "version", type: "string", mandatory: true },
102
+ Release: { alias: "release", type: "integer", default: 1, mandatory: true },
103
+ Source0: { alias: "source", type: "string" },
104
+ Group: { alias: "group", type: "string" },
41
105
  Packager: { type: "string" },
42
- URL: { alias: "homepage", type: "string" }
106
+ BuildArch: {
107
+ alias: "arch",
108
+ default: "noarch",
109
+ type: "string",
110
+ mandatory: true
111
+ },
112
+ URL: { alias: "homepage", type: "string" },
113
+ Requires: { type: "string[]" }
43
114
  };
44
115
 
45
116
  const sections = {
@@ -47,50 +118,7 @@ const sections = {
47
118
  prep: {},
48
119
  build: {},
49
120
  install: {},
121
+ check: {},
50
122
  files: {},
51
123
  changelog: {}
52
124
  };
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
@@ -49,17 +49,23 @@ export function extractFromPackage(pkg) {
49
49
  )[0];
50
50
  }
51
51
 
52
+ if (pkg.repository) {
53
+ properties.source = pkg.repository.url;
54
+ }
55
+
52
56
  let sources = [];
53
57
 
54
58
  if (pkg.pkgbuild) {
55
- Object.entries(pkg.pkgbuild)
59
+ const pkgbuild = pkg.pkgbuild;
60
+ Object.entries(pkgbuild)
56
61
  .filter(([k, v]) => typeof v === "string")
57
62
  .forEach(([k, v]) => (properties[k] = v));
58
63
 
59
- if (pkg.pkgbuild.content) {
60
- sources = Object.entries(pkg.pkgbuild.content).map(
61
- ([destination, value]) => [new FileContentProvider(value), destination]
62
- );
64
+ if (pkgbuild.content) {
65
+ sources = Object.entries(pkgbuild.content).map(([destination, value]) => [
66
+ new FileContentProvider(value),
67
+ destination
68
+ ]);
63
69
  }
64
70
  }
65
71
 
@@ -114,6 +120,7 @@ export async function copyEntries(
114
120
  }
115
121
  }
116
122
 
123
+ console.log(destName);
117
124
  await pipeline(
118
125
  await entry.readStream,
119
126
  createWriteStream(destName, options)