def parseNodeVersion = { String value -> value.replaceFirst("^v", "") .tokenize(".") .collect { part -> def matcher = part =~ /\d+/ matcher.find() ? matcher.group().toInteger() : 0 } } ext.resolveNodeExecutable = { def fromEnv = System.getenv("NODE_BINARY") if (fromEnv != null && !fromEnv.trim().isEmpty()) { return fromEnv.trim() } def home = System.getProperty("user.home") def candidates = [] def nvmVersionsDir = new File(home, ".nvm/versions/node") if (nvmVersionsDir.isDirectory()) { def versionDirs = nvmVersionsDir.listFiles()?.findAll { new File(it, "bin/node").canExecute() } ?: [] versionDirs.sort { a, b -> def aVersion = parseNodeVersion(a.name) def bVersion = parseNodeVersion(b.name) for (int i = 0; i < Math.max(aVersion.size(), bVersion.size()); i++) { def aPart = i < aVersion.size() ? aVersion[i] : 0 def bPart = i < bVersion.size() ? bVersion[i] : 0 if (aPart != bPart) { return bPart <=> aPart } } return b.name <=> a.name }.each { candidates.add(new File(it, "bin/node").absolutePath) } } candidates.addAll([ "${home}/.nvm/current/bin/node", "/opt/homebrew/bin/node", "/usr/local/bin/node" ]) return candidates.find { new File(it).canExecute() } ?: "node" }