nvexeca
Version:
nvm + execa = nvexeca
122 lines (80 loc) • 2.32 kB
JavaScript
import{readdir,readFile,stat}from"node:fs/promises";
import{delimiter,normalize}from"node:path";
import pMap from"p-map";
import{isDirectory}from"path-type";
import{getContent}from"./content.js";
import{isOutputDir}from"./output.js";
export const listSrcPaths=async(pathValue)=>{
const srcBinDirs=[...new Set(pathValue.split(delimiter))];
const srcPaths=await Promise.all(srcBinDirs.map(getSrcPaths));
return srcPaths.flat().filter(hasPriority)
};
const getSrcPaths=async(srcBinDir)=>{
const srcBinDirA=normalize(srcBinDir);
if(isOutputDir(srcBinDirA)){
return[]
}
if(!(await isDirectory(srcBinDirA))){
return[]
}
const filenames=await readdir(srcBinDirA);
const srcPaths=await pMap(
filenames,
(filename)=>getSrcPath({srcBinDir:srcBinDirA,filenames,filename}),
{concurrency:FILE_CONCURRENCY}
);
return srcPaths.flat()
};
const FILE_CONCURRENCY=100;
const getSrcPath=async({srcBinDir,filenames,filename})=>{
if(!CMD_BINARY_REGEXP.test(filename)){
return[]
}
const bashFilename=filename.replace(CMD_BINARY_REGEXP,"");
if(!(await isNodeBinary(srcBinDir,filenames,bashFilename))){
return[]
}
const ps1Filename=filename.replace(CMD_BINARY_REGEXP,".ps1");
const srcPaths=await readSrcPaths({
srcBinDir,
bashFilename,
filename,
ps1Filename,
filenames
});
return srcPaths
};
const CMD_BINARY_REGEXP=/\.cmd$/u;
const isNodeBinary=async(srcBinDir,filenames,bashFilename)=>{
if(!filenames.includes(bashFilename)){
return false
}
const bashPath=`${srcBinDir}/${bashFilename}`;
const bashStat=await stat(bashPath);
if(!bashStat.isFile()){
return false
}
const bashContent=await readFile(bashPath,"utf8");
return NODE_DETECT_REGEXP.test(bashContent)
};
const NODE_DETECT_REGEXP=/\[ -x "(\$basedir\/node|\$NODE_EXE)" \]/u;
const readSrcPaths=({
srcBinDir,
bashFilename,
filename,
ps1Filename,
filenames
})=>
Promise.all([
readSrcPath({type:"bash",srcBinDir,filename:bashFilename}),
readSrcPath({type:"cmd",srcBinDir,filename}),
...(filenames.includes(ps1Filename)?
[readSrcPath({type:"ps1",srcBinDir,filename:ps1Filename})]:
[])]
);
const readSrcPath=async({type,srcBinDir,filename})=>{
const content=await getContent({type,srcBinDir,filename});
return{filename,content}
};
const hasPriority=({filename},index,srcPaths)=>
srcPaths.slice(0,index).every((srcPath)=>srcPath.filename!==filename);