refactor(client): streamline code & improve error propagation

pull/306/head
Jef Roosens 2022-12-15 10:01:45 +01:00
parent 0bd5158608
commit 0727d0fd25
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
6 changed files with 29 additions and 67 deletions

View File

@ -1,6 +1,6 @@
module client module client
import net.http { Method, Status } import net.http { Method }
import net.urllib import net.urllib
import web.response { Response, new_data_response } import web.response { Response, new_data_response }
import json import json
@ -57,25 +57,24 @@ fn (c &Client) send_request<T>(method Method, url string, params map[string]stri
// output as a Response<T> object. // output as a Response<T> object.
fn (c &Client) send_request_with_body<T>(method Method, url string, params map[string]string, body string) !Response<T> { fn (c &Client) send_request_with_body<T>(method Method, url string, params map[string]string, body string) !Response<T> {
res := c.send_request_raw(method, url, params, body)! res := c.send_request_raw(method, url, params, body)!
status := http.status_from_int(res.status_code)
// Just return an empty successful response // Just return an empty successful response
if res.status_code == Status.no_content.int() { if status.is_success() && res.body == '' {
return new_data_response(T{}) return new_data_response(T{})
} }
// Non-successful requests are expected to return either an empty body or // Non-successful requests are expected to return either an empty body or
// Response<string> // Response<string>
if res.status_code < 200 || res.status_code > 299 { if status.is_error() {
status_string := http.status_from_int(res.status_code).str()
// A non-successful status call will have an empty body // A non-successful status call will have an empty body
if res.body == '' { if res.body == '' {
return error('Error $res.status_code ($status_string): (empty response)') return error('Error $res.status_code ($status.str()): (empty response)')
} }
data := json.decode(Response<string>, res.body)! data := json.decode(Response<string>, res.body)!
return error('Status $res.status_code ($status_string): $data.message') return error('Status $res.status_code ($status.str()): $data.message')
} }
data := json.decode(Response<T>, res.body)! data := json.decode(Response<T>, res.body)!

View File

@ -1,7 +1,6 @@
module client module client
import build { BuildConfig } import build { BuildConfig }
import web.response { Response }
// poll_jobs requests a list of new build jobs from the server. // poll_jobs requests a list of new build jobs from the server.
pub fn (c &Client) poll_jobs(arch string, max int) ![]BuildConfig { pub fn (c &Client) poll_jobs(arch string, max int) ![]BuildConfig {
@ -15,12 +14,10 @@ pub fn (c &Client) poll_jobs(arch string, max int) ![]BuildConfig {
// queue_job adds a new one-time build job for the given target to the job // queue_job adds a new one-time build job for the given target to the job
// queue. // queue.
pub fn (c &Client) queue_job(target_id int, arch string, force bool) !Response<string> { pub fn (c &Client) queue_job(target_id int, arch string, force bool) ! {
data := c.send_request<string>(.post, '/api/v1/jobs/queue', { c.send_request<string>(.post, '/api/v1/jobs/queue', {
'target': target_id.str() 'target': target_id.str()
'arch': arch 'arch': arch
'force': force.str() 'force': force.str()
})! })!
return data
} }

View File

@ -6,29 +6,18 @@ import web.response { Response }
import time import time
// get_build_logs returns all build logs. // get_build_logs returns all build logs.
pub fn (c &Client) get_build_logs(filter BuildLogFilter) !Response<[]BuildLog> { pub fn (c &Client) get_build_logs(filter BuildLogFilter) ![]BuildLog {
params := models.params_from(filter) params := models.params_from(filter)
data := c.send_request<[]BuildLog>(Method.get, '/api/v1/logs', params)! data := c.send_request<[]BuildLog>(Method.get, '/api/v1/logs', params)!
return data return data.data
}
// get_build_logs_for_target returns all build logs for a given target.
pub fn (c &Client) get_build_logs_for_target(target_id int) !Response<[]BuildLog> {
params := {
'repo': target_id.str()
}
data := c.send_request<[]BuildLog>(Method.get, '/api/v1/logs', params)!
return data
} }
// get_build_log returns a specific build log. // get_build_log returns a specific build log.
pub fn (c &Client) get_build_log(id int) !Response<BuildLog> { pub fn (c &Client) get_build_log(id int) !BuildLog {
data := c.send_request<BuildLog>(Method.get, '/api/v1/logs/$id', {})! data := c.send_request<BuildLog>(Method.get, '/api/v1/logs/$id', {})!
return data return data.data
} }
// get_build_log_content returns the contents of the build log file. // get_build_log_content returns the contents of the build log file.

View File

@ -2,7 +2,6 @@ module client
import models { Target, TargetFilter } import models { Target, TargetFilter }
import net.http { Method } import net.http { Method }
import web.response { Response }
// get_targets returns a list of targets, given a filter object. // get_targets returns a list of targets, given a filter object.
pub fn (c &Client) get_targets(filter TargetFilter) ![]Target { pub fn (c &Client) get_targets(filter TargetFilter) ![]Target {
@ -49,24 +48,24 @@ pub struct NewTarget {
} }
// add_target adds a new target to the server. // add_target adds a new target to the server.
pub fn (c &Client) add_target(t NewTarget) !Response<int> { pub fn (c &Client) add_target(t NewTarget) !int {
params := models.params_from<NewTarget>(t) params := models.params_from<NewTarget>(t)
data := c.send_request<int>(Method.post, '/api/v1/targets', params)! data := c.send_request<int>(Method.post, '/api/v1/targets', params)!
return data return data.data
} }
// remove_target removes the target with the given id from the server. // remove_target removes the target with the given id from the server.
pub fn (c &Client) remove_target(id int) !Response<string> { pub fn (c &Client) remove_target(id int) !string {
data := c.send_request<string>(Method.delete, '/api/v1/targets/$id', {})! data := c.send_request<string>(Method.delete, '/api/v1/targets/$id', {})!
return data return data.data
} }
// patch_target sends a PATCH request to the given target with the params as // patch_target sends a PATCH request to the given target with the params as
// payload. // payload.
pub fn (c &Client) patch_target(id int, params map[string]string) !Response<string> { pub fn (c &Client) patch_target(id int, params map[string]string) !string {
data := c.send_request<string>(Method.patch, '/api/v1/targets/$id', params)! data := c.send_request<string>(Method.patch, '/api/v1/targets/$id', params)!
return data return data.data
} }

View File

@ -183,15 +183,7 @@ fn print_log_list(logs []BuildLog, raw bool) ! {
// list prints a list of all build logs. // list prints a list of all build logs.
fn list(conf Config, filter BuildLogFilter, raw bool) ! { fn list(conf Config, filter BuildLogFilter, raw bool) ! {
c := client.new(conf.address, conf.api_key) c := client.new(conf.address, conf.api_key)
logs := c.get_build_logs(filter)!.data logs := c.get_build_logs(filter)!
print_log_list(logs, raw)!
}
// list prints a list of all build logs for a given target.
fn list_for_target(conf Config, target_id int, raw bool) ! {
c := client.new(conf.address, conf.api_key)
logs := c.get_build_logs_for_target(target_id)!.data
print_log_list(logs, raw)! print_log_list(logs, raw)!
} }
@ -199,7 +191,7 @@ fn list_for_target(conf Config, target_id int, raw bool) ! {
// info print the detailed info for a given build log. // info print the detailed info for a given build log.
fn info(conf Config, id int) ! { fn info(conf Config, id int) ! {
c := client.new(conf.address, conf.api_key) c := client.new(conf.address, conf.api_key)
log := c.get_build_log(id)!.data log := c.get_build_log(id)!
print(log) print(log)
} }

View File

@ -215,8 +215,7 @@ pub fn cmd() cli.Command {
} }
c := client.new(conf.address, conf.api_key) c := client.new(conf.address, conf.api_key)
res := c.queue_job(target_id, arch, force)! c.queue_job(target_id, arch, force)!
println(res.message)
} else { } else {
build(conf, target_id, force)! build(conf, target_id, force)!
} }
@ -245,23 +244,19 @@ fn list(conf Config, filter TargetFilter, raw bool) ! {
// add adds a new repository to the server's list. // add adds a new repository to the server's list.
fn add(conf Config, t &NewTarget, raw bool) ! { fn add(conf Config, t &NewTarget, raw bool) ! {
c := client.new(conf.address, conf.api_key) c := client.new(conf.address, conf.api_key)
res := c.add_target(t)! target_id := c.add_target(t)!
if raw { if raw {
println(res.data) println(target_id)
} else { } else {
println('Target added with id $res.data') println('Target added with id $target_id')
} }
} }
// remove removes a repository from the server's list. // remove removes a repository from the server's list.
fn remove(conf Config, id string) ! { fn remove(conf Config, id string) ! {
id_int := id.int() c := client.new(conf.address, conf.api_key)
c.remove_target(id.int())!
if id_int != 0 {
c := client.new(conf.address, conf.api_key)
c.remove_target(id_int)!
}
} }
// patch patches a given repository with the provided params. // patch patches a given repository with the provided params.
@ -274,22 +269,13 @@ fn patch(conf Config, id string, params map[string]string) ! {
} }
} }
id_int := id.int() c := client.new(conf.address, conf.api_key)
if id_int != 0 { c.patch_target(id.int(), params)!
c := client.new(conf.address, conf.api_key)
c.patch_target(id_int, params)!
}
} }
// info shows detailed information for a given repo. // info shows detailed information for a given repo.
fn info(conf Config, id string) ! { fn info(conf Config, id string) ! {
id_int := id.int()
if id_int == 0 {
return
}
c := client.new(conf.address, conf.api_key) c := client.new(conf.address, conf.api_key)
repo := c.get_target(id_int)! repo := c.get_target(id.int())!
println(repo) println(repo)
} }