tools/lib.ts (90 lines of code) (raw):

import * as path from "https://deno.land/std/path/mod.ts"; import { exists } from "https://deno.land/std/fs/mod.ts"; const BASE_CONTESTS_DIR = "contests"; const TEMPLATE_FILE_NAME = "problem_template.rs"; const CARGO_TOML_PATH = `${BASE_CONTESTS_DIR}/Cargo.toml`; export type ContestProperty = { contestName: string; taskName: string; }; export const getContestProperty = (url: URL): ContestProperty => { if (url.host !== "atcoder.jp") { throw new URIError(`invalid host, correct "atcoder.jp": ${url.host}`); } const re = new RegExp(`\/contests\/(\\S+)\/tasks\/(\\S+)`); if (!re.test(url.pathname)) { throw new URIError( `invalid path, correct "${re.source}": ${url.pathname}`, ); } const matchGroups = url.pathname.match(re); if (matchGroups === null) { throw new URIError("unknown error"); } const contestProperty = { contestName: matchGroups[1].toString(), taskName: matchGroups[2].toString(), }; // console.debug(`DEBUG: ${JSON.stringify({contestProperty}, null, 2)}`) return contestProperty; }; export const createTemplateFile = async ( url: URL, contestProperty: ContestProperty, ) => { const workingDir = path.join( Deno.cwd(), `${BASE_CONTESTS_DIR}/${contestProperty.contestName}`, ); // console.debug(`DEBUG: ${JSON.stringify({workingDir}, null, 2)}`) try { await Deno.mkdir(workingDir); console.info(`INFO: create "${workingDir}"`); } catch (err) { if (err.name === "AlreadyExists") { console.info(`INFO: "${workingDir}" is already exists.`); } else { throw err; } } const fromPath = path.join(Deno.cwd(), TEMPLATE_FILE_NAME); const toPath = path.join(workingDir, `${contestProperty.taskName}.rs`); if (await exists(toPath)) { console.info(`INFO: "${toPath}" is already exists.`); return; } await Deno.copyFile(fromPath, toPath); const encoder = new TextEncoder(); const encodedComment = encoder.encode(` // ${url.toString()} `); await Deno.writeFile( toPath, encodedComment, { append: true }, ); console.info(`INFO: create "${toPath}"`); }; export const settingProblemBin = async (contestProperty: ContestProperty) => { const tomlPath = path.join(Deno.cwd(), CARGO_TOML_PATH); const settingString = ` [[bin]] name="${contestProperty.contestName}_${contestProperty.taskName}" path = "${contestProperty.contestName}/${contestProperty.taskName}.rs" `; const tomlFile = await Deno.readTextFile(tomlPath); if ( tomlFile.match( `${contestProperty.contestName}_${contestProperty.taskName}`, ) !== null ) { console.info(`INFO: already settings to Cargo.toml.`); return; } const encoder = new TextEncoder(); const encodedSettingString = encoder.encode(settingString); await Deno.writeFile( tomlPath, encodedSettingString, { append: true }, ); console.info(`INFO: setting to Cargo.toml.`); };