From 5b016df85ddcef017648039601ff08668d329ba8 Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Sat, 7 May 2022 21:50:20 +0200 Subject: [PATCH] feat(cli): added commands for interacting with build logs --- src/client/client.v | 32 ++++++--- src/client/logs.v | 6 ++ src/console/console.v | 1 + src/{git/cli.v => console/git/git.v} | 0 src/console/logs/logs.v | 99 ++++++++++++++++++++++++++++ src/db/logs.v | 14 ++++ src/main.v | 4 +- 7 files changed, 145 insertions(+), 11 deletions(-) create mode 100644 src/console/console.v rename src/{git/cli.v => console/git/git.v} (100%) create mode 100644 src/console/logs/logs.v diff --git a/src/client/client.v b/src/client/client.v index 7446e91..12c92d3 100644 --- a/src/client/client.v +++ b/src/client/client.v @@ -18,15 +18,7 @@ pub fn new(address string, api_key string) Client { } } -// send_request just calls send_request_with_body with an empty body. -fn (c &Client) send_request(method Method, url string, params map[string]string) ?Response { - return c.send_request_with_body(method, url, params, '') -} - -// send_request_with_body is a convenience method for sending requests to -// the repos API. It mostly does string manipulation to create a query string -// containing the provided params. -fn (c &Client) send_request_with_body(method Method, url string, params map[string]string, body string) ?Response { +fn (c &Client) send_request_raw(method Method, url string, params map[string]string, body string) ?http.Response { mut full_url := '$c.address$url' if params.len > 0 { @@ -46,7 +38,27 @@ fn (c &Client) send_request_with_body(method Method, url string, params map[s req.add_custom_header('X-Api-Key', c.api_key) ? res := req.do() ? - data := json.decode(Response, res.text) ? + + return res +} + +// send_request just calls send_request_with_body with an empty body. +fn (c &Client) send_request(method Method, url string, params map[string]string) ?Response { + return c.send_request_with_body(method, url, params, '') +} + +// send_request_with_body is a convenience method for sending requests to +// the repos API. It mostly does string manipulation to create a query string +// containing the provided params. +fn (c &Client) send_request_with_body(method Method, url string, params map[string]string, body string) ?Response { + res_text := c.send_request_raw_response(method, url, params, body) ? + data := json.decode(Response, res_text) ? return data } + +fn (c &Client) send_request_raw_response(method Method, url string, params map[string]string, body string) ?string { + res := c.send_request_raw(method, url, params, body) ? + + return res.text +} diff --git a/src/client/logs.v b/src/client/logs.v index 9182f69..19575a6 100644 --- a/src/client/logs.v +++ b/src/client/logs.v @@ -27,6 +27,12 @@ pub fn (c &Client) get_build_log(id int) ?Response { return data } +pub fn (c &Client) get_build_log_content(id int) ?string { + data := c.send_request_raw_response(Method.get, '/api/logs/$id/content', {}, '') ? + + return data +} + pub fn (c &Client) add_build_log(repo_id int, start_time time.Time, end_time time.Time, arch string, exit_code int, content string) ?Response { params := { 'repo': repo_id.str() diff --git a/src/console/console.v b/src/console/console.v new file mode 100644 index 0000000..6f296bd --- /dev/null +++ b/src/console/console.v @@ -0,0 +1 @@ +module console diff --git a/src/git/cli.v b/src/console/git/git.v similarity index 100% rename from src/git/cli.v rename to src/console/git/git.v diff --git a/src/console/logs/logs.v b/src/console/logs/logs.v new file mode 100644 index 0000000..14aeddf --- /dev/null +++ b/src/console/logs/logs.v @@ -0,0 +1,99 @@ +module logs + +import cli +import env +import client +import db + +struct Config { + address string [required] + api_key string [required] +} + +pub fn cmd() cli.Command { + return cli.Command{ + name: 'logs' + description: 'Interact with the build logs API.' + commands: [ + cli.Command{ + name: 'list' + description: 'List the build logs. If a repo ID is provided, only list the build logs for that repo.' + flags: [ + cli.Flag{ + name: 'repo' + description: 'ID of the Git repo to restrict list to.' + flag: cli.FlagType.int + }, + ] + execute: fn (cmd cli.Command) ? { + config_file := cmd.flags.get_string('config-file') ? + conf := env.load(config_file) ? + + repo_id := cmd.flags.get_int('repo') ? + + if repo_id == 0 { list(conf) ? } else { list_for_repo(conf, repo_id) ? } + } + }, + cli.Command{ + name: 'info' + required_args: 1 + usage: 'id' + description: 'Show all info for a specific build log.' + execute: fn (cmd cli.Command) ? { + config_file := cmd.flags.get_string('config-file') ? + conf := env.load(config_file) ? + + id := cmd.args[0].int() + info(conf, id) ? + } + }, + cli.Command{ + name: 'content' + required_args: 1 + usage: 'id' + description: 'Output the content of a build log to stdout.' + execute: fn (cmd cli.Command) ? { + config_file := cmd.flags.get_string('config-file') ? + conf := env.load(config_file) ? + + id := cmd.args[0].int() + content(conf, id) ? + } + }, + ] + } +} + +fn print_log_list(logs []db.BuildLog) { + for log in logs { + println('$log.id\t$log.start_time\t$log.exit_code') + } +} + +fn list(conf Config) ? { + c := client.new(conf.address, conf.api_key) + logs := c.get_build_logs() ?.data + + print_log_list(logs) +} + +fn list_for_repo(conf Config, repo_id int) ? { + c := client.new(conf.address, conf.api_key) + logs := c.get_build_logs_for_repo(repo_id) ?.data + + print_log_list(logs) +} + +fn info(conf Config, id int) ? { + c := client.new(conf.address, conf.api_key) + log := c.get_build_log(id) ?.data + + print(log) +} + +fn content(conf Config, id int) ? { + c := client.new(conf.address, conf.api_key) + content := c.get_build_log_content(id) ? + + println(content) +} diff --git a/src/db/logs.v b/src/db/logs.v index 9ce2865..05973af 100644 --- a/src/db/logs.v +++ b/src/db/logs.v @@ -12,6 +12,20 @@ pub: exit_code int [nonull] } +pub fn (bl &BuildLog) str() string { + mut parts := [ + 'id: $bl.id', + 'repo id: $bl.repo_id', + 'start time: $bl.start_time', + 'end time: $bl.end_time', + 'arch: $bl.arch', + 'exit code: $bl.exit_code', + ] + str := parts.join('\n') + + return str +} + // get_build_logs returns all BuildLog's in the database. pub fn (db &VieterDb) get_build_logs() []BuildLog { res := sql db.conn { diff --git a/src/main.v b/src/main.v index 4ba6d30..41d0d33 100644 --- a/src/main.v +++ b/src/main.v @@ -4,7 +4,8 @@ import os import server import cli import build -import git +import console.git +import console.logs import cron fn main() { @@ -27,6 +28,7 @@ fn main() { build.cmd(), git.cmd(), cron.cmd(), + logs.cmd(), ] }