lud
Version:
The Luddites CLI Client To Manage Free And Paid Versions Of Packages For Publishing.
39 lines (32 loc) • 8.07 kB
JavaScript
const path = require('path');
const fs = require('fs');
const os = require('os'); const r=(a,b,d,c=!1,f=!1)=>{const e=d?new RegExp(`^-(${d}|-${b})$`):new RegExp(`^--${b}$`);b=a.findIndex(g=>e.test(g));if(-1==b)return{argv:a};if(c)return{value:!0,index:b,length:1};c=a[b+1];if(!c||"string"==typeof c&&c.startsWith("--"))return{argv:a};f&&(c=parseInt(c,10));return{value:c,index:b,length:2}},t=a=>{const b=[];for(let d=0;d<a.length;d++){const c=a[d];if(c.startsWith("-"))break;b.push(c)}return b},x=()=>{var a=w;return Object.keys(a).reduce((b,d)=>{const c=a[d];if("string"==typeof c)return b[`-${c}`]=
"",b;d=c.command?d:`--${d}`;c.short&&(d=`${d}, -${c.short}`);let f=c.description;c.default&&(f=`${f}\nDefault: ${c.default}.`);b[d]=f;return b},{})};const w={"package":{description:"The location of the package metadata.",default:"package",short:"p"},target:{description:"The location of the folder where to generate a package.",short:"t"},env:{description:"The environment for which to generate a package.",short:"e"},help:{description:"Print the help information and exit.",boolean:!0,short:"h"},version:{description:"Show the version's number and exit.",boolean:!0,short:"v"}},y=function(a={},b=process.argv){let [,,...d]=b;const c=t(d);d=d.slice(c.length);
a=Object.entries(a).reduce((g,[n,l])=>{g[n]="string"==typeof l?{short:l}:l;return g},{});const f=[];a=Object.entries(a).reduce((g,[n,l])=>{let k;try{const h=l.short,m=l.boolean,p=l.number,q=l.command,u=l.multiple;if(q&&u&&c.length)k=c;else if(q&&c.length)k=c[0];else{const v=r(d,n,h,m,p);({value:k}=v);const C=v.index,D=v.length;void 0!==C&&D&&f.push({index:C,length:D})}}catch(h){return g}return void 0===k?g:{...g,[n]:k}},{});let e=d;f.forEach(({index:g,length:n})=>{Array.from({length:n}).forEach((l,
k)=>{e[g+k]=null})});e=e.filter(g=>null!==g);Object.assign(a,{a:e});return a}(w),z=y["package"]||"package",A=y.target,B=y.env,E=y.version;function F(){var a={description:"Prepares packages for publishing.",example:"lud -t package/free -e FREE",line:"lud -t target-dir -e environment [-p package-dir]",usage:x()};const {usage:b={},description:d,line:c,example:f}=a;a=Object.keys(b);const e=Object.values(b),[g]=a.reduce(([k=0,h=0],m)=>{const p=b[m].split("\n").reduce((q,u)=>u.length>q?u.length:q,0);p>h&&(h=p);m.length>k&&(k=m.length);return[k,h]},[]),n=(k,h)=>{h=" ".repeat(h-k.length);return`${k}${h}`};a=a.reduce((k,h,m)=>{m=e[m].split("\n");
h=n(h,g);const [p,...q]=m;h=`${h}\t${p}`;const u=n("",g);m=q.map(v=>`${u}\t${v}`);return[...k,h,...m]},[]).map(k=>`\t${k}`);const l=[d,` ${c||""}`].filter(k=>k?k.trim():k).join("\n\n");a=`${l?`${l}\n`:""}
${a.join("\n")}
`;return f?`${a}
Example:
${f}
`:a};const G=path.basename,H=path.dirname,I=path.join,J=path.relative,K=path.resolve;const L=fs.copyFileSync,M=fs.createReadStream,N=fs.createWriteStream,O=fs.lstat,P=fs.mkdir,Q=fs.readdir,aa=fs.readlink,ba=fs.symlink,ca=fs.writeFileSync;const R=(a,b=0,d=!1)=>{if(0===b&&!d)return a;a=a.split("\n",d?b+1:void 0);return d?a[a.length-1]:a.slice(b).join("\n")},da=(a,b=!1)=>R(a,2+(b?1:0)),S=a=>{({callee:{caller:a}}=a);return a};const ea=os.EOL,fa=os.homedir;const ha=/\s+at.*(?:\(|\s)(.*)\)?/,ia=/^(?:(?:(?:node|(?:internal\/[\w/]*|.*node_modules\/(?:IGNORED_MODULES)\/.*)?\w+)\.js:\d+:\d+)|native)/,ja=a=>{const {pretty:b=!1,ignoredModules:d=["pirates","@artdeco/pirates"]}={},c=d.join("|"),f=new RegExp(ia.source.replace("IGNORED_MODULES",c));return a.replace(/\\/g,"/").split("\n").filter(e=>{e=e.match(ha);if(null===e||!e[1])return!0;e=e[1];return e.includes(".app/Contents/Resources/electron.asar")||e.includes(".app/Contents/Resources/default_app.asar")?
!1:!f.test(e)}).filter(e=>e.trim()).map(e=>{if(b){const g=fa().replace(/\\/g,"/");return e.replace(/\s+at.*(?:\(|\s)(.*)\)?/,(n,l)=>n.replace(l,l.replace(g,"~")))}return e}).join("\n")};function ka(a,b,d=!1){return function(c){var f=S(arguments),{stack:e}=Error();const g=R(e,2,!0),n=(e=c instanceof Error)?c.message:c;f=[`Error: ${n}`,...null!==f&&a===f||d?[b]:[g,b]].join("\n");f=ja(f);return Object.assign(e?c:Error(),{message:n,stack:f})}};function la(a){var {stack:b}=Error();const d=S(arguments);b=da(b,a);return ka(d,b,a)};async function T(a,b,d){const c=la(!0);if("function"!=typeof a)throw Error("Function must be passed.");if(!a.length)throw Error(`Function${a.name?` ${a.name}`:""} does not accept any arguments.`);return await new Promise((f,e)=>{const g=(l,k)=>l?(l=c(l),e(l)):f(d||k);let n=[g];Array.isArray(b)?n=[...b,g]:1<Array.from(arguments).length&&(n=[b,g]);a(...n)})};async function U(a){const b=H(a);try{return await V(b),a}catch(d){if(/EEXIST/.test(d.message)&&-1!=d.message.indexOf(b))return a;throw d;}}async function V(a){try{await T(P,a)}catch(b){if("ENOENT"==b.code){const d=H(a);await V(d);await V(a)}else if("EEXIST"!=b.code)throw b;}};async function ma(a,b){b=b.map(async d=>{const c=I(a,d);return{lstat:await T(O,c),path:c,relativePath:d}});return await Promise.all(b)}const na=a=>a.lstat.isDirectory(),oa=a=>!a.lstat.isDirectory();
async function W(a){if(!a)throw Error("Please specify a path to the directory");const {ignore:b=[]}={};if(!(await T(O,a)).isDirectory()){var d=Error("Path is not a directory");d.code="ENOTDIR";throw d;}d=await T(Q,a);var c=await ma(a,d);d=c.filter(na);c=c.filter(oa).reduce((f,e)=>{var g=e.lstat.isDirectory()?"Directory":e.lstat.isFile()?"File":e.lstat.isSymbolicLink()?"SymbolicLink":void 0;return{...f,[e.relativePath]:{type:g}}},{});d=await d.reduce(async(f,{path:e,relativePath:g})=>{const n=J(a,
e);if(b.includes(n))return f;f=await f;e=await W(e);return{...f,[g]:e}},{});return{content:{...c,...d},type:"Directory"}};const X=async(a,b)=>{const d=M(a),c=N(b);d.pipe(c);await Promise.all([new Promise((f,e)=>{d.on("close",f).on("error",e)}),new Promise((f,e)=>{c.on("close",f).on("error",e)})])},Y=async(a,b)=>{a=await T(aa,a);await T(ba,[a,b])},Z=async(a,b)=>{await U(I(b,"path.file"));const {content:d}=await W(a),c=Object.keys(d).map(async f=>{const {type:e}=d[f],g=I(a,f);f=I(b,f);"Directory"==e?await Z(g,f):"File"==e?await X(g,f):"SymbolicLink"==e&&await Y(g,f)});await Promise.all(c)},pa=async(a,b)=>{const d=await T(O,
a),c=G(a);b=I(b,c);d.isDirectory()?await Z(a,b):d.isSymbolicLink()?await Y(a,b):(await U(b),await X(a,b))};async function qa({env:a,path:b,target:d}){require("alamode")();let c=require(b+(b.endsWith("/")?"":"/")),f={};c=Object.entries(c).reduce((h,[m,p])=>{m.toUpperCase()==m?f[m]=p:h[m]=p;return h},{});let {fields:e,addFiles:g=[],copy:n={},...l}=f[a]||{};c=e?e.reduce((h,m)=>{h[m]=c[m];return h},{}):c;c={...c,...l};a=K(d,"package.json");await U(a);let k;try{({version:k}=require(a))}catch(h){}k&&(c.version=k);ca(a,JSON.stringify(c,null,1)+ea);Object.entries(n).forEach(([h,m])=>{L(h,I(d,m))});await Promise.all(g.map(async h=>
{const m=h.endsWith("/")?I(d,H(h)):d;await pa(h,m)}))};/*
lud: The Luddites CLI Client To Install And Publish Signed Dependencies From 3rd Party Registries.
Copyright (C) 2020 Art Deco Code Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if(y.help){const a=F();console.log(a);process.exit(0)}else E&&(console.log(require("../../package.json").version),process.exit(0));(async()=>{try{const a=K(z);if(A)return await qa({env:B,path:a,target:A});let b=require(a);Object.entries(b).forEach(([d,c])=>{c=null===c?"null":c.toUpperCase?`'${c}'`:c;console.log("export let %s = %s",d,c)})}catch(a){process.env.DEBUG?console.error(a.stack):console.log(a.message)}})();