Skip to content

Commit

Permalink
mvb binary
Browse files Browse the repository at this point in the history
  • Loading branch information
pirog committed Sep 30, 2024
1 parent 9688a09 commit 46b54c2
Show file tree
Hide file tree
Showing 9 changed files with 251 additions and 169 deletions.
34 changes: 18 additions & 16 deletions .lando.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
name: vitepress-theme-default-plus
proxy:
cli:
- vitepress-theme-default-plus.lndo.site:5173
services:
node:
type: node:18
build:
- npm install
cli:
api: 4
image: node:18
command: sleep infinity
ports:
- 5173:5173/http
scanner: false
ssl: false
sslExpose: false
overrides:
ports:
- 8071:8071
user: node
build:
app: |
npm install
tooling:
node:
service: node
service: cli
npm:
service: node
dev:
service: node
cmd: npm run dev --port 8071
env:
DEBUG: "@lando/*"
service: cli
vitepress:
service: cli
cmd: npx vitepress
174 changes: 174 additions & 0 deletions bin/mvb.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
#!/usr/bin/env node
import path from 'node:path';
import {tmpdir} from 'node:os';

import fs from 'fs-extra';
import parser from 'yargs-parser';
import {bold, dim, green} from 'colorette';
import {nanoid} from 'nanoid';
import {resolveConfig} from 'vitepress';

import {default as getStdOut} from '../utils/parse-stdout.js';
import {default as getTags} from '../utils/get-tags.js';
import {default as traverseUp} from '../utils/traverse-up.js';

import Debug from 'debug';

// debugger
const debug = Debug('@lando/mvb'); // eslint-disable-line

// enable debug if applicable
if (process.argv.includes('--debug')) Debug.enable(process.env.DEBUG ?? '*');

// lets start by getting argv
const argv = parser(process.argv.slice(2));
debug('received argv %o', argv);

// source dir
const srcDir = argv._[0] ?? 'docs';
// orginal absolute path to source
const osource = path.resolve(process.cwd(), srcDir);
// help
const help = argv.h || argv.help;

// get site config
// @TODO: if no site then throw error? how do we determine that?
const siteConfig = await resolveConfig(osource, 'build', 'production');
const {site} = siteConfig;

// build default options
const defaults = {
base: site?.base ?? '/',
build: site?.themeConfig?.multiVersionBuild?.build ?? 'stable',
match: site?.themeConfig?.multiVersionBuild?.match ?? 'v[0-9].*',
outDir: path.relative(process.cwd(), siteConfig.outDir) ?? './.vitepress/dist',
satisfies: site?.themeConfig?.multiVersionBuild?.satisfies ?? '*',
versionBase: site?.themeConfig?.multiVersionBuild?.base ?? '/v/',
};
debug('default options %o', defaults);

// show help/usage if requested
if (help) {
console.log(`
Usage: ${dim('[CI=1]')} ${bold(`${path.basename(process.argv[1])} <root>`)} ${dim('[--base <base>] [--build <alias>] [--match "<match>"] [--out-dir <dir>] [--satisifes "<satisfies>"] [--version-base <dir>] [--debug] [--help]')}
${green('Options')}:
--base sets site base ${dim(`[default: ${defaults.base}`)}]
--build uses this version alias for main/root build ${dim(`[default: ${defaults.build}`)}]
--match filters versions from git tags ${dim(`[default: "${defaults.match}"`)}]
--out-dir builds into this location ${dim(`[default: ${defaults.outDir}`)}]
--satisfies builds versioned docs in this semantic range ${dim(`[default: "${defaults.satisfies}"`)}]
--version-base builds versioned docs in this location ${dim(`[default: ${defaults.versionBase}`)}]
--debug shows debug messages
-h, --help displays this message
${green('Environment Variables')}:
CI installs in CI mode (e.g. does not prompt for user input)
`);
}

// resolve options with argv input
// @TODO: /tmp location option?
const options = {...defaults, ...argv, tmpDir: path.resolve(tmpdir(), nanoid())};
debug('multiversion build from %o using resolved build options: %O', srcDir, options);


// @TODO: rework logic to use new options?
// @TODO: helpers
// exec factory osourceExec tmpExec
// for package.json dumping?
// @TODO: remove dev release from sidebar ender?

// @TODO: clean versions in path? eg /v/1.0.0 instead of /v/v1.0.0/
// @TODO: replace explicit build with optiins spreader
// @TODO: remove defaults once we have arg handling
// @TODO: wrap whole thing in try?
// @TODO: separate exec func with try?
// @TODO: better cli message?

// build a helper for running commands in tmp
const exec = (command, options = {}) => {
// combine options
options = {cwd: tmpDir, stdio: 'inherit', ...options};
// debug
debug('running %o with %o', command, options);
// exec
return getStdOut(command, options);
};

// determine gitdir
// @TODO: throw error if no git dir?
const gitDir = traverseUp(['.git'], osource).find(dir => fs.existsSync(dir));
debug('determined git-dir: %o', gitDir);

// destructure some helpful options
const {outDir, tmpDir} = options;

// do the initial setup
fs.removeSync(tmpDir, {force: true, maxRetries: 10, recursive: true});
fs.mkdirSync(tmpDir, {recursive: true});

// update all osource
exec('git fetch origin --tags', {cwd: osource});
// switch cwd to tmpdir and clone from osource
process.chdir(tmpDir);
// and clone from osource
exec(`git clone ${gitDir} ./`);

// get extended version information
const {extended} = await getTags(gitDir, options);
debug('determined versions to build: %o', extended);

// set up base build and unshift into extended
// @TODO: throw error if empty?
extended.unshift(extended.find(version => version.alias === options.build));
debug('determined main/root build is %o %o', options.build, extended[0]);

// now loop through extended and construct the build metadata
const builds = extended.map((version, index) => {
// add base and outdir but remember index === 0 is special
if (index === 0) {
version.base = site.base;
version.outDir = outDir;
} else {
version.base = path.resolve(`/${site.base}/${options.versionBase}/${version.alias ?? version.version}`) + '/';
version.outDir = path.join(outDir, options.versionBase, version.alias ?? version.version);
}

return {...version, srcDir};
});

// and now build them all
for (const build of builds) {
// separate out our stuff
const {alias, ref, semantic, srcDir, version, ...config} = build;
debug('building %o version %o from %o with config %o', srcDir, `${alias ?? version}@${ref}`, config);

// reset HEAD HARD
exec('git reset HEAD --hard');
// checkout new ref
exec(`git checkout ${ref}`);
// reinstall
exec('npm clean-install');

// update package.json if needed
const pjsonPath = path.join(tmpDir, 'package.json');
const pjson = JSON.parse(fs.readFileSync(pjsonPath, {encoding: 'utf8'}));
if (pjson.version !== semantic) {
// update version
pjson.version = semantic;
// rewrite
fs.writeFileSync(pjsonPath, JSON.stringify(pjson, null, 2));
// log
debug('updated %o version to %o', pjsonPath, semantic);
}

// build the version
exec(`npx vitepress build ${srcDir} --outDir ${config.outDir} --base ${config.base}`);
}

// clean original
fs.removeSync(siteConfig.outDir, {force: true, maxRetries: 10, recursive: true});
// move tmp to original
fs.moveSync(path.resolve(tmpDir, outDir), siteConfig.outDir);
131 changes: 0 additions & 131 deletions bin/vitepress-mvb.js

This file was deleted.

4 changes: 2 additions & 2 deletions client/use-tags.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import {useData} from 'vitepress';
export default function useTags() {
// get version path data
const {theme} = useData();
const vp = theme?.value?.multiVersionBuild?.path ?? '/v/';
const base = theme?.value?.multiVersionBuild?.base ?? '/v/';

// generate links we can pass into VPLVersionLink
const links = tags.versions
.map(version => ({
text: version,
href: `${vp}${version}/`,
href: path.resolve(`/${base}/${version}`) + '/',
prerelease: /^v?\d+\.\d+\.\d+-\S+$/.test(version),
stable: tags?.aliases?.stable === version,
edge: tags?.aliases?.edge === version,
Expand Down
7 changes: 3 additions & 4 deletions docs/.vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,10 @@ export default defineConfig({
},
logo: {src: '/images/vitepress-lando-logo-icon.png', width: 24, height: 24},
multiVersionBuild: {
rootBuild: 'stable',
build: 'dev',
match: 'v[0-9].*',
path: '/v/',
satisfies: '>1.0.0-beta.40',
base: '/v/',
satisfies: '>=1.0.0-beta.42',
},
tags: {
'obscure': {
Expand Down Expand Up @@ -250,7 +250,6 @@ export default defineConfig({
items: [
{text: 'stable', target: '_blank', link: '/v/stable/'},
{text: 'edge', target: '_blank', link: '/v/edge/'},
{text: 'dev', target: '_blank', link: '/v/dev/'},
{text: '<strong>see all versions</strong>', link: '/v/'},
],
},
Expand Down
Loading

0 comments on commit 46b54c2

Please sign in to comment.