npm-pkgbuild 7.3.4 → 7.3.8

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.4",
3
+ "version": "7.3.8",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -46,6 +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
50
  "npm-packlist": "^3.0.0",
50
51
  "pacote": "^12.0.2",
51
52
  "pkg-dir": "^6.0.1",
package/src/module.mjs CHANGED
@@ -6,4 +6,5 @@ export * from "./content/node-modules-content-provider.mjs";
6
6
  export * from "./content/npm-pack-content-provider.mjs";
7
7
  export * from "./output/deb.mjs";
8
8
  export * from "./output/rpm.mjs";
9
- export * from "./output/pkg.mjs";
9
+ export * from "./output/pkg.mjs";
10
+ export * from "./output/packager.mjs";
@@ -7,7 +7,7 @@ import program from "commander";
7
7
  import { aggregateFifo } from "aggregate-async-iterator";
8
8
  import { packageDirectory } from "pkg-dir";
9
9
  import { utf8StreamOptions, extractFromPackage } from "./util.mjs";
10
- import { FileContentProvider, Deb, PKG, RPM } from "npm-pkgbuild";
10
+ import { FileContentProvider, DEB, PKG, RPM } from "npm-pkgbuild";
11
11
 
12
12
  const { version, description } = JSON.parse(
13
13
  readFileSync(new URL("../package.json", import.meta.url).pathname),
@@ -16,7 +16,7 @@ const { version, description } = JSON.parse(
16
16
 
17
17
  const cwd = process.cwd();
18
18
 
19
- const outputs = [Deb, PKG, RPM];
19
+ const outputs = [DEB, PKG, RPM];
20
20
 
21
21
  program.description(description).version(version);
22
22
 
@@ -4,9 +4,9 @@ import { createWriteStream } from "fs";
4
4
  import { mkdtemp, mkdir, chmod } from "fs/promises";
5
5
  import { pipeline } from "stream/promises";
6
6
  import { execa } from "execa";
7
- import { EmptyContentEntry } from "content-entry";
7
+ import { EmptyContentEntry, ReadableStreamContentEntry } from "content-entry";
8
+ import { keyValueTransformer } from "key-value-transformer";
8
9
  import { Packager } from "./packager.mjs";
9
- import { keyValueTransformer } from "../key-value-transformer.mjs";
10
10
 
11
11
  const executableAttributes = { chmod: "0775" };
12
12
 
@@ -17,7 +17,7 @@ const permissions = {
17
17
  "DEBIAN/postrm": executableAttributes
18
18
  };
19
19
 
20
- export class Deb extends Packager {
20
+ export class DEB extends Packager {
21
21
  static get name() {
22
22
  return "deb";
23
23
  }
@@ -26,37 +26,23 @@ export class Deb extends Packager {
26
26
  return ".deb";
27
27
  }
28
28
 
29
+ static get fields() {
30
+ return fields;
31
+ }
32
+
29
33
  get packageFileName() {
30
34
  return `${this.properties.name}_${this.properties.version}_${this.properties.arch}${this.constructor.fileNameExtension}`;
31
35
  }
32
36
 
33
37
  async execute(options) {
34
38
  const properties = this.properties;
35
-
36
- Object.entries(fields).forEach(([k, v]) => {
37
- const e = properties[v.alias];
38
- if (e !== undefined) {
39
- properties[k] = e;
40
- }
41
- else {
42
- if(v.default !== undefined) {
43
- properties[v.alias] = v.default;
44
- }
45
- }
46
- });
47
-
39
+ const mandatoryFields = this.mandatoryFields;
48
40
  const tmp = await mkdtemp(join(tmpdir(), "deb-"));
49
41
  const staging = join(tmp, `${properties.name}-${properties.version}`);
50
42
 
51
- const mandatoryProperties = new Set(
52
- Object.entries(fields)
53
- .filter(([k, v]) => v.mandatory)
54
- .map(([k, v]) => k)
55
- );
56
-
57
43
  function* controlProperties(k, v, presentKeys) {
58
44
  if (k === undefined) {
59
- for (const p of mandatoryProperties) {
45
+ for (const p of mandatoryFields) {
60
46
  if (!presentKeys.has(p)) {
61
47
  const v = properties[p];
62
48
  yield [p, v === undefined ? fields[p].default : v];
@@ -67,6 +53,19 @@ export class Deb extends Packager {
67
53
  }
68
54
  }
69
55
 
56
+ const debianControlName = "DEBIAN/control";
57
+ const transformers = [
58
+ {
59
+ match: entry => entry.name === debianControlName,
60
+ transform: async entry =>
61
+ new ReadableStreamContentEntry(
62
+ entry.name,
63
+ keyValueTransformer(await entry.readStream, controlProperties)
64
+ ),
65
+ createEntryWhenMissing: new EmptyContentEntry(debianControlName)
66
+ }
67
+ ];
68
+
70
69
  let debianControlEntry;
71
70
 
72
71
  for await (const entry of this.source) {
@@ -74,7 +73,7 @@ export class Deb extends Packager {
74
73
 
75
74
  await mkdir(dirname(destName), { recursive: true });
76
75
 
77
- if (entry.name === "DEBIAN/control") {
76
+ if (entry.name === debianControlName) {
78
77
  debianControlEntry = entry;
79
78
  } else {
80
79
  console.log("ENTRY", entry.name, entry.basename);
@@ -83,7 +82,6 @@ export class Deb extends Packager {
83
82
  await Promise.all(
84
83
  Object.entries(permissions).map(async ([pattern, option]) => {
85
84
  if (destName.endsWith(pattern)) {
86
- //console.log("CHMOD", option.chmod, destName, pattern);
87
85
  return chmod(destName, option.chmod);
88
86
  }
89
87
  })
@@ -92,7 +90,7 @@ export class Deb extends Packager {
92
90
  }
93
91
 
94
92
  if (!debianControlEntry) {
95
- debianControlEntry = new EmptyContentEntry("DEBIAN/control");
93
+ debianControlEntry = new EmptyContentEntry(debianControlName);
96
94
  }
97
95
 
98
96
  let destName = join(staging, debianControlEntry.name);
@@ -127,7 +125,12 @@ const fields = {
127
125
  Priority: { type: "string", recommended: true },
128
126
  Essential: { type: "boolean" },
129
127
  Origin: { type: "string" },
130
- Architecture: { alias: "arch", type: "string", default: "any", mandatory: true },
128
+ Architecture: {
129
+ alias: "arch",
130
+ type: "string",
131
+ default: "any",
132
+ mandatory: true
133
+ },
131
134
  Homepage: { alias: "homepage", type: "string" },
132
135
  Bugs: { alias: "bugs", type: "string" },
133
136
  Depends: { alias: "depends", type: "packageList" },
@@ -1,8 +1,60 @@
1
+ /**
2
+ * @typedef {Object} Field
3
+ * @property {string} alias interchangeable field name
4
+ * @property {string} type
5
+ * @property {any} default
6
+ * @property {boolean} mandatory
7
+ */
8
+
9
+ /**
10
+ * @param {Object} properties
11
+ */
1
12
  export class Packager {
13
+ static get fields() {
14
+ return {};
15
+ }
16
+
2
17
  constructor(source, properties) {
3
18
  this.source = source;
4
- this.properties = properties;
19
+ this._properties = properties;
20
+ }
21
+
22
+ get fields() {
23
+ return this.constructor.fields;
24
+ }
25
+
26
+ get properties() {
27
+ const properties = this._properties;
28
+
29
+ Object.entries(this.fields).forEach(([k, v]) => {
30
+ const e = properties[v.alias];
31
+ if (e !== undefined) {
32
+ properties[k] = e;
33
+ } else {
34
+ if (v.default !== undefined) {
35
+ properties[v.alias] = v.default;
36
+ }
37
+ }
38
+ });
39
+
40
+ return properties;
41
+ }
42
+
43
+ /**
44
+ * @return {Set<string,Field>} mandatory fields
45
+ */
46
+ get mandatoryFields() {
47
+ const mandatoryFields = new Set(
48
+ Object.entries(this.fields)
49
+ .filter(([k, v]) => v.mandatory)
50
+ .map(([k, v]) => k)
51
+ );
52
+
53
+ return mandatoryFields;
5
54
  }
6
55
 
56
+ /**
57
+ * Execute package generation
58
+ */
7
59
  async execute() {}
8
60
  }
@@ -1,67 +1,86 @@
1
- import { join, dirname } from "path";
1
+ import { join } from "path";
2
+ import { createWriteStream } from "fs";
2
3
  import { tmpdir } from "os";
3
4
  import { finished } from "stream";
4
5
  import { promisify } from "util";
5
6
  import { mkdtemp, mkdir, chmod } from "fs/promises";
6
- import { execa } from "execa";
7
+ import { execa } from "execa";
7
8
  import { Packager } from "./packager.mjs";
8
9
  import { quote } from "../util.mjs";
9
10
 
10
11
  export class PKG extends Packager {
11
-
12
- static get name() { return "pkg"; }
12
+ static get name() {
13
+ return "pkg";
14
+ }
13
15
 
14
16
  static get fileNameExtension() {
15
- return ".pkg.tar";
17
+ return ".pkg.tar.zst";
16
18
  }
17
19
 
18
- async execute() {
20
+ static get fields() {
21
+ return fields;
22
+ }
19
23
 
24
+ async execute(options) {
20
25
  const tmp = await mkdtemp(join(tmpdir(), "pkg-"));
21
26
 
27
+ const pkgbuildFileName = join(tmp, "PKGBUILD");
28
+
29
+ this.writePkbuild(pkgbuildFileName);
30
+
22
31
  await execa("makepkg", [], { cwd: tmp });
23
32
  }
33
+
34
+ writePkbuild(pkgbuildFileName) {
35
+ const out = createWriteStream(pkgbuildFileName, { encoding: "utf8" });
36
+
37
+ out.write(`
38
+ package() {
39
+ cp -r $srcdir/* "$pkgdir"
40
+ }
41
+ `);
42
+
43
+ out.end();
44
+ }
24
45
  }
25
46
 
26
47
  /**
27
48
  * well known package properties
28
49
  * https://www.archlinux.org/pacman/PKGBUILD.5.html
29
50
  */
30
- const arrayOptionsPKGBUILD = [
31
- "pkgname",
32
- "license",
33
- "source",
34
- "validpgpkeys",
35
- "noextract",
36
- "md5sums",
37
- "sha1sums",
38
- "sha256sums",
39
- "sha384sums",
40
- "sha512sums",
41
- "groups",
42
- "arch",
43
- "backup",
44
- "depends",
45
- "makedepends",
46
- "checkdepends",
47
- "optdepends",
48
- "conflicts",
49
- "provides",
50
- "replaces",
51
- "options"
52
- ];
53
-
54
- const optionsPKGBUILD = [
55
- ...arrayOptionsPKGBUILD,
56
- "pkgver",
57
- "pkgrel",
58
- "epoch",
59
- "pkgdesc",
60
- "url",
61
- "install",
62
- "changelog"
63
- ];
64
-
51
+ const fields = {
52
+ pkgname: { alias: "name", type: "string[]" },
53
+ license: { type: "string[]" },
54
+ source: { type: "string[]" },
55
+ validpgpkeys: { type: "string[]" },
56
+ noextract: { type: "string[]" },
57
+ md5sums: { type: "string[]" },
58
+ sha1sums: { type: "string[]" },
59
+ sha256sums: { type: "string[]" },
60
+ sha384sums: { type: "string[]" },
61
+ sha512sums: { type: "string[]" },
62
+ groups: { type: "string[]" },
63
+ arch: { type: "string[]" },
64
+ backup: { type: "string[]" },
65
+ depends: { type: "string[]" },
66
+ makedepends: { type: "string[]" },
67
+ checkdepends: { type: "string[]" },
68
+ optdepends: { type: "string[]" },
69
+ conflicts: { type: "string[]" },
70
+ provides: { type: "string[]" },
71
+ replaces: { type: "string[]" },
72
+ options: { type: "string[]" },
73
+
74
+ pkgver: {},
75
+ pkgrel: {},
76
+ epoch: {},
77
+ pkgdesc: {},
78
+ url: {},
79
+ install: {},
80
+ changelog: {}
81
+ };
82
+
83
+ /*
65
84
  export async function pkgbuild(context, stagingDir, out, options = {}) {
66
85
  const pkg = { contributors: [], pacman: {}, ...context.pkg };
67
86
 
@@ -139,7 +158,7 @@ ${Object.keys(properties)
139
158
  ${pkgver}
140
159
  build() {
141
160
  cd \${pkgname}${directory}
142
- sed -i 's/"version": ".*/"version": "${
161
+ sed -i 's/"version": ".* /"version": "${
143
162
  context.properties.pkgver
144
163
  }",/' package.json
145
164
  npm install
@@ -158,8 +177,6 @@ package() {
158
177
  `
159
178
  );
160
179
 
161
- out.end();
162
-
163
180
  await promisify(finished);
164
181
  }
165
182
 
@@ -177,3 +194,4 @@ function makeDepends(d) {
177
194
  return a;
178
195
  }, []);
179
196
  }
197
+ */
@@ -1,35 +1,59 @@
1
1
  import { globby } from "globby";
2
2
  import { Packager } from "./packager.mjs";
3
3
 
4
-
5
4
  export class RPM extends Packager {
6
- static get name() { return "rpm"; }
5
+ static get name() {
6
+ return "rpm";
7
+ }
7
8
 
8
9
  static get fileNameExtension() {
9
10
  return ".rpm";
10
11
  }
12
+
13
+ static get fields() {
14
+ return fields;
15
+ }
16
+
17
+ async execute(options) {
18
+ const properties = this.properties;
19
+ const mandatoryFields = this.mandatoryFields;
20
+
21
+ const tmp = await mkdtemp(join(tmpdir(), "deb-"));
22
+ const staging = join(tmp, `${properties.name}-${properties.version}`);
23
+
24
+ let specFileName = ".spec";
25
+
26
+ //if (entry.name === ".spec")
27
+
28
+ await execa("rpmbuild", ["-ba", specFileName]);
29
+ }
11
30
  }
12
31
 
32
+ const fields = {
33
+ Name: { alias: "name", type: "string" },
34
+ Summary: { alias: "description", type: "string" },
35
+ License: { alias: "license", type: "string" },
36
+ Version: { alias: "version", type: "string" },
37
+ Release: { type: "integer", default: 0 },
38
+ Packager: { type: "string" },
39
+ URL: { alias: "homepage", type: "string" }
40
+ };
41
+
42
+ const sections = {
43
+ description: {},
44
+ prep: {},
45
+ build: {},
46
+ install: {},
47
+ files: {},
48
+ changelog: {}
49
+ };
50
+
13
51
  export async function rpmspec(context, stagingDir, out, options = {}) {
14
52
  const pkg = { contributors: [], pacman: {}, ...context.pkg };
15
53
 
16
54
  const installdir = context.properties.installdir;
17
55
  let directory = "";
18
56
 
19
- if (pkg.repository) {
20
- directory = pkg.repository.directory ? "/" + pkg.repository.directory : "";
21
- }
22
-
23
- const properties = {
24
- Name: pkg.name,
25
- Summary: pkg.description,
26
- License: pkg.license,
27
- Version: context.properties.pkgver.replace(/\-.*$/, ""),
28
- Release: context.properties.pkgrel,
29
- Packager: pkg.contributors.map((c, i) => `${c.name} <${c.email}>`)[0],
30
- URL: pkg.homepage
31
- };
32
-
33
57
  const npmDistPackage = options.npmDist
34
58
  ? `( cd %{_sourcedir}${installdir}
35
59
  tar -x --transform="s/^package\\///" -f %{buildroot}${directory}/${pkg.name}-${context.properties.pkgver}.tgz)`
@@ -48,8 +72,6 @@ export async function rpmspec(context, stagingDir, out, options = {}) {
48
72
  %description
49
73
  ${pkg.description}
50
74
 
51
- %prep
52
-
53
75
  %build
54
76
  npm install
55
77
  mkdir -p %{buildroot}${installdir}
package/src/util.mjs CHANGED
@@ -1,3 +1,8 @@
1
+ import { join, dirname } from "path";
2
+ import { mkdir } from "fs/promises";
3
+ import { pipeline } from "stream/promises";
4
+ import { createWriteStream } from "fs";
5
+
1
6
  import { FileContentProvider } from "npm-pkgbuild";
2
7
 
3
8
  export const utf8StreamOptions = { encoding: "utf8" };
@@ -60,3 +65,26 @@ export function extractFromPackage(pkg) {
60
65
 
61
66
  return { properties, sources };
62
67
  }
68
+
69
+ /**
70
+ * Copy content from source into destinationDirectory
71
+ * @param {AsyncIterator<ContentEntry>} source
72
+ * @param {string} destinationDirectory
73
+ * @param {Transformer[]} transformers
74
+ */
75
+ export async function copyEntries(source, destinationDirectory, transformers) {
76
+ for await (let entry of source) {
77
+ const destName = join(destinationDirectory, entry.name);
78
+
79
+ await mkdir(dirname(destName), { recursive: true });
80
+
81
+ for (const t of transformers) {
82
+ if (t.match(entry)) {
83
+ entry = await t.transform(entry);
84
+ break;
85
+ }
86
+ }
87
+
88
+ await pipeline(await entry.readStream, createWriteStream(destName));
89
+ }
90
+ }
@@ -1,62 +0,0 @@
1
- /**
2
- * Replaces key value pairs in a stream of lines.
3
- * @param {AsyncIterator<String>} source
4
- * @param updates
5
- */
6
- export async function* keyValueTransformer(source, updates) {
7
- const presentKeys = new Set();
8
-
9
- let key, value;
10
-
11
- function* eject() {
12
- if (key !== undefined) {
13
- for(const [k,v] of updates(key, value, presentKeys)) {
14
- yield `${k}: ${v}\n`;
15
- }
16
- key = value = undefined;
17
- }
18
- }
19
-
20
- for await (const line of asLines(source)) {
21
- const m = line.match(/^(\w+):\s*(.*)/);
22
- if (m) {
23
- yield* eject();
24
- key = m[1];
25
- value = m[2];
26
- presentKeys.add(key);
27
- } else if (key !== undefined) {
28
- const m = line.match(/^\s+(.*)/);
29
- if (m) {
30
- value += m[1];
31
- } else {
32
- yield* eject();
33
- yield line + "\n";
34
- }
35
- } else {
36
- yield line + "\n";
37
- }
38
- }
39
-
40
- yield* eject();
41
-
42
- for(const [k,v] of updates(undefined, undefined, presentKeys)) {
43
- yield `${k}: ${v}\n`;
44
- }
45
- }
46
-
47
- async function* asLines(source) {
48
- let buffer = "";
49
-
50
- for await (let chunk of source) {
51
- buffer += chunk.toString();
52
- const lines = buffer.split(/\n\r?/);
53
- buffer = lines.pop();
54
- for (const line of lines) {
55
- yield line;
56
- }
57
- }
58
-
59
- if (buffer.length > 0) {
60
- yield buffer;
61
- }
62
- }