From eb6f22c0e3e2f10669d2368b7fad6b0a594d8585 Mon Sep 17 00:00:00 2001 From: Lance Pollard Date: Thu, 18 Jan 2024 20:35:57 -0800 Subject: [PATCH] system info --- code/cli/logging.ts | 47 ++++++++++- code/cli/task.ts | 11 +++ code/node/code.ts | 132 +++++++++++++++---------------- code/node/system.ts | 34 ++++++++ code/shared/code.ts | 12 +++ code/shared/type/cast.ts | 10 +++ code/shared/type/code.ts | 17 ++++ code/shared/type/source/code.ts | 18 +++++ code/shared/type/source/index.ts | 1 + code/shared/type/take.ts | 10 +++ code/shared/video.ts | 1 - package.json | 5 ++ pnpm-lock.yaml | 52 ++++++++++++ readme.md | 1 + test/cli.sh | 2 +- 15 files changed, 284 insertions(+), 69 deletions(-) create mode 100644 code/node/system.ts diff --git a/code/cli/logging.ts b/code/cli/logging.ts index 3094231..abd2fb2 100644 --- a/code/cli/logging.ts +++ b/code/cli/logging.ts @@ -2,10 +2,13 @@ import stripAnsi from 'strip-ansi' import tint, { Tint } from '@termsurf/tint-text' import ora from 'ora' import { log, logWithSpace } from '../shared/logger.js' +import _ from 'lodash' const M: Tint = { tone: 'magenta' } const C: Tint = { tone: 'cyan' } -const B: Tint = { tone: 'white' } +const B: Tint = { tone: 'blackBright' } +const W: Tint = { tone: 'white' } +const WB: Tint = { tone: 'whiteBright' } const G: Tint = { tone: 'green' } const R: Tint = { tone: 'red' } @@ -68,3 +71,45 @@ export function renderProgress(text: string, color = true) { return text } } + +export function logTree(json) { + const text: Array = [] + + traverse(json) + + console.log(text.join('\n')) + + function traverse(json, depth = 1) { + for (const name in json) { + const val = json[name] + if (val) { + if (_.isObject(val)) { + text.push( + ident(depth) + + tint('o', B) + + ' ' + + tint(_.kebabCase(name), W), + ) + traverse(val, depth + 1) + } else { + text.push( + ident(depth) + + tint('o', B) + + ' ' + + tint(_.kebabCase(name), W), + ) + text.push( + ident(depth + 1) + + tint(' o <', B) + + tint(val, C) + + tint('>', B), + ) + } + } + } + } +} + +function ident(size: number) { + return ''.padStart(size * 2, ' ') +} diff --git a/code/cli/task.ts b/code/cli/task.ts index d84cee3..2a12e63 100644 --- a/code/cli/task.ts +++ b/code/cli/task.ts @@ -48,6 +48,7 @@ import { logOutput, logOutputError, logStart, + logTree, renderProgress, } from './logging.js' import { @@ -56,6 +57,7 @@ import { transferInput, } from './parse.js' import { formatRust } from '../node/code.js' +import { inspectSystem } from '../node/system.js' export const CONVERT_KEY: Record = { i: { line: ['input', 'file', 'path'] }, @@ -303,6 +305,15 @@ export async function call(task: Task, source) { return } } + case 'inspect': { + const thing = source.object[0] as string + if (thing === 'system') { + const info = await inspectSystem() + logTree(info) + return + } + break + } } throw kink('task_not_implemented', { diff --git a/code/node/code.ts b/code/node/code.ts index 29f4f62..ed81d1d 100644 --- a/code/node/code.ts +++ b/code/node/code.ts @@ -12,73 +12,73 @@ import { CompileToAst, } from '../shared/index.js' import { handleCommand } from './command.js' -import Parser from 'tree-sitter' -import JavaScript from 'tree-sitter-javascript' -import Swift from 'tree-sitter-swift' -import fsp from 'fs/promises' - -// compileToAsm({ -// input: { -// format: 'js', -// file: { path: 'test/file/code/quicksort/quicksort.js' }, -// }, -// }) - -// compileToAsm({ -// input: { -// format: 'js', -// file: { path: 'test/file/code/quicksort/quicksort.swift' }, -// }, -// }) - -const TREE_SITTER_LANGUAGE: Record = { - js: JavaScript, - swift: Swift, -} +// import Parser from 'tree-sitter' +// import JavaScript from 'tree-sitter-javascript' +// import Swift from 'tree-sitter-swift' +// import fsp from 'fs/promises' + +// // compileToAsm({ +// // input: { +// // format: 'js', +// // file: { path: 'test/file/code/quicksort/quicksort.js' }, +// // }, +// // }) + +// // compileToAsm({ +// // input: { +// // format: 'js', +// // file: { path: 'test/file/code/quicksort/quicksort.swift' }, +// // }, +// // }) + +// const TREE_SITTER_LANGUAGE: Record = { +// js: JavaScript, +// swift: Swift, +// } -export async function compileToAsm(input: CompileToAst) { - const parser = new Parser() - parser.setLanguage(TREE_SITTER_LANGUAGE[input.input.format]) - const code = await fsp.readFile(input.input.file.path, 'utf-8') - const tree = parser.parse(code) - return traverse(tree.rootNode) - - function traverse(node) { - const out: any = { - form: node.type, - base: node.startPosition, - head: node.endPosition, - } - if (node.type.match(/^[\w_]+$/)) { - switch (node.type) { - case 'identifier': - case 'number': - case 'string': - case 'comment': - case 'string_fragment': - case 'template_string': - case 'simple_identifier': - case 'var': - case 'let': - case 'const': - case 'true': - case 'return': - case 'false': - out.text = node.text - break - } - } else { - out.text = node.text - } - if (node.children?.length) { - out.nest = [] - for (const child of node.children) { - out.nest.push(traverse(child)) - } - } - return out - } -} +// export async function compileToAsm(input: CompileToAst) { +// const parser = new Parser() +// parser.setLanguage(TREE_SITTER_LANGUAGE[input.input.format]) +// const code = await fsp.readFile(input.input.file.path, 'utf-8') +// const tree = parser.parse(code) +// return traverse(tree.rootNode) + +// function traverse(node) { +// const out: any = { +// form: node.type, +// base: node.startPosition, +// head: node.endPosition, +// } +// if (node.type.match(/^[\w_]+$/)) { +// switch (node.type) { +// case 'identifier': +// case 'number': +// case 'string': +// case 'comment': +// case 'string_fragment': +// case 'template_string': +// case 'simple_identifier': +// case 'var': +// case 'let': +// case 'const': +// case 'true': +// case 'return': +// case 'false': +// out.text = node.text +// break +// } +// } else { +// out.text = node.text +// } +// if (node.children?.length) { +// out.nest = [] +// for (const child of node.children) { +// out.nest.push(traverse(child)) +// } +// } +// return out +// } +// } // function define( // lang: string, diff --git a/code/node/system.ts b/code/node/system.ts new file mode 100644 index 0000000..fdde7ca --- /dev/null +++ b/code/node/system.ts @@ -0,0 +1,34 @@ +import si from 'systeminformation' +import _ from 'lodash' + +export async function inspectSystem() { + return await inspectBasicSystem() +} + +export async function inspectBasicSystem() { + const os = _.omit(await si.osInfo(), [ + 'serial', + 'servicepack', + 'logofile', + 'fqdn', + 'uefi', + ]) + const system = _.omit(await si.system(), [ + 'serial', + 'uuid', + 'sku', + 'uuid', + ]) + const cpu = _.omit(await si.cpu(), [ + 'cache', + 'governor', + 'flags', + 'virtualization', + 'revision', + 'voltage', + 'vendor', + 'speedMin', + 'speedMax', + ]) + return { os, system, cpu } +} diff --git a/code/shared/code.ts b/code/shared/code.ts index e1dbeeb..644baeb 100644 --- a/code/shared/code.ts +++ b/code/shared/code.ts @@ -10,9 +10,21 @@ import { FormatPython, FormatRuby, FormatRust, + FormatSqlWithContent, FormatSwift, LLVM_ARCHITECTURE_CONTENT, } from './type/index.js' +import { format as _formatSql } from 'sql-formatter' +import decodeUtf8 from 'decode-utf8' + +// https://github.com/sql-formatter-org/sql-formatter?tab=readme-ov-file +export function formatSqlWithContent(input: FormatSqlWithContent) { + const text = + input.input.file.content instanceof ArrayBuffer + ? decodeUtf8(input.input.file.content) + : input.input.file.content + return _formatSql(text) +} export function buildCommandToCompileSwift(input: CompileSwift) { const cmd = getCommand(`swiftc`) diff --git a/code/shared/type/cast.ts b/code/shared/type/cast.ts index 433d158..02293f6 100644 --- a/code/shared/type/cast.ts +++ b/code/shared/type/cast.ts @@ -92225,6 +92225,15 @@ export type FormatRust = { } } +export type FormatSqlWithContent = { + input: { + format: string + file: { + content: ArrayBuffer | string + } + } +} + export type FormatSwift = { input: { format: string @@ -108104,6 +108113,7 @@ export const TASK = [ 'read', 'add', 'verify', + 'inspect', ] as const export type Task = (typeof TASK)[number] diff --git a/code/shared/type/code.ts b/code/shared/type/code.ts index c6db4a4..305628a 100644 --- a/code/shared/type/code.ts +++ b/code/shared/type/code.ts @@ -27,6 +27,23 @@ export const transform_input_output_file: Make = { }, } +export const validate_input_file_path_or_content: Make = { + form: 'make', + make: (v: Record, ctx: RefinementCtx) => { + if (!v.input.file.path) { + if (!v.input.file.content) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `Must specify either input file path or content.`, + path: ['input', 'file'], + }) + } + } + + return v + }, +} + export const test_time_string: Test = { form: 'test', test: (bond: string, name: string) => diff --git a/code/shared/type/source/code.ts b/code/shared/type/source/code.ts index 97d160e..15ecad2 100644 --- a/code/shared/type/source/code.ts +++ b/code/shared/type/source/code.ts @@ -737,3 +737,21 @@ export const compile_to_ast: Form = { }, }, } + +export const format_sql_with_content: Form = { + form: 'form', + link: { + input: { + link: { + format: { like: 'string', name: { mark: 'I' } }, + file: { + link: { + content: { + case: [{ like: 'ArrayBuffer' }, { like: 'string' }], + }, + }, + }, + }, + }, + }, +} diff --git a/code/shared/type/source/index.ts b/code/shared/type/source/index.ts index 952163b..aae70f0 100644 --- a/code/shared/type/source/index.ts +++ b/code/shared/type/source/index.ts @@ -130,6 +130,7 @@ export const task: List = { 'read', 'add', 'verify', + 'inspect', ], } diff --git a/code/shared/type/take.ts b/code/shared/type/take.ts index 8f62aae..12ba0b9 100644 --- a/code/shared/type/take.ts +++ b/code/shared/type/take.ts @@ -1316,6 +1316,16 @@ export const FormatRustModel: z.ZodType = z.object({ }), }) +export const FormatSqlWithContentModel: z.ZodType = + z.object({ + input: z.object({ + format: z.string(), + file: z.object({ + content: z.union([z.instanceof(ArrayBuffer), z.string()]), + }), + }), + }) + export const FormatSwiftModel: z.ZodType = z.object({ input: z.object({ format: z.string(), diff --git a/code/shared/video.ts b/code/shared/video.ts index 22686db..6b73c38 100644 --- a/code/shared/video.ts +++ b/code/shared/video.ts @@ -3,7 +3,6 @@ import { CompressMp4WithFfmpegModel, ConvertMp4ToGifWithFfmpegModel, ConvertVideoWithFfmpeg, - ConvertVideoWithFfmpegModel, FfmpegCodecAudio, IOPath, } from './type/index.js' diff --git a/package.json b/package.json index db4ef26..7a1698a 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "@types/node-forge": "^1.3.11", "@types/replace-ext": "^2.0.2", "@types/sanitize-html": "^2.9.5", + "@types/sql-formatter": "^4.0.1", "accept-language-parser": "^1.5.0", "archiver": "^6.0.1", "bytes": "^3.1.2", @@ -59,6 +60,8 @@ "css-property-parser": "^1.0.6", "csv-parse": "^5.5.3", "dayjs": "^1.11.10", + "decode-utf8": "^1.0.1", + "encode-utf8": "^2.0.0", "fast-content-type-parse": "^1.1.0", "fast-glob": "^3.3.2", "fflate": "^0.8.1", @@ -83,8 +86,10 @@ "replace-ext": "^2.0.0", "sanitize-html": "^2.11.0", "sql-escape-string": "^1.1.0", + "sql-formatter": "^15.0.2", "strip-ansi": "^7.1.0", "svgexport": "^0.4.2", + "systeminformation": "^5.21.22", "tmp-promise": "^3.0.3", "tree-sitter": "^0.20.6", "tree-sitter-javascript": "^0.20.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 39924f1..e487544 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -56,6 +56,9 @@ dependencies: '@types/sanitize-html': specifier: ^2.9.5 version: 2.9.5 + '@types/sql-formatter': + specifier: ^4.0.1 + version: 4.0.1 accept-language-parser: specifier: ^1.5.0 version: 1.5.0 @@ -95,6 +98,12 @@ dependencies: dayjs: specifier: ^1.11.10 version: 1.11.10 + decode-utf8: + specifier: ^1.0.1 + version: 1.0.1 + encode-utf8: + specifier: ^2.0.0 + version: 2.0.0 fast-content-type-parse: specifier: ^1.1.0 version: 1.1.0 @@ -167,12 +176,18 @@ dependencies: sql-escape-string: specifier: ^1.1.0 version: 1.1.0 + sql-formatter: + specifier: ^15.0.2 + version: 15.0.2 strip-ansi: specifier: ^7.1.0 version: 7.1.0 svgexport: specifier: ^0.4.2 version: 0.4.2 + systeminformation: + specifier: ^5.21.22 + version: 5.21.22 tmp-promise: specifier: ^3.0.3 version: 3.0.3 @@ -1414,6 +1429,13 @@ packages: resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==} dev: true + /@types/sql-formatter@4.0.1: + resolution: {integrity: sha512-WLSHjarjiUz4GtQivyaDbagqJNHcFA1XOAvrgXmWLl1OeTCP0RuiFB1PtUIH4ArOqZX1Hk6ANzABWe6nw9nKpg==} + deprecated: This is a stub types definition. sql-formatter provides its own type definitions, so you do not need this installed. + dependencies: + sql-formatter: 15.0.2 + dev: false + /@types/xlsx@0.0.35: resolution: {integrity: sha512-s0x3DYHZzOkxtjqOk/Nv1ezGzpbN7I8WX+lzlV/nFfTDOv7x4d8ZwGHcnaiB8UCx89omPsftQhS5II3jeWePxQ==} dev: true @@ -2407,6 +2429,10 @@ packages: dependencies: ms: 2.1.2 + /decode-utf8@1.0.1: + resolution: {integrity: sha512-iTpp497Pgdg5JdQ3HkHbG0vwSSYRDrtVXKpz/ieFhY+LjLOZ2HjVtdmNKyO4f25lr4Q6O0cYSzlo6h27LgsLDA==} + dev: false + /decompress-response@6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} @@ -2539,6 +2565,11 @@ packages: /emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + /encode-utf8@2.0.0: + resolution: {integrity: sha512-3EyMFxZj1/7oMotElDQUEQcP7N4TIe1aJ0m1uBDoyQ8I2LBHhBsXx8P3KsPbqNlGzG+NYxFwEauUwMPHZg3YDQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: false + /end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} dependencies: @@ -3429,6 +3460,11 @@ packages: hasown: 2.0.0 dev: true + /get-stdin@8.0.0: + resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} + engines: {node: '>=10'} + dev: false + /get-stream@5.2.0: resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} engines: {node: '>=8'} @@ -5657,6 +5693,15 @@ packages: resolution: {integrity: sha512-/kqO4pLZSLfV0KsBM2xkVh2S3GbjJJone37d7gYwLyP0c+REh3vnmkhQ7VwNrX76igC0OhJWpTg0ukkdef9vvA==} dev: false + /sql-formatter@15.0.2: + resolution: {integrity: sha512-B8FTRc1dhb36lfuwSdiLhwrhkvT3PU/3es7YDPPQBOhbGHdXKlweAXTRS+QfCWk06ufAh118yFja6NcukBS4gg==} + hasBin: true + dependencies: + argparse: 2.0.1 + get-stdin: 8.0.0 + nearley: 2.20.1 + dev: false + /stdin-discarder@0.2.2: resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} engines: {node: '>=18'} @@ -5823,6 +5868,13 @@ packages: - utf-8-validate dev: false + /systeminformation@5.21.22: + resolution: {integrity: sha512-gNHloAJSyS+sKWkwvmvozZ1eHrdVTEsynWMTY6lvLGBB70gflkBQFw8drXXr1oEXY84+Vr9tOOrN8xHZLJSycA==} + engines: {node: '>=8.0.0'} + os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] + hasBin: true + dev: false + /tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} diff --git a/readme.md b/readme.md index 88c7ba1..2f69986 100644 --- a/readme.md +++ b/readme.md @@ -143,6 +143,7 @@ You don't need to run Docker to develop this, you can just install the tools on - add compress commands - add format commands - add compile commands +- add spreadsheet conversion ## License diff --git a/test/cli.sh b/test/cli.sh index 21e7131..d921c36 100755 --- a/test/cli.sh +++ b/test/cli.sh @@ -113,7 +113,7 @@ alias task="pnpm tsx code/cli" # # run script on all files matching pattern # task replace -r -i *.js -e script.ts # # get data on current device -# task inspect device +# task inspect system # task list process # task kill process 123 # task trace server -i https://google.com