More commands

This commit is contained in:
Daniel Kluge 2021-12-17 20:02:42 +01:00
parent a24692e3ed
commit 9ea06a16fe
6 changed files with 92 additions and 21 deletions

View File

@ -2,6 +2,7 @@
"extends": "next/core-web-vitals", "extends": "next/core-web-vitals",
"rules": { "rules": {
"semi": ["warn", "always"], "semi": ["warn", "always"],
"quotes": ["warn", "double"] "quotes": ["warn", "double"],
"eqeqeq": "error"
} }
} }

View File

@ -1,4 +1,6 @@
import type { Command, Flag } from "./types"; import type { Command, Flag } from "./types";
import type { Project } from "../projects/types";
import projectList from "../projects";
function getCommandByName(name: string): Command|undefined { function getCommandByName(name: string): Command|undefined {
return commandList.find(cmd => cmd.name === name); return commandList.find(cmd => cmd.name === name);
@ -18,7 +20,7 @@ function checkFlags(flags: string[], cmd: Command): boolean {
for (const flag of flags) { for (const flag of flags) {
const isLong = flag.substring(0,2) === "--"; const isLong = flag.substring(0,2) === "--";
const flagObj = cmd.flags.find(f => isLong ? f.long === flag.substring(2) : f.short === flag.substring(1)); const flagObj = Object.values(cmd.flags).find(f => isLong ? f.long === flag.substring(2) : f.short === flag.substring(1));
if (!flagObj) return false; if (!flagObj) return false;
} }
return true; return true;
@ -29,24 +31,25 @@ function checkSubcmd(subcmds: string[], cmd: Command): boolean {
if (!cmd.subcommands) return false; if (!cmd.subcommands) return false;
for (const sc of subcmds) { for (const sc of subcmds) {
const flagObj = cmd.subcommands.find(s => s.name === sc); const flagObj = Object.values(cmd.subcommands).find(s => s.name === sc);
if (!flagObj) return false; if (!flagObj) return false;
} }
return true; return true;
} }
function checkFlagInclude(flagsProvided: string[], flag: Flag): boolean { function checkFlagInclude(flagsProvided: string[], flag: Flag): boolean {
if (!flag) return false;
return flagsProvided.includes(`-${flag.short}`) || flagsProvided.includes(`--${flag.long}`); return flagsProvided.includes(`-${flag.short}`) || flagsProvided.includes(`--${flag.long}`);
} }
export function printSyntax(cmd: Command): string[] { export function printSyntax(cmd: Command): string[] {
let flagsOption = ""; let flagsOption = "";
let flagsDesc = []; let flagsDesc = [];
if (cmd.flags && cmd.flags.length > 0) { if (cmd.flags && Object.keys(cmd.flags).length > 0) {
flagsOption = " ["; flagsOption = " [";
flagsDesc.push(""); flagsDesc.push("");
flagsDesc.push("Flags:"); flagsDesc.push("Flags:");
cmd.flags.forEach((flag => { Object.values(cmd.flags).forEach((flag => {
flagsOption += `-${flag.short} `; flagsOption += `-${flag.short} `;
flagsDesc.push(`\t-${flag.short}\t--${flag.long}\t${flag.desc}`); flagsDesc.push(`\t-${flag.short}\t--${flag.long}\t${flag.desc}`);
})); }));
@ -55,13 +58,13 @@ export function printSyntax(cmd: Command): string[] {
let subcmdOption = ""; let subcmdOption = "";
let subcmdDesc = []; let subcmdDesc = [];
if (cmd.subcommands && cmd.subcommands.length > 0) { if (cmd.subcommands && Object.keys(cmd.subcommands).length > 0) {
subcmdOption = " ["; subcmdOption = " [";
subcmdDesc.push(""); subcmdDesc.push("");
subcmdDesc.push("Arguments:"); subcmdDesc.push("Arguments:");
cmd.subcommands.forEach((subcmd => { Object.values(cmd.subcommands).forEach((subcmd => {
subcmdOption += `${subcmd.name}|`; subcmdOption += `${subcmd.name}|`;
subcmdDesc.push(`\t${subcmd.name}\t\t${subcmd.desc}`); subcmdDesc.push(`\t${subcmd.name}\t${subcmd.desc}`);
})); }));
subcmdOption = subcmdOption.substring(0, subcmdOption.length-1) + "]"; subcmdOption = subcmdOption.substring(0, subcmdOption.length-1) + "]";
} }
@ -72,7 +75,7 @@ export function printSyntax(cmd: Command): string[] {
const about: Command = { const about: Command = {
name: "about", name: "about",
desc: "Show information about this page.", desc: "Show information about this page.",
execute: (_flags, _args, _raw) => { execute: () => {
return [ return [
"Hello there wanderer.", "Hello there wanderer.",
"So you want to know what this is about?", "So you want to know what this is about?",
@ -85,7 +88,7 @@ const about: Command = {
"Even when you open a project page you don't need your mouse - just press Esc to close it.", "Even when you open a project page you don't need your mouse - just press Esc to close it.",
"", "",
"I hope you enjoy your stay here!", "I hope you enjoy your stay here!",
"If you wanted more information about the page itself, type 'project this'." "If you wanted more information about the page itself, type 'project this' or 'help -t'."
]; ];
} }
}; };
@ -93,10 +96,9 @@ const about: Command = {
const help: Command = { const help: Command = {
name: "help", name: "help",
desc: "Shows helptext.", desc: "Shows helptext.",
flags: [{ long: "more", short: "m", desc: "Show more information." }], flags: {more: { long: "this", short: "t", desc: "Show information about this site." }},
execute: (flags, _args, _raw) => { execute: (flags) => {
checkFlags(flags, help); if (help.flags && checkFlagInclude(flags, help.flags.more)) {
if (help.flags && checkFlagInclude(flags, help.flags[0])) {
return [ return [
"Hello user!", "Hello user!",
"What you see here should resemble an CLI. If you ever used Linux this should be pretty easy for you.", "What you see here should resemble an CLI. If you ever used Linux this should be pretty easy for you.",
@ -120,8 +122,10 @@ const help: Command = {
const man: Command = { const man: Command = {
name: "man", name: "man",
desc: "Provides a manual for a command.", desc: "Provides a manual for a command.",
subcommands: [{name: "command", desc: "Name of a command"}], subcommands: {
execute: (_flags, args, _raw) => { command: {name: "command", desc: "Name of a command"}
},
execute: (_flags, args) => {
if (args.length !== 1) { if (args.length !== 1) {
return printSyntax(man); return printSyntax(man);
} else { } else {
@ -132,4 +136,46 @@ const man: Command = {
} }
}; };
export const commandList = [about, help, man]; const project: Command = {
name: "project",
desc: "Show information about a project.",
flags: {
minimal: {short: "m", long: "minimal", desc: "Only show minimal information."},
source: {short: "s", long: "source", desc: "Open git repository of project."},
list: {short: "l", long: "list", desc: "Show list of projects."}
},
subcommands: {name: {name: "name", desc: "Name of the project."}},
execute: (flags, args) => {
if (project.flags && checkFlagInclude(flags, project.flags.list)) {
const result = ["Found the following projects:"];
projectList.forEach(project => result.push(`\t${project.name}\t${project.short}`));
return result;
}
if (args.length !== 1) return printSyntax(project);
if (args[0] === "this") args[0] = "homepage";
const pjt = projectList.find(p => p.name === args[0]);
if (!pjt) return [
`Cannot find project ${args[0]}!`,
"You can see available projects using 'project -l'."
];
if (project.flags && checkFlagInclude(flags, project.flags.source)) {
try {
window && window.open(pjt.repo, "_blank");
return ["Opened repository in new tab."];
} catch {
return ["Sorry, no repository for this project."];
}
}
if (project.flags && checkFlagInclude(flags, project.flags.minimal)) return pjt.desc;
// TODO
// Open project page here.
return [];
}
};
export const commandList = [about, help, man, project];

View File

@ -1,7 +1,5 @@
import { printSyntax, commandList } from "./definitions"; import { printSyntax, commandList } from "./definitions";
//const commandList = ["about", "navigate", "external", "help", "ed", "nano"];
export function commandCompletion(input: string): string[] { export function commandCompletion(input: string): string[] {
if (input === "") return []; if (input === "") return [];
const candidates = commandList.filter(cmd => cmd.name.substring(0, input.length) === input).map(cmd => cmd.name); const candidates = commandList.filter(cmd => cmd.name.substring(0, input.length) === input).map(cmd => cmd.name);

View File

@ -13,7 +13,7 @@ export interface Command {
name: string; name: string;
hidden?: boolean; hidden?: boolean;
desc: string; desc: string;
flags?: Flag[]; flags?: Record<string,Flag>;
subcommands?: SubCommand[]; subcommands?: Record<string,SubCommand>;
execute: (flags: string[], args: string[], raw: string, extra?: any) => string[]; execute: (flags: string[], args: string[], raw: string, extra?: any) => string[];
} }

19
lib/projects/index.ts Normal file
View File

@ -0,0 +1,19 @@
import type { Project } from "./types";
const projectList: Project[] = [
{
name: "homepage",
short: "This website.",
desc: [
"This is my homepage.",
"What you see here should resemble an CLI. If you ever used Linux this should be pretty easy for you.",
"Everyone else: Have no fear. It is pretty simple. You just type in commands and the output is shown here or it does something on the webite.",
"To find out, which commands are available, you can type just 'help'.",
"",
"Have fun!"
],
repo: "https://git.c0ntroller.de/c0ntroller/frontpage"
}
];
export default projectList;

7
lib/projects/types.ts Normal file
View File

@ -0,0 +1,7 @@
export interface Project {
name: string;
desc: string[];
short: string;
more?: string;
repo?: string;
}