Skip to content

Instantly share code, notes, and snippets.

@ds300
Created June 28, 2017 11:45
Show Gist options
  • Save ds300/158250f230d1825af8a3edd6e7af9cc0 to your computer and use it in GitHub Desktop.
Save ds300/158250f230d1825af8a3edd6e7af9cc0 to your computer and use it in GitHub Desktop.
Automatically choose the latest versions of all packages when running yarn --flat
#!/usr/bin/env node
# run this before using: yarn add --dev node-pty semver
const os = require("os")
const pty = require("node-pty")
const semver = require("semver")
function semverComparator(a, b) {
if (semver.lt(a, b)) {
return -1
} else if (semver.gt(a, b)) {
return 1
} else {
return 0
}
}
const proc = pty.spawn("yarn", ["install", "--flat"], {
name: "xterm-color",
cols: 80,
rows: 30,
env: process.env,
})
let buff = ""
proc.on("data", function(data) {
buff += data.toString()
if (buff.match(/Answer\?:/g)) {
const packageName = buff.match(/suitable version for "(\S+)"/)[1]
const versions = buff
.split(/\r?\n/g)
.filter(line => line.match("which resolved to"))
.map(line => line.match(/"(\S+)"$/)[1])
const sorted = versions.slice(0).sort(semverComparator)
const highestVersion = sorted[sorted.length - 1]
const choice = versions.indexOf(highestVersion) + 1
console.log(`Choosing ${packageName}@${highestVersion}`)
proc.write(choice.toString() + "\r\n")
buff = ""
}
})
proc.on("error", err => {
console.error(err)
})
@AndePa01
Copy link

I made some changes to get it working on my Windows environment with a large project.

const pty = require("node-pty");
const semver = require("semver");

function semverComparator(a, b) {
  if (semver.lt(a, b)) {
    return -1;
  } else if (semver.gt(a, b)) {
    return 1;
  } else {
    return 0;
  }
}

const proc = pty.spawn(`yarn${process.platform === "win32" ? ".cmd" : ""}`, ["install", "--flat"], {
  name: "xterm-color",
  cols: 8000,
  rows: 9001,
  env: process.env,
});

let buff = "";

function onAnswer() {
  const packageName = buff.match(/suitable version for "(\S+)"/)[1];
  const versions = buff
    .split(/\r?\n/g)
    .filter((line) => line.match("which resolved to"))
    .map((line) => line.match(/o "(\S+)"/)[1]);
  if (!versions || versions.length < 2) {
    throw new Error("No versions found!");
  }
  const sorted = versions.slice(0).sort(semverComparator);
  const highestVersion = sorted[sorted.length - 1];
  const choice = versions.indexOf(highestVersion) + 1;
  console.log(`Choosing ${packageName}@${highestVersion}`);
  buff = "";
  proc.write(choice.toString() + "\r\n");
}

let receivedInput = false;
let outputMode = false;
let answerFound = false;
let idlingTimeout;
proc.onData(function (data) {
  if (outputMode) {
    console.log(data);
  } else {
    buff += data.toString();
    if (buff.match(/Answer\?:/g)) {
      if (!answerFound) {
        answerFound = true;
        console.clear();
      }
      receivedInput = true;
      if (idlingTimeout) {
        clearTimeout(idlingTimeout);
      }
      idlingTimeout = setTimeout(onAnswer, 500);
    } else if (buff.match("Fetching packages")) {
      outputMode = true;
    } else if (!answerFound) {
      console.log(data);
    }
  }
});

proc.on("error", (err) => {
  console.error(err);
});

proc.onExit(function (_e) {
  process.exit(1);
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment