mirror of
https://github.com/status-im/sourcecred.git
synced 2025-02-21 08:48:14 +00:00
cli: add site
subcommand (#1905)
Summary: The `sourcecred site` command now sets up a static site for a cred instance, which may be deployed to (e.g.) GitHub Pages or IPFS. This implementation sets up a directory structure where the site is contained in a `site/` subdirectory whose top-level entries are also symbolically linked from the root of the instance. Thus: ``` my-instance/ sourcecred.json config/ output/ site/ index.html favicon.png static/ static/js/... index.html -> site/index.html favicon.png -> site/favicon.png static -> site/static ``` The purpose of this is to enable the instance to be served directly as a GitHub Pages site without the user having to navigate to a URL that includes a `site/` path component. It’s not a perfect solution. The top level of the instance is cluttered. If we have any web pages other than the root directory, then they’ll appear at top level, too. If we change the structure, we’ll need to teach `sourcecred site` to clean up vestiges of old structures. We also won’t be able to have any pages called `config` or `output` or `cache` due to namespace collision. But we think that it’s at least a reasonable stopgap, and doesn’t incur much conceptual overhead. This isn’t tested or officially supported on Windows. Paired with @decentralion. Test Plan: Run `yarn build` to build the frontend and backend, then `cd` into a SourceCred instance and run `node "${OLDPWD}/bin/sourcecred.js site`. Note that a `site/` directory is created, and when the static site is served it works from either `site/` or the instance root. Note that this all works when actually deployed to GitHub Pages as well. wchargin-branch: cli-site
This commit is contained in:
parent
a30c45bc05
commit
7ab3a74c3a
@ -16,6 +16,6 @@ ENV SOURCECRED_DIRECTORY ${SOURCECRED_DEFAULT_DIRECTORY}
|
||||
|
||||
# Install the remainder of our code.
|
||||
COPY . /code
|
||||
RUN yarn build:backend
|
||||
RUN yarn build
|
||||
|
||||
ENTRYPOINT ["/bin/bash", "/code/scripts/docker-entrypoint.sh"]
|
||||
|
@ -94,7 +94,7 @@
|
||||
"prettify": "prettier --write '**/*.js'",
|
||||
"check-pretty": "prettier --list-different '**/*.js'",
|
||||
"start": "NODE_ENV=development webpack-dev-server --config config/webpack.config.web.js",
|
||||
"build": "run-p build:*",
|
||||
"build": "run-p build:* && ln -sf ../build ./bin/site-template",
|
||||
"build:frontend": "NODE_ENV=production webpack --config config/webpack.config.web.js",
|
||||
"build:backend": "NODE_ENV=development webpack --config config/webpack.config.backend.js",
|
||||
"api": "webpack --config config/webpack.config.api.js",
|
||||
|
42
src/cli/site.js
Normal file
42
src/cli/site.js
Normal file
@ -0,0 +1,42 @@
|
||||
// @flow
|
||||
|
||||
import fs from "fs-extra";
|
||||
|
||||
import type {Command} from "./command";
|
||||
import {join as pathJoin} from "path";
|
||||
|
||||
const SITE_TEMPLATE_DIR = "site-template";
|
||||
const SITE_OUTPUT = "site"; // under instance dir
|
||||
const SITE_SYMLINKS = ["index.html", "favicon.png", "static"];
|
||||
|
||||
function die(std, message) {
|
||||
std.err("fatal: " + message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const siteCommand: Command = async (args, std) => {
|
||||
if (args.length !== 0) {
|
||||
return die(std, "usage: sourcecred site");
|
||||
}
|
||||
const siteTemplate = pathJoin(__dirname, SITE_TEMPLATE_DIR);
|
||||
await fs.copy(siteTemplate, SITE_OUTPUT, {dereference: true});
|
||||
for (const symlink of SITE_SYMLINKS) {
|
||||
await lnsf(pathJoin(SITE_OUTPUT, symlink), symlink);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
// Create a symlink, overwriting if it exists, like `ln -sf`.
|
||||
async function lnsf(src: string, dst: string): Promise<void> {
|
||||
try {
|
||||
await fs.symlink(src, dst);
|
||||
} catch (e) {
|
||||
if (e.code !== "EEXIST") {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
await fs.unlink(dst);
|
||||
await fs.symlink(src, dst);
|
||||
}
|
||||
|
||||
export default siteCommand;
|
@ -6,6 +6,7 @@ import {VERSION_SHORT} from "../core/version";
|
||||
import load from "./load";
|
||||
import graph from "./graph";
|
||||
import score from "./score";
|
||||
import site from "./site";
|
||||
import help from "./help";
|
||||
|
||||
const sourcecred: Command = async (args, std) => {
|
||||
@ -26,6 +27,8 @@ const sourcecred: Command = async (args, std) => {
|
||||
return graph(args.slice(1), std);
|
||||
case "score":
|
||||
return score(args.slice(1), std);
|
||||
case "site":
|
||||
return site(args.slice(1), std);
|
||||
default:
|
||||
std.err("fatal: unknown command: " + JSON.stringify(args[0]));
|
||||
std.err("fatal: run 'sourcecred help' for commands and usage");
|
||||
|
Loading…
x
Reference in New Issue
Block a user