hasundue / nublar

A command-line tool to manage Deno scripts installed via deno install
https://deno.land/x/nublar
MIT License
17 stars 1 forks source link

update unversioned binaries #97

Closed sigmaSd closed 9 months ago

sigmaSd commented 10 months ago

I think a cool feature would be to update unversioned binaries to their latest version

I have stuff like

       │ File: /home/mrcool/.deno/bin/deno_bindgen
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ #!/bin/sh
   2   │ # generated by deno install
   3   │ exec deno run --allow-all --quiet --no-config 'https://deno.land/x/deno_bindgen/cli.ts' "$@"
───────┴─────────────────────────────────────────────────────────────────────────────────────────────────

with this feature I expect an update form unversioned to x.x.x (whatver the latest is)

This will make suddenly most of my binaries compatible with nublar with no effort of my part as the user

sigmaSd commented 10 months ago

I have this done locally but it requires changes to deno-udd (to handle unspecified version)

sigmaSd commented 10 months ago

Here is how it looks btw image

hasundue commented 10 months ago

It would be good if you could enable this feature with an option flag.

We might migrate to https://github.com/deaddeno/update or find a way to use https://github.com/hasundue/deno-molt ?

sigmaSd commented 10 months ago

I feel like molt doesn't really fit, since the whole keypoint which is deno graph doesn't work here, unless maybe you expose some useful utilities

Does this really need a dependency can't we just regex search and replace deno urls ?

hasundue commented 10 months ago

I feel like molt doesn't really fit, since the whole keypoint which is deno graph doesn't work here,

True. Just using regex is probably fine, since we do not really need variety of registries anymore after npm: specifier was introduced.

sigmaSd commented 10 months ago

I'm using this script for now

import homeDir from "https://deno.land/x/dir@1.5.1/home_dir/mod.ts";
import * as stdPath from "https://deno.land/std@0.204.0/path/mod.ts";
import * as infer from "npm:deno-infer@1.0.8";

function* getPrograms() {
  const homeDirPath = homeDir();
  if (!homeDirPath) throw "home dir not found";
  const programsDir = Deno.readDirSync(
    stdPath.join(homeDirPath, ".deno", "bin"),
  );
  for (const entry of programsDir) {
    if (!entry.isFile) continue;
    const path = stdPath.join(homeDirPath, ".deno", "bin", entry.name);
    //FIXME: windows have a different extension
    if (infer.getFromPath(path)?.extension() !== "sh") continue;
    yield {
      name: entry.name,
      path,
    };
  }
}

async function update(text: string) {
  let newText = text;
  for (
    const match of text.matchAll(
      /https:\/\/deno.land\/x\/([^@/]+)(@[^/]+)*\//g,
    )
  ) {
    let [_url, name, version] = match;
    // remove the @
    if (version) version = version.slice(1);
    const latestVersion: string | undefined = await fetch(
      `https://cdn.deno.land/${name}/meta/versions.json`,
    ).then((r) => r.json()).then((r) => r.latest);

    if (latestVersion === undefined) {
      console.error(
        "Could not determine package latest version, name: " + name,
      );
      return;
    }

    if (version !== latestVersion) {
      console.log(
        `${name} version: '${version}' remote-version: '${latestVersion}'`,
      );
      const oldUrl = version
        ? `https://deno.land/x/${name}@${version}/`
        : `https://deno.land/x/${name}/`;
      newText = newText.replace(
        oldUrl,
        `https://deno.land/x/${name}@${latestVersion}/`,
      );
    }
  }
  if (newText === text) return;
  return newText;
}

if (import.meta.main) {
  for (const program of getPrograms()) {
    const text = Deno.readTextFileSync(program.path);
    const newText = await update(text);
    if (newText !== undefined) {
      if (confirm(`Update ${program.name} ?`)) {
        Deno.writeTextFileSync(program.path, newText);
      }
    }
  }
}
hasundue commented 10 months ago

Thanks. Looks good, very clean. Can I integrate your implementation into nublar, or should I ask you to create a PR with your authority?

hasundue commented 10 months ago

Ah maybe I can just use a routine in molt with a little work. Let me try.

sigmaSd commented 10 months ago

It's cool there is nothing to copyright there, Iits better if nublar gets more features

hasundue commented 9 months ago

Now fixing molt for this https://github.com/hasundue/molt/pull/63

hasundue commented 9 months ago

Done but not tested extensively. Bug reports would be very helpful.

sigmaSd commented 9 months ago

thanks awesome