diff --git a/README.md b/README.md index 3bc778e..7ba4045 100644 --- a/README.md +++ b/README.md @@ -42,9 +42,31 @@ Or checkout these two videos: ## Installing Silver Bullet -Silver Bullet is built using [Deno](https://deno.land). To install it, you will -need to have Deno installed (tested on 1.26 or later). If you have homebrew on a -Mac, this is just a single `brew install deno` away. +### Installing Deno + +Silver Bullet is built using [Deno](https://deno.land). To install Deno on Linux +or Mac run: + +```shell +curl -fsSL https://deno.land/install.sh | sh +``` + +This will install Deno into `~/.deno/bin`, add this folder to your `PATH` in +your `~/.bashrc` or `~/.zshrc` file. + +To install Deno on Windows (using Powershell) run: + +```powershell +irm https://deno.land/install.ps1 | iex +``` + +### Install Silver Bullet + +With Deno installed (see instruction above), run: + +```shell +deno install -f --name silverbullet -A --unstable https://get.silverbullet.md +``` To run Silver Bullet create a folder for your pages (it can be empty, or be an existing folder with `.md` files) and run the following command in your diff --git a/cmd/fix.ts b/cmd/fix.ts new file mode 100644 index 0000000..c268a12 --- /dev/null +++ b/cmd/fix.ts @@ -0,0 +1,29 @@ +import { path } from "../server/deps.ts"; + +export async function fixCommand(_options: any, folder: string) { + folder = path.resolve(Deno.cwd(), folder); + console.log("Now going to attempt to fix", folder); + console.log(`First, we'll purge the ${folder}/_plug folder...`); + try { + await Deno.remove(path.join(folder, "_plug"), { recursive: true }); + } catch (e: any) { + if (e instanceof Deno.errors.NotFound) { + console.log("No _plug folder found, nothing to do here."); + } else { + console.error("Something went wrong:", e); + } + } + console.log("And now we'll delete data.db"); + try { + await Deno.remove(path.join(folder, "data.db")); + } catch (e: any) { + if (e instanceof Deno.errors.NotFound) { + console.log("No data.db found, nothing to do here."); + } else { + console.error("Something went wrong:", e); + } + } + console.log( + "Alright then, that should be it. Try running Silver Bullet again.", + ); +} diff --git a/cmd/server.ts b/cmd/server.ts new file mode 100644 index 0000000..4590513 --- /dev/null +++ b/cmd/server.ts @@ -0,0 +1,26 @@ +import { path } from "../server/deps.ts"; +import { HttpServer } from "../server/http_server.ts"; +import assetBundle from "../dist/asset_bundle.json" assert { type: "json" }; +import { AssetBundle, AssetJson } from "../plugos/asset_bundle/bundle.ts"; + +export function serveCommand(options: any, folder: string) { + const pagesPath = path.resolve(Deno.cwd(), folder); + const port = options.port || 3000; + + console.log( + "Going to start Silver Bullet on port", + port, + "serving pages from", + pagesPath, + ); + + const httpServer = new HttpServer({ + port: port, + pagesPath: pagesPath, + assetBundle: new AssetBundle(assetBundle as AssetJson), + password: options.password, + }); + httpServer.start().catch((e) => { + console.error(e); + }); +} diff --git a/cmd/upgrade.ts b/cmd/upgrade.ts new file mode 100644 index 0000000..1f78e4b --- /dev/null +++ b/cmd/upgrade.ts @@ -0,0 +1,39 @@ +import { version } from "../version.ts"; + +export async function upgradeCommand() { + console.log( + "Now going to attempt an upgrade, this may involve downloading the Internet (but there may be cool spinners). Prepare!", + ); + + const p = Deno.run({ + cmd: ["deno", "cache", "--reload", Deno.mainModule], + }); + const exitCode = await p.status(); + if (!exitCode.success) { + console.error("Something went wrong there..."); + Deno.exit(1); + } + console.log( + "So, that's done. Now let's see if this actually did anything...", + ); + const vp = Deno.run({ + cmd: ["deno", "run", "-A", "--unstable", Deno.mainModule, "version"], + stdout: "piped", + }); + const versionStatus = await vp.status(); + if (!versionStatus.success) { + console.error("Could not run version command, something is wrong."); + Deno.exit(1); + } + const rawVersion = await vp.output(); + const newVersion = new TextDecoder().decode(rawVersion).trim(); + if (newVersion === version) { + console.log( + `Nope. I hate to tell you this, but it looks like we're stilling running ${newVersion}.\nThis was a bit of a futile exercise. Let's try again soon some time.`, + ); + } else { + console.log( + `Congrats, we've upgraded you from ${version} to ${newVersion}. Seems like quite bump, enjoy! https://silverbullet.md/changelog/ may give you more hints on what's new.`, + ); + } +} diff --git a/cmd/version.ts b/cmd/version.ts new file mode 100644 index 0000000..19082be --- /dev/null +++ b/cmd/version.ts @@ -0,0 +1,5 @@ +import { version } from "../version.ts"; + +export function versionCommand() { + console.log(version); +} diff --git a/deno.jsonc b/deno.jsonc index 703daa8..61b14d7 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -1,14 +1,15 @@ { "tasks": { "clean": "rm -rf dist dist_bundle", - "install": "deno install -f -A --unstable plugos/bin/plugos-bundle.ts && deno install -f -n silverbullet -A --unstable server/silverbullet.ts", + "install": "deno install -f -A --unstable plugos/bin/plugos-bundle.ts && deno install -f -A --unstable silverbullet.ts", "test": "deno test -A --unstable", "build": "./build_plugs.sh && deno run -A --unstable --check build.ts", "watch-web": "deno run -A --unstable --check build.ts --watch", - "watch-server": "deno run -A --unstable --check --watch server/silverbullet.ts", + "watch-server": "deno run -A --unstable --check --watch silverbullet.ts", // The only reason to run a shell script is that deno task doesn't support globs yet (e.g. *.plug.yaml) "watch-plugs": "./build_plugs.sh --watch", - "bundle": "deno bundle --importmap import_map.json server/silverbullet.ts dist/silverbullet.js", + "bundle": "deno bundle --importmap import_map.json silverbullet.ts dist/silverbullet.js", + // Regenerates some bundle files (checked into the repo) "generate": "deno run -A plugos/gen.ts" }, diff --git a/server/http_server.ts b/server/http_server.ts index 1186215..7db9159 100644 --- a/server/http_server.ts +++ b/server/http_server.ts @@ -85,17 +85,26 @@ export class HttpServer { this.system.addHook(namespaceHook); // The space - this.spacePrimitives = new AssetBundlePlugSpacePrimitives( - new EventedSpacePrimitives( - new PlugSpacePrimitives( - new DiskSpacePrimitives(options.pagesPath), - namespaceHook, + try { + this.spacePrimitives = new AssetBundlePlugSpacePrimitives( + new EventedSpacePrimitives( + new PlugSpacePrimitives( + new DiskSpacePrimitives(options.pagesPath), + namespaceHook, + ), + this.eventHook, ), - this.eventHook, - ), - this.assetBundle, - ); - this.space = new Space(this.spacePrimitives); + this.assetBundle, + ); + this.space = new Space(this.spacePrimitives); + } catch (e: any) { + if (e instanceof Deno.errors.NotFound) { + console.error("Pages folder", options.pagesPath, "not found"); + } else { + console.error(e.message); + } + Deno.exit(1); + } // The database used for persistence (SQLite) this.db = new AsyncSQLite(path.join(options.pagesPath, "data.db")); diff --git a/server/silverbullet.ts b/server/silverbullet.ts deleted file mode 100755 index b3e6aaa..0000000 --- a/server/silverbullet.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Command } from "https://deno.land/x/cliffy@v0.25.2/command/command.ts"; - -import * as path from "https://deno.land/std@0.158.0/path/mod.ts"; -import { HttpServer } from "./http_server.ts"; -import assetBundle from "../dist/asset_bundle.json" assert { type: "json" }; -import { AssetBundle, AssetJson } from "../plugos/asset_bundle/bundle.ts"; - -await new Command() - .name("silverbullet") - .description("Markdown as a platform") - // Main command - .arguments("") - .option("-p, --port ", "Port to listen on") - .option("--password ", "Password for basic authentication") - .action((options, folder) => { - const pagesPath = path.resolve(Deno.cwd(), folder); - const port = options.port || 3000; - - console.log("Pages folder:", pagesPath); - - const httpServer = new HttpServer({ - port: port, - pagesPath: pagesPath, - assetBundle: new AssetBundle(assetBundle as AssetJson), - password: options.password, - }); - httpServer.start().catch((e) => { - console.error(e); - }); - }) - // Upgrade command - .command("upgrade", "Upgrade Silver Bullet") - .action(async () => { - console.log("Attempting upgrade..."); - const p = Deno.run({ - cmd: ["deno", "cache", "--reload", Deno.mainModule], - }); - const exitCode = await p.status(); - if (exitCode.success) { - console.log("Upgrade succeeded"); - } else { - console.error("Upgrade failed"); - } - }) - .parse(Deno.args); diff --git a/server/util.ts b/server/util.ts deleted file mode 100644 index 55b0a08..0000000 --- a/server/util.ts +++ /dev/null @@ -1,5 +0,0 @@ -export function safeRun(fn: () => Promise) { - fn().catch((e) => { - console.error(e); - }); -} diff --git a/silverbullet.ts b/silverbullet.ts new file mode 100755 index 0000000..a427225 --- /dev/null +++ b/silverbullet.ts @@ -0,0 +1,30 @@ +import { Command } from "https://deno.land/x/cliffy@v0.25.2/command/command.ts"; + +import { version } from "./version.ts"; + +import { upgradeCommand } from "./cmd/upgrade.ts"; +import { versionCommand } from "./cmd/version.ts"; +import { fixCommand } from "./cmd/fix.ts"; +import { serveCommand } from "./cmd/server.ts"; + +await new Command() + .name("silverbullet") + .description("Markdown as a platform") + .version(version) + .help({ + colors: false, + }) + .usage(" | (see below)") + // Main command + .arguments("") + .option("-p, --port ", "Port to listen on") + .option("--password ", "Password for basic authentication") + .action(serveCommand) + .command("fix", "Fix a broken space") + .arguments("") + .action(fixCommand) + .command("upgrade", "Upgrade Silver Bullet") + .action(upgradeCommand) + .command("version", "Get current version") + .action(versionCommand) + .parse(Deno.args); diff --git a/version.ts b/version.ts new file mode 100644 index 0000000..fb9b29d --- /dev/null +++ b/version.ts @@ -0,0 +1 @@ +export const version = "0.1.13";