Skip to content

Commit

Permalink
Add media garbage collection
Browse files Browse the repository at this point in the history
  • Loading branch information
leebyron committed Jul 24, 2023
1 parent 9962b42 commit 48c6e47
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 28 deletions.
1 change: 0 additions & 1 deletion media/d952123032e51b0f.svg

This file was deleted.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
"build": "./bin/til --build",
"install": "mkdir -p \"$HOME/.local/bin\"; ln -sf \"$PWD/bin/til\" \"$HOME/.local/bin/til\""
},
"prettier": {
"semi": false
},
"dependencies": {
"context-eval": "^0.1.0",
"hyperjsx": "^1.0.12",
Expand Down
80 changes: 54 additions & 26 deletions src/til.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
exec,
fileExists,
spin,
confirm,
} from './util.mjs'

export default async function til(args) {
Expand All @@ -38,7 +39,8 @@ Other commands:
\x1B[1mtil --help\x1B[0m this lovely message right here
\x1B[1mtil --build\x1B[0m builds all documents to HTML files for distribution
\x1B[1mtil --sync\x1B[0m ensures the local environment has all known changes
\x1B[1mtil --sync\x1B[0m ensures the local environment has all known changes
\x1B[1mtil --gc\x1B[0m removes unused files
Examples:
Expand Down Expand Up @@ -70,6 +72,11 @@ open all in fzf.`)
case '--sync':
await syncRepo()
return

case 'gc':
case '--gc':
await garbageCollect()
return
}

// Almost certainly a mistake
Expand Down Expand Up @@ -100,7 +107,7 @@ open all in fzf.`)
const title = args.join(' ')

// Make sure the repo is up to date before making any changes.
await syncRepo()
// await syncRepo()

// Either coerce the promptname to a filename, or show a fzf.
let filename = title
Expand Down Expand Up @@ -180,30 +187,7 @@ open all in fzf.`)
await exec(`mkdir -p ${ENTRIES_PATH}`)

// Get all existing tags
const allTags = await spin(
'Tagging',
async () =>
new Set(
(
await Promise.all(
(
await fs.readdir(ENTRIES_PATH)
).map(async filename =>
yamlTags(
yaml.parse(
(
await fs.readFile(
path.resolve(ENTRIES_PATH, filename),
'utf8'
)
).match(/---\n(.+?)\n---\n/s)?.[1] || ''
)?.tags
)
)
)
).flat()
)
)
const allTags = await spin('Tagging', getAllTags)

// Write a template to a tmp file and fill it into the editor buffer.
// This way you can quit without saving and not alter the repo state.
Expand Down Expand Up @@ -258,6 +242,9 @@ open all in fzf.`)
break
}

// Clean up any unreferenced files
await garbageCollect()

// Update the repo
await spin('Publish', async () => {
// Ensure the file is named correctly after editing
Expand Down Expand Up @@ -358,6 +345,47 @@ async function syncRepo() {
})
}

async function garbageCollect() {
const mediaRefs = new Set(
(await getAllEntries()).flatMap(({ contents }) =>
contents.match(/[0-9a-f]{8,32}\.[a-z]+/g) || []
)
)

const medias = new Set(await fs.readdir(MEDIA_PATH))

// Remove all medias which have a reference leaving only unreferenced media
// to remain.
for (const ref of mediaRefs) {
medias.delete(ref)
}

for (const filename of medias) {
if (await confirm(`Remove unused media ${filename}?`)) {
await fs.unlink(path.resolve(MEDIA_PATH, filename))
}
}
}

async function getAllEntries() {
return await Promise.all(
(await fs.readdir(ENTRIES_PATH)).map(async filename => ({
filename,
contents: await fs.readFile(path.resolve(ENTRIES_PATH, filename), 'utf8')
}))
)
}

async function getAllTags() {
return new Set(
(await getAllEntries()).flatMap(({ contents }) =>
yamlTags(
yaml.parse(contents.match(/---\n(.+?)\n---\n/s)?.[1] || '')?.tags
)
)
)
}

function sanitizeFilename(name) {
return name
.toLowerCase()
Expand Down
14 changes: 13 additions & 1 deletion src/util.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as child_process from 'child_process'
import * as fs from 'fs/promises'
import * as path from 'path'
import * as readline from 'readline/promises'
import * as url from 'url'
import * as util from 'util'
import { DateTime } from 'luxon'
Expand Down Expand Up @@ -52,7 +53,7 @@ export const fileExists = exists(stats => stats.isFile())
export const directoryExists = exists(stats => stats.isDirectory())

// Show a spinner while running an async `doing` function.
export const spin = async (name, doing) => {
export async function spin(name, doing) {
if (!doing) [name, doing] = [doing, name]
let frame = 0
const SPINNER = [
Expand Down Expand Up @@ -82,6 +83,17 @@ export const spin = async (name, doing) => {
}
}

// Ask for confirmation before continuing
export async function confirm(query) {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
})
const response = (await rl.question(query + ' (Y/n): ')).trim().toLowerCase()
rl.close()
return response === 'y' || response === ''
}

function handleInterrupt(event, code) {
process.exit(code)
}
Expand Down

0 comments on commit 48c6e47

Please sign in to comment.