From 46f75467e251809dce87a4bb17828aa76b65fdf3 Mon Sep 17 00:00:00 2001 From: didier amyot Date: Fri, 3 Mar 2023 07:41:59 -0800 Subject: [PATCH] added state to cli --- mod.ts | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 3 deletions(-) diff --git a/mod.ts b/mod.ts index 294775b..6bbdee3 100644 --- a/mod.ts +++ b/mod.ts @@ -1,13 +1,100 @@ import { Command } from "https://deno.land/x/cliffy@v0.25.7/command/mod.ts"; +import { DB } from "https://deno.land/x/sqlite/mod.ts"; +import {join} from "https://deno.land/std@0.178.0/path/mod.ts"; + +// for the demo, we will place the state in the /tmp instead of $HOME +const HOME_DIRECTORY = '/tmp'; +const CLI_STATE_DIRECTORY = join(HOME_DIRECTORY, 'deno-cli-example'); + +// the CLI will need read and write access to /tmp/deno-cli-example directory +await Deno.mkdir(CLI_STATE_DIRECTORY, {recursive: true}); +const MAIN_DB_FILE = join(CLI_STATE_DIRECTORY, 'state.sqlite'); -function helloWorld(options, ...args) { - console.log("hello world"); +/** + * Create tables in the database. This function is a + * trivial data migration algorithm. + */ +function initDB(){ + const db = new DB(MAIN_DB_FILE); + const init_db = ` + CREATE TABLE IF NOT EXISTS usernames ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + username TEXT, + creation_ts DATETIME DEFAULT CURRENT_TIMESTAMP + ) + `; + try { + db.execute(init_db); + } finally { + db.close(); + } } +/** + * Returns the latest username saved in the state. + */ +function getUsernameFromDB(){ + const db = new DB(MAIN_DB_FILE); + try { + return db.query(`SELECT username + FROM usernames + ORDER BY creation_ts + DESC LIMIT 1`)[0] + } finally { + db.close(); + } +} + +/** + * Set the passed username in the database. + */ +function setUsernameInDB(username: string){ + const db = new DB(MAIN_DB_FILE); + try { + return db.query("INSERT INTO usernames (username) VALUES (?)", [username]) + } finally { + db.close(); + } +} + +function getUsernameOrDefault(name?: string): string{ + return name || getUsernameFromDB() || 'no username set yet.'; +} + +/** + * Calls httpbin.org/get with the username as argument. + */ +async function getFromService(options){ + const username = getUsernameOrDefault(options.usermame); + const encodedUsername = encodeURIComponent(username); + const url = `https://httpbin.org/get?username=${encodedUsername}`; + const response = await fetch(); + console.log(await response.json()); +} + +async function setProperties(options){ + if(options.username){ + setUsernameInDB(options.username); + } +} + +initDB(); await new Command() .name("deno-cli-example") .version("0.1.0") .description("Example of a deno CLI.") - .action(helloWorld) + .command('call-service') + .description('Example of a real use case. call-service will called ' + + 'https://httpbin.org/get with username passed as parameter.') + .option("--username ", + 'username to use in the service call. If no username specified, the ' + + ' persisted username will be used.') + .action(getFromService) + .command('set-properties') + .description('Persist properties to state. Persisted properties will then ' + + 'be used as default in other commands') + .option("--username ", "Set the default username property.", + {required: true}) + .action(setProperties) .parse(Deno.args);