support bare executables and xbin on windows for jq
[webi-installers/.git] / _webi / packages.js
1 'use strict';
2
3 var frontmarker = require('./frontmarker.js');
4 var shmatter = require('shmatter');
5 var fs = require('fs');
6 var path = require('path');
7
8 var pkgs = module.exports;
9 pkgs.create = function (Pkgs, basepath) {
10   if (!Pkgs) {
11     Pkgs = {};
12   }
13   if (!basepath) {
14     basepath = path.join(__dirname, '../');
15   }
16
17   Pkgs.all = function () {
18     return fs.promises.readdir(basepath).then(function (nodes) {
19       var items = [];
20       return nodes
21         .reduce(function (p, node) {
22           return p.then(function () {
23             return pkgs.get(node).then(function (meta) {
24               if (meta && '_' !== node[0]) {
25                 meta.name = node;
26                 items.push(meta);
27               }
28             });
29           });
30         }, Promise.resolve())
31         .then(function () {
32           return items;
33         });
34     });
35   };
36
37   Pkgs.get = function (node) {
38     var yash = path.join(basepath, node, 'package.yash');
39     var curlbash = path.join(basepath, node, 'install.sh');
40     var readme = path.join(basepath, node, 'README.md');
41     var winstall = path.join(basepath, node, 'install.ps1');
42     return Promise.all([
43       fs.promises
44         .readFile(readme, 'utf-8')
45         .then(function (txt) {
46           // TODO
47           return frontmarker.parse(txt);
48         })
49         .catch(function (e) {
50           if ('ENOENT' !== e.code && 'ENOTDIR' !== e.code) {
51             console.error("failed to read '" + node + "/README.md'");
52             console.error(e);
53           }
54         }),
55       fs.promises
56         .readFile(yash, 'utf-8')
57         .then(function (txt) {
58           return shmatter.parse(txt);
59         })
60         .catch(function (e) {
61           // no yash package description
62           yash = '';
63           if ('ENOENT' !== e.code && 'ENOTDIR' !== e.code) {
64             console.error("failed to parse '" + node + "/package.yash'");
65             console.error(e);
66           }
67           return fs.promises.readFile(curlbash, 'utf-8').then(function (txt) {
68             return shmatter.parse(txt);
69           });
70         })
71         .catch(function (e) {
72           // no *nix installer
73           curlbash = '';
74           if ('ENOENT' !== e.code && 'ENOTDIR' !== e.code) {
75             console.error("failed to parse '" + node + "/install.sh'");
76             console.error(e);
77           }
78         }),
79       fs.promises.access(winstall).catch(function (e) {
80         // no winstaller
81         winstall = '';
82         if ('ENOENT' !== e.code && 'ENOTDIR' !== e.code) {
83           console.error("failed to read '" + node + "/install.ps1'");
84           console.error(e);
85         }
86       })
87     ]).then(function (items) {
88       var meta = items[0] || items[1];
89       if (!meta) {
90         // doesn't exist
91         return;
92       }
93       meta.windows = !!winstall;
94       meta.bash = !!curlbash;
95
96       return meta;
97     });
98   };
99
100   return Pkgs;
101 };
102 pkgs.create(pkgs);
103
104 if (module === require.main) {
105   pkgs.all().then(function (data) {
106     console.info('package info:');
107     console.info(data);
108   });
109 }