Update build script for relative paths everywhere
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Cadence Ember 2020-10-20 23:25:04 +13:00
parent 9c7497406b
commit 4855b2c6a0
Signed by: cadence
GPG key ID: BC1C2C61CF521B17
27 changed files with 122 additions and 91 deletions

View file

@ -18,6 +18,7 @@ const validationQueue = []
const validationHost = os.hostname() === "future" ? "http://localhost:8888/" : "http://validator.w3.org/nu/" const validationHost = os.hostname() === "future" ? "http://localhost:8888/" : "http://validator.w3.org/nu/"
const static = new Map() const static = new Map()
const links = new Map() const links = new Map()
const sources = new Map()
const pugLocals = {static, links} const pugLocals = {static, links}
const spec = require("./spec.js") const spec = require("./spec.js")
@ -26,6 +27,14 @@ function hash(buffer) {
return crypto.createHash("sha256").update(buffer).digest("hex").slice(0, 10) return crypto.createHash("sha256").update(buffer).digest("hex").slice(0, 10)
} }
function getRelative(targetPath, staticTarget) {
const pathLayer = (path.dirname(targetPath).replace(/\/$/, "").match(/\//g) || []).length
const prefix = Array(pathLayer).fill("../").join("")
const result = prefix + staticTarget.replace(/^\//, "")
if (result) return result
else return "./"
}
function validate(filename, body, type) { function validate(filename, body, type) {
const promise = fetch(validationHost+"?out=json", { const promise = fetch(validationHost+"?out=json", {
method: "POST", method: "POST",
@ -82,7 +91,7 @@ function runHint(filename, source) {
undef: true, undef: true,
// unused: true, // unused: true,
loopfunc: true, loopfunc: true,
globals: ["console", "URLSearchParams"], globals: ["console", "URLSearchParams", "staticFiles"],
browser: true, browser: true,
asi: true, asi: true,
}) })
@ -121,11 +130,21 @@ async function addFile(sourcePath, targetPath) {
fs.writeFile(pj(buildDir, targetPath), contents) fs.writeFile(pj(buildDir, targetPath), contents)
} }
async function loadJS(sourcePath, targetPath) {
let content = await fs.readFile(pj(".", sourcePath), {encoding: "utf8"})
sources.set(sourcePath, content)
static.set(sourcePath, `${targetPath}?static=${hash(content)}`)
}
async function addJS(sourcePath, targetPath) { async function addJS(sourcePath, targetPath) {
const source = await fs.readFile(pj(".", sourcePath), {encoding: "utf8"}) let content = sources.get(sourcePath)
static.set(sourcePath, `${targetPath}?static=${hash(source)}`) // resolve imports to hashed paths
runHint(sourcePath, source); content = content.replace(/\$to_relative "([^"]+)"/g, function(_, file) {
fs.writeFile(pj(buildDir, targetPath), source) if (!static.get(file)) throw new Error(`Tried to relative import ${file} from ${sourcePath}, but import not found`)
return '"' + getRelative(targetPath, static.get(file)) + '"'
})
runHint(sourcePath, content)
fs.writeFile(pj(buildDir, targetPath), content)
} }
async function addSass(sourcePath, targetPath) { async function addSass(sourcePath, targetPath) {
@ -154,21 +173,17 @@ async function addSass(sourcePath, targetPath) {
} }
async function addPug(sourcePath, targetPath) { async function addPug(sourcePath, targetPath) {
function getRelative(staticTarget) { function getRelativeHere(staticTarget) {
const pathLayer = (path.dirname(targetPath).replace(/\/$/, "").match(/\//g) || []).length return getRelative(targetPath, staticTarget)
const prefix = Array(pathLayer).fill("../").join("")
const result = prefix + staticTarget.replace(/^\//, "")
if (result) return result
else return "./"
} }
function getStatic(target) { function getStatic(target) {
return getRelative(static.get(target)) return getRelativeHere(static.get(target))
} }
function getStaticName(target) { function getStaticName(target) {
return getRelative(static.get(target)).replace(/\?.*$/, "") return getRelativeHere(static.get(target)).replace(/\?.*$/, "")
} }
function getLink(target) { function getLink(target) {
return getRelative(links.get(target)) return getRelativeHere(links.get(target))
} }
const renderedHTML = pug.compileFile(pj(".", sourcePath), {pretty: true})({getStatic, getStaticName, getLink, ...pugLocals}) const renderedHTML = pug.compileFile(pj(".", sourcePath), {pretty: true})({getStatic, getStaticName, getLink, ...pugLocals})
let renderedWithoutPHP = renderedHTML.replace(/<\?(?:php|=).*?\?>/gsm, "") let renderedWithoutPHP = renderedHTML.replace(/<\?(?:php|=).*?\?>/gsm, "")
@ -217,10 +232,18 @@ async function addBabel(sourcePath, targetPath) {
} }
} }
// Stage 2: Load JS
await Promise.all(spec.filter(item => {
return item.type === "js"
}).map(item => {
return loadJS(item.source, item.target)
}))
// Stage 3: Create dirs
const dirs = [...new Set(spec.map(item => path.dirname(item.target))).values()] const dirs = [...new Set(spec.map(item => path.dirname(item.target))).values()]
await Promise.all(dirs.map(d => fs.mkdir(pj(buildDir, d), {recursive: true}))) await Promise.all(dirs.map(d => fs.mkdir(pj(buildDir, d), {recursive: true})))
// Stage 2: Build // Stage 4: Build
for (const item of spec) { for (const item of spec) {
if (item.type === "file") { if (item.type === "file") {
await addFile(item.source, item.target) await addFile(item.source, item.target)

View file

@ -2,12 +2,15 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<!-- var static = !{JSON.stringify([...static.entries()].reduce((a, c) => (a[c[0]] = getRelative(c[1]), a), {}))}-->
<script>var staticFiles = new Map([["/js/basic.js","static/basic.js?static=4212436742"],["/js/groups.js","static/groups.js?static=551ad1c247"],["/js/chat-input.js","static/chat-input.js?static=556a7b79a3"],["/js/room-picker.js","static/room-picker.js?static=d5e34a8051"],["/js/store/store.js","static/store/store.js?static=ce3066287b"],["/js/store/Subscribable.js","static/store/Subscribable.js?static=19b7e44aa6"],["/js/store/SubscribeValue.js","static/store/SubscribeValue.js?static=215b6a5099"],["/js/store/SubscribeMapList.js","static/store/SubscribeMapList.js?static=b2732c5460"],["/js/store/SubscribeSet.js","static/store/SubscribeSet.js?static=39a1c0a2a4"],["/js/sync/sync.js","static/sync/sync.js?static=fc5795a5b8"],["/js/lsm.js","static/lsm.js?static=aed2c7ca35"],["/js/Timeline.js","static/Timeline.js?static=1393b78916"],["/js/Anchor.js","static/Anchor.js?static=85efd1a836"],["/js/chat.js","static/chat.js?static=b01b3716ff"],["/js/functions.js","static/functions.js?static=e3784c70ce"],["/assets/fonts/whitney-500.woff","static/whitney-500.woff?static=ba33ed18fe"],["/assets/fonts/whitney-400.woff","static/whitney-400.woff?static=0f823bc4b5"],["/assets/icons/directs.svg","static/directs.svg?static=2555ccd447"],["/assets/icons/channels.svg","static/channels.svg?static=8389f20610"],["/assets/icons/join-event.svg","static/join-event.svg?static=761c23a0ef"],["/sass/main.sass","static/main.css?static=e9db1a3439"]])
</script>
<link rel="stylesheet" type="text/css" href="static/main.css?static=e9db1a3439"> <link rel="stylesheet" type="text/css" href="static/main.css?static=e9db1a3439">
<script type="module" src="static/groups.js?static=2cc7f0daf8"></script> <script type="module" src="static/groups.js?static=551ad1c247"></script>
<script type="module" src="static/chat-input.js?static=16321d4eb4"></script> <script type="module" src="static/chat-input.js?static=556a7b79a3"></script>
<script type="module" src="static/room-picker.js?static=edb9a5f669"></script> <script type="module" src="static/room-picker.js?static=d5e34a8051"></script>
<script type="module" src="static/sync/sync.js?static=b817c21dbe"></script> <script type="module" src="static/sync/sync.js?static=fc5795a5b8"></script>
<script type="module" src="static/chat.js?static=fc121d3d23"></script> <script type="module" src="static/chat.js?static=b01b3716ff"></script>
<title>Carbon</title> <title>Carbon</title>
</head> </head>
<body> <body>

View file

@ -1,4 +1,4 @@
import {ElemJS} from "./basic.js" import {ElemJS} from "../static/basic.js?static=4212436742"
class Anchor extends ElemJS { class Anchor extends ElemJS {
constructor() { constructor() {

View file

@ -1,9 +1,9 @@
import {ElemJS, ejs} from "./basic.js" import {ElemJS, ejs} from "../static/basic.js?static=4212436742"
import {Subscribable} from "./store/Subscribable.js" import {Subscribable} from "../static/store/Subscribable.js?static=19b7e44aa6"
import {store} from "./store/store.js" import {store} from "../static/store/store.js?static=ce3066287b"
import {Anchor} from "./Anchor.js" import {Anchor} from "../static/Anchor.js?static=85efd1a836"
import * as lsm from "./lsm.js" import * as lsm from "../static/lsm.js?static=aed2c7ca35"
import {resolveMxc} from "./functions.js" import {resolveMxc} from "../static/functions.js?static=e3784c70ce"
const dateFormatter = Intl.DateTimeFormat("default", {hour: "numeric", minute: "numeric", day: "numeric", month: "short", year: "numeric"}) const dateFormatter = Intl.DateTimeFormat("default", {hour: "numeric", minute: "numeric", day: "numeric", month: "short", year: "numeric"})

View file

@ -1,7 +1,7 @@
import {q} from "./basic.js" import {q} from "../static/basic.js?static=4212436742"
import {store} from "./store/store.js" import {store} from "../static/store/store.js?static=ce3066287b"
import * as lsm from "./lsm.js" import * as lsm from "../static/lsm.js?static=aed2c7ca35"
import {chat} from "./chat.js" import {chat} from "../static/chat.js?static=b01b3716ff"
const input = q("#c-chat-textarea") const input = q("#c-chat-textarea")

View file

@ -1,5 +1,5 @@
import {ElemJS, q, ejs} from "./basic.js" import {ElemJS, q, ejs} from "../static/basic.js?static=4212436742"
import {store} from "./store/store.js" import {store} from "../static/store/store.js?static=ce3066287b"
const chatMessages = q("#c-chat-messages") const chatMessages = q("#c-chat-messages")

View file

@ -1,4 +1,4 @@
import {q} from "./basic.js" import {q} from "../static/basic.js?static=4212436742"
let state = "CLOSED" let state = "CLOSED"

View file

@ -1,10 +1,10 @@
import {q, ElemJS, ejs} from "./basic.js" import {q, ElemJS, ejs} from "../static/basic.js?static=4212436742"
import {store} from "./store/store.js" import {store} from "../static/store/store.js?static=ce3066287b"
import {SubscribeMapList} from "./store/SubscribeMapList.js" import {SubscribeMapList} from "../static/store/SubscribeMapList.js?static=b2732c5460"
import {SubscribeValue} from "./store/SubscribeValue.js" import {SubscribeValue} from "../static/store/SubscribeValue.js?static=215b6a5099"
import {Timeline} from "./Timeline.js" import {Timeline} from "../static/Timeline.js?static=1393b78916"
import * as lsm from "./lsm.js" import * as lsm from "../static/lsm.js?static=aed2c7ca35"
import {resolveMxc} from "./functions.js" import {resolveMxc} from "../static/functions.js?static=e3784c70ce"
class ActiveGroupMarker extends ElemJS { class ActiveGroupMarker extends ElemJS {
constructor() { constructor() {

View file

@ -1,5 +1,5 @@
import {Subscribable} from "./Subscribable.js" import {Subscribable} from "../../static/store/Subscribable.js?static=19b7e44aa6"
import {SubscribeValue} from "./SubscribeValue.js" import {SubscribeValue} from "../../static/store/SubscribeValue.js?static=215b6a5099"
class SubscribeMapList extends Subscribable { class SubscribeMapList extends Subscribable {
constructor(inner) { constructor(inner) {

View file

@ -1,4 +1,4 @@
import {Subscribable} from "./Subscribable.js" import {Subscribable} from "../../static/store/Subscribable.js?static=19b7e44aa6"
class SubscribeSet extends Subscribable { class SubscribeSet extends Subscribable {
constructor() { constructor() {

View file

@ -1,4 +1,4 @@
import {Subscribable} from "./Subscribable.js" import {Subscribable} from "../../static/store/Subscribable.js?static=19b7e44aa6"
class SubscribeValue extends Subscribable { class SubscribeValue extends Subscribable {
constructor() { constructor() {

View file

@ -1,7 +1,7 @@
import {Subscribable} from "./Subscribable.js" import {Subscribable} from "../../static/store/Subscribable.js?static=19b7e44aa6"
import {SubscribeMapList} from "./SubscribeMapList.js" import {SubscribeMapList} from "../../static/store/SubscribeMapList.js?static=b2732c5460"
import {SubscribeSet} from "./SubscribeSet.js" import {SubscribeSet} from "../../static/store/SubscribeSet.js?static=39a1c0a2a4"
import {SubscribeValue} from "./SubscribeValue.js" import {SubscribeValue} from "../../static/store/SubscribeValue.js?static=215b6a5099"
const store = { const store = {
groups: new SubscribeMapList(SubscribeValue), groups: new SubscribeMapList(SubscribeValue),

View file

@ -1,6 +1,6 @@
import {store} from "../store/store.js" import {store} from "../../static/store/store.js?static=ce3066287b"
import * as lsm from "../lsm.js" import * as lsm from "../../static/lsm.js?static=aed2c7ca35"
import {resolveMxc} from "../functions.js" import {resolveMxc} from "../../static/functions.js?static=e3784c70ce"
let lastBatch = null let lastBatch = null
@ -111,13 +111,13 @@ function syncLoop() {
{ {
id: "directs", id: "directs",
name: "Directs", name: "Directs",
icon: "/static/directs.svg", icon: staticFiles.get("/assets/icons/directs.svg"),
order: -2 order: -2
}, },
{ {
id: "channels", id: "channels",
name: "Channels", name: "Channels",
icon: "/static/channels.svg", icon: staticFiles.get("/assets/icons/channels.svg"),
order: -1 order: -1
} }
].forEach(data => store.groups.askAdd(data.id, data)) ].forEach(data => store.groups.askAdd(data.id, data))

View file

@ -33,6 +33,11 @@ doctype html
html html
head head
meta(charset="utf-8") meta(charset="utf-8")
// var static = !{JSON.stringify([...static.entries()].reduce((a, c) => (a[c[0]] = getRelative(c[1]), a), {}))}
script
| var staticFiles = new Map(
!= JSON.stringify([...static.keys()].map(k => [k, getStatic(k)]))
| )
link(rel="stylesheet" type="text/css" href=getStatic("/sass/main.sass")) link(rel="stylesheet" type="text/css" href=getStatic("/sass/main.sass"))
script(type="module" src=getStatic("/js/groups.js")) script(type="module" src=getStatic("/js/groups.js"))
script(type="module" src=getStatic("/js/chat-input.js")) script(type="module" src=getStatic("/js/chat-input.js"))

View file

@ -1,4 +1,4 @@
import {ElemJS} from "./basic.js" import {ElemJS} from $to_relative "/js/basic.js"
class Anchor extends ElemJS { class Anchor extends ElemJS {
constructor() { constructor() {

View file

@ -1,9 +1,9 @@
import {ElemJS, ejs} from "./basic.js" import {ElemJS, ejs} from $to_relative "/js/basic.js"
import {Subscribable} from "./store/Subscribable.js" import {Subscribable} from $to_relative "/js/store/Subscribable.js"
import {store} from "./store/store.js" import {store} from $to_relative "/js/store/store.js"
import {Anchor} from "./Anchor.js" import {Anchor} from $to_relative "/js/Anchor.js"
import * as lsm from "./lsm.js" import * as lsm from $to_relative "/js/lsm.js"
import {resolveMxc} from "./functions.js" import {resolveMxc} from $to_relative "/js/functions.js"
const dateFormatter = Intl.DateTimeFormat("default", {hour: "numeric", minute: "numeric", day: "numeric", month: "short", year: "numeric"}) const dateFormatter = Intl.DateTimeFormat("default", {hour: "numeric", minute: "numeric", day: "numeric", month: "short", year: "numeric"})

View file

@ -1,7 +1,7 @@
import {q} from "./basic.js" import {q} from $to_relative "/js/basic.js"
import {store} from "./store/store.js" import {store} from $to_relative "/js/store/store.js"
import * as lsm from "./lsm.js" import * as lsm from $to_relative "/js/lsm.js"
import {chat} from "./chat.js" import {chat} from $to_relative "/js/chat.js"
const input = q("#c-chat-textarea") const input = q("#c-chat-textarea")

View file

@ -1,5 +1,5 @@
import {ElemJS, q, ejs} from "./basic.js" import {ElemJS, q, ejs} from $to_relative "/js/basic.js"
import {store} from "./store/store.js" import {store} from $to_relative "/js/store/store.js"
const chatMessages = q("#c-chat-messages") const chatMessages = q("#c-chat-messages")

View file

@ -1,4 +1,4 @@
import * as lsm from "./lsm.js" import * as lsm from $to_relative "/js/lsm.js"
function resolveMxc(url, size, method) { function resolveMxc(url, size, method) {
const [server, id] = url.match(/^mxc:\/\/([^/]+)\/(.*)/).slice(1) const [server, id] = url.match(/^mxc:\/\/([^/]+)\/(.*)/).slice(1)

View file

@ -1,4 +1,4 @@
import {q} from "./basic.js" import {q} from $to_relative "/js/basic.js"
let state = "CLOSED" let state = "CLOSED"

View file

@ -1,10 +1,10 @@
import {q, ElemJS, ejs} from "./basic.js" import {q, ElemJS, ejs} from $to_relative "/js/basic.js"
import {store} from "./store/store.js" import {store} from $to_relative "/js/store/store.js"
import {SubscribeMapList} from "./store/SubscribeMapList.js" import {SubscribeMapList} from $to_relative "/js/store/SubscribeMapList.js"
import {SubscribeValue} from "./store/SubscribeValue.js" import {SubscribeValue} from $to_relative "/js/store/SubscribeValue.js"
import {Timeline} from "./Timeline.js" import {Timeline} from $to_relative "/js/Timeline.js"
import * as lsm from "./lsm.js" import * as lsm from $to_relative "/js/lsm.js"
import {resolveMxc} from "./functions.js" import {resolveMxc} from $to_relative "/js/functions.js"
class ActiveGroupMarker extends ElemJS { class ActiveGroupMarker extends ElemJS {
constructor() { constructor() {

View file

@ -1,5 +1,5 @@
import {Subscribable} from "./Subscribable.js" import {Subscribable} from $to_relative "/js/store/Subscribable.js"
import {SubscribeValue} from "./SubscribeValue.js" import {SubscribeValue} from $to_relative "/js/store/SubscribeValue.js"
class SubscribeMap extends Subscribable { class SubscribeMap extends Subscribable {
constructor() { constructor() {

View file

@ -1,5 +1,5 @@
import {Subscribable} from "./Subscribable.js" import {Subscribable} from $to_relative "/js/store/Subscribable.js"
import {SubscribeValue} from "./SubscribeValue.js" import {SubscribeValue} from $to_relative "/js/store/SubscribeValue.js"
class SubscribeMapList extends Subscribable { class SubscribeMapList extends Subscribable {
constructor(inner) { constructor(inner) {

View file

@ -1,4 +1,4 @@
import {Subscribable} from "./Subscribable.js" import {Subscribable} from $to_relative "/js/store/Subscribable.js"
class SubscribeSet extends Subscribable { class SubscribeSet extends Subscribable {
constructor() { constructor() {

View file

@ -1,4 +1,4 @@
import {Subscribable} from "./Subscribable.js" import {Subscribable} from $to_relative "/js/store/Subscribable.js"
class SubscribeValue extends Subscribable { class SubscribeValue extends Subscribable {
constructor() { constructor() {

View file

@ -1,7 +1,7 @@
import {Subscribable} from "./Subscribable.js" import {Subscribable} from $to_relative "/js/store/Subscribable.js"
import {SubscribeMapList} from "./SubscribeMapList.js" import {SubscribeMapList} from $to_relative "/js/store/SubscribeMapList.js"
import {SubscribeSet} from "./SubscribeSet.js" import {SubscribeSet} from $to_relative "/js/store/SubscribeSet.js"
import {SubscribeValue} from "./SubscribeValue.js" import {SubscribeValue} from $to_relative "/js/store/SubscribeValue.js"
const store = { const store = {
groups: new SubscribeMapList(SubscribeValue), groups: new SubscribeMapList(SubscribeValue),

View file

@ -1,6 +1,6 @@
import {store} from "../store/store.js" import {store} from $to_relative "/js/store/store.js"
import * as lsm from "../lsm.js" import * as lsm from $to_relative "/js/lsm.js"
import {resolveMxc} from "../functions.js" import {resolveMxc} from $to_relative "/js/functions.js"
let lastBatch = null let lastBatch = null
@ -111,13 +111,13 @@ function syncLoop() {
{ {
id: "directs", id: "directs",
name: "Directs", name: "Directs",
icon: "/static/directs.svg", icon: staticFiles.get("/assets/icons/directs.svg"),
order: -2 order: -2
}, },
{ {
id: "channels", id: "channels",
name: "Channels", name: "Channels",
icon: "/static/channels.svg", icon: staticFiles.get("/assets/icons/channels.svg"),
order: -1 order: -1
} }
].forEach(data => store.groups.askAdd(data.id, data)) ].forEach(data => store.groups.askAdd(data.id, data))