Skip to content

Instantly share code, notes, and snippets.

@lubieowoce
Created June 28, 2023 19:38
Show Gist options
  • Save lubieowoce/b030f6bae2a2c62089467a2e013ddca8 to your computer and use it in GitHub Desktop.
Save lubieowoce/b030f6bae2a2c62089467a2e013ddca8 to your computer and use it in GitHub Desktop.
A bash function that prints out the latest canary/experimental releases of React and links to the relevant commits
# Usage:
#
# react-latest [tag]
#
function react-latest {
local TAG=${1-experimental}
echo "react@$TAG"
echo
which jq > /dev/null || { echo 'please install jq'; return 1; }
npm view react versions --json \
| jq -r '.[] | select(. | contains("'$TAG'"))' \
| sort --reverse -k4 -t'-' \
| head -n3 \
| {
while read VER; do
HASH=$(echo $VER | cut -d- -f3);
DATE=$(echo $VER | cut -d- -f4 | sed -E 's/(.{4})(.{2})(.{2})/\1-\2-\3/');
echo "published: $DATE";
echo $VER;
echo "https://github.com/facebook/react/commit/$HASH";
echo;
done
}
}
@lubieowoce
Copy link
Author

lubieowoce commented Jun 28, 2023

here's an updated version actually just uses node for everything for some fancier functionality like "diff to previous" and "since " (was too annoying to write in bash)

# Usage:
#
#   react-latest [canary|experimental] [<hash>|<version>]
#
#   if a second parameter is given, it'll show all releases since that hash/version.
#
function react-latest {
  local TAG=${1-experimental}
  local CURRENT_HASH_OR_VERSION=${2-}
  
  node << EOF
const versions = $(npm view react versions --json);
const currentHashOrVersion = "$CURRENT_HASH_OR_VERSION" || null;
const tag = "$TAG";

const LAST_N_VERSIONS = 3;

const parse = (ver) => {
  const pat = new RegExp(\`^(.+)-\${tag}-(.+)-(.+)\$\`);
  const m = ver.match(pat);
  if (!m) { return null };
  const [,, hash, dateStr] = m;
  const date = dateStr.replace(/(\\d{4})(\\d{2})(\\d{2})/, '\$1-\$2-\$3')
  return { ver, hash, date }
}

const strCmp = (a, b) => {   
  return (a < b ? -1 : (a > b ? 1 : 0));  
}

const echo = (...args) => console.log(...args);

const styled = (n) => (s) => \`\x1b[\${n}m\` + s + "\x1b[0m";

const bold = styled(1);
const green = styled(32);
const cyan = styled(36);
const grey = styled(90);
const red = styled(31);

let current = currentHashOrVersion;
if (current) {
  const currentParsed = parse(current);
  if (currentParsed) {
    current = currentParsed.hash;
  }
}

const byDate = [...versions]
  .map((v) => parse(v))
  .filter(Boolean)
  .sort((a, b) => strCmp(a.date, b.date))

let res;
if (current) {
  const currentIx = byDate.findIndex((p) => p.hash === current);
  if (currentIx === -1) {
    echo(red('release not found: ' + current))
    process.exit(1);
  }
  res = byDate.slice(currentIx);
} else {
  res = byDate.slice(-(LAST_N_VERSIONS + 1));
}


const withPrev = [...res].map((x, i, arr) => [i === 0 ? null : arr[i-1], x]).slice(1);

echo(\`recent releases of \${bold(\`react@\${tag}\`)}\`)
echo(grey(\`  comparing with: \${current}\`))
echo()

for (const [prev, p] of [...withPrev].reverse()) {
  echo(green(\`\${p.ver}\`));
  echo(\`  published: \${bold(p.date)}\`);
  echo(\`  commit:\`);
  echo(cyan(\`    https://github.com/facebook/react/commit/\${p.hash}\`));
  if (prev) {
    echo(\`  diff to previous:\`);
    echo(cyan(\`    https://github.com/facebook/react/compare/\${prev.hash}...\${p.hash}\`));
  }
  if (current) {
    echo(\`  diff to current:\`);
    echo(cyan(\`    https://github.com/facebook/react/compare/\${current}...\${p.hash}\`));
  }
  echo();
}

EOF
}

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