npm-pkgbuild 7.3.14 → 7.4.3

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.3",
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",
@@ -11,7 +11,7 @@ import { ContentProvider } from "./content-provider.mjs";
11
11
  * @param {string} definitions.base base directory where to find the files
12
12
  */
13
13
  export class FileContentProvider extends ContentProvider {
14
- constructor(definitions) {
14
+ constructor(definitions, entryProperties) {
15
15
  super();
16
16
 
17
17
  if (typeof definitions === "string") {
@@ -24,6 +24,8 @@ export class FileContentProvider extends ContentProvider {
24
24
  this.definitions = { pattern: ["**/*"], ...definitions };
25
25
  this.definitions.pattern = asArray(this.definitions.pattern);
26
26
  }
27
+
28
+ this.entryProperties = entryProperties;
27
29
  }
28
30
 
29
31
  async *[Symbol.asyncIterator]() {
@@ -33,7 +35,9 @@ export class FileContentProvider extends ContentProvider {
33
35
  for (const name of await globby(definitions.pattern, {
34
36
  cwd: base
35
37
  })) {
36
- yield new FileSystemEntry(name, base);
38
+ const entry = new FileSystemEntry(name, base);
39
+ Object.assign(entry, this.entryProperties);
40
+ yield entry;
37
41
  }
38
42
  }
39
43
  }
@@ -57,17 +57,20 @@ program
57
57
  sources.push(
58
58
  ...[...options.content, ...options.meta]
59
59
  .filter(x => x)
60
- .map(source => [
61
- new FileContentProvider({
62
- base: source
63
- }),
64
- ""
65
- ])
60
+ .map(
61
+ source =>
62
+ new FileContentProvider({
63
+ base: source
64
+ })
65
+ )
66
66
  );
67
67
 
68
68
  const output = new outputFactory(properties);
69
69
 
70
- const fileName = await output.execute(aggregateFifo(sources.map(([c, d]) => c[Symbol.asyncIterator]() )), options);
70
+ const fileName = await output.execute(
71
+ aggregateFifo(sources.map(c => c[Symbol.asyncIterator]())),
72
+ options
73
+ );
71
74
 
72
75
  console.log(fileName);
73
76
  }
@@ -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
 
46
+ get packageFileName() {
47
+ const p = this.properties;
48
+ return `${p.name}-${p.version}-${p.release}.${p.arch}${this.constructor.fileNameExtension}`;
49
+ }
50
+
24
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: staging });
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
  );
185
-
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
174
  */
175
+
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
@@ -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]
65
+ if (pkgbuild.content) {
66
+ sources = Object.entries(pkgbuild.content).map(
67
+ ([destination, value]) =>
68
+ new FileContentProvider(value, { destination })
62
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) {
@@ -103,7 +118,7 @@ export async function copyEntries(
103
118
  attributes = []
104
119
  ) {
105
120
  for await (let entry of source) {
106
- const destName = join(destinationDirectory, entry.name);
121
+ const destName = entry.destination === undefined ? join(destinationDirectory, entry.name) : join(destinationDirectory, entry.destination, entry.name);
107
122
  await mkdir(dirname(destName), { recursive: true });
108
123
 
109
124
  const options = { mode: entry.mode };
@@ -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)