diff --git a/Makefile b/Makefile index 69bd795..895d3fd 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ SRC_DIR := src SOURCES != find '$(SRC_DIR)' -iname '*.v' V_PATH ?= v -V := $(V_PATH) -showcc -gc boehm +V := $(V_PATH) -showcc -gc boehm -W all: vieter diff --git a/src/build/build.v b/src/build/build.v index 2ad70a6..734427d 100644 --- a/src/build/build.v +++ b/src/build/build.v @@ -21,8 +21,8 @@ const ( // system, install some necessary packages & creates a non-root user to run // makepkg with. The base image should be some Linux distribution that uses // Pacman as its package manager. -pub fn create_build_image(base_image string) ?string { - mut dd := docker.new_conn()? +pub fn create_build_image(base_image string) !string { + mut dd := docker.new_conn()! defer { dd.close() or {} @@ -57,15 +57,15 @@ pub fn create_build_image(base_image string) ?string { image_tag := if image_parts.len > 1 { image_parts[1] } else { 'latest' } // We pull the provided image - dd.pull_image(image_name, image_tag)? + dd.pull_image(image_name, image_tag)! - id := dd.container_create(c)?.id - // id := docker.create_container(c)? - dd.container_start(id)? + id := dd.container_create(c)!.id + // id := docker.create_container(c)! + dd.container_start(id)! // This loop waits until the container has stopped, so we can remove it after for { - data := dd.container_inspect(id)? + data := dd.container_inspect(id)! if !data.state.running { break @@ -79,8 +79,8 @@ pub fn create_build_image(base_image string) ?string { // TODO also add the base image's name into the image name to prevent // conflicts. tag := time.sys_mono_now().str() - image := dd.create_image_from_container(id, 'vieter-build', tag)? - dd.container_remove(id)? + image := dd.create_image_from_container(id, 'vieter-build', tag)! + dd.container_remove(id)! return image.id } @@ -96,8 +96,8 @@ pub: // build_target builds, packages & publishes a given Arch package based on the // provided target. The base image ID should be of an image previously created // by create_build_image. It returns the logs of the container. -pub fn build_target(address string, api_key string, base_image_id string, target &Target) ?BuildResult { - mut dd := docker.new_conn()? +pub fn build_target(address string, api_key string, base_image_id string, target &Target) !BuildResult { + mut dd := docker.new_conn()! defer { dd.close() or {} @@ -125,25 +125,25 @@ pub fn build_target(address string, api_key string, base_image_id string, target user: '0:0' } - id := dd.container_create(c)?.id - dd.container_start(id)? + id := dd.container_create(c)!.id + dd.container_start(id)! - mut data := dd.container_inspect(id)? + mut data := dd.container_inspect(id)! // This loop waits until the container has stopped, so we can remove it after for data.state.running { time.sleep(1 * time.second) - data = dd.container_inspect(id)? + data = dd.container_inspect(id)! } - mut logs_stream := dd.container_get_logs(id)? + mut logs_stream := dd.container_get_logs(id)! // Read in the entire stream mut logs_builder := strings.new_builder(10 * 1024) - util.reader_to_writer(mut logs_stream, mut logs_builder)? + util.reader_to_writer(mut logs_stream, mut logs_builder)! - dd.container_remove(id)? + dd.container_remove(id)! return BuildResult{ start_time: data.state.start_time diff --git a/src/client/client.v b/src/client/client.v index d68ff18..aa6094a 100644 --- a/src/client/client.v +++ b/src/client/client.v @@ -21,7 +21,7 @@ pub fn new(address string, api_key string) Client { // send_request_raw sends an HTTP request, returning the http.Response object. // It encodes the params so that they're safe to pass as HTTP query parameters. -fn (c &Client) send_request_raw(method Method, url string, params map[string]string, body string) ?http.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 { @@ -38,31 +38,33 @@ fn (c &Client) send_request_raw(method Method, url string, params map[string]str full_url = '$full_url?$params_str' } - mut req := http.new_request(method, full_url, body)? - req.add_custom_header('X-Api-Key', c.api_key)? + // Looking at the source code, this function doesn't actually fail, so I'm + // not sure why it returns an optional + mut req := http.new_request(method, full_url, body) or { return error('') } + req.add_custom_header('X-Api-Key', c.api_key)! - res := req.do()? + res := req.do()! 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 { +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 calls send_request_raw_response & parses its // output as a Response object. -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)? +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 } // send_request_raw_response returns the raw text response for an HTTP request. -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)? +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.body } diff --git a/src/client/logs.v b/src/client/logs.v index b414245..eaddc8c 100644 --- a/src/client/logs.v +++ b/src/client/logs.v @@ -6,40 +6,40 @@ import web.response { Response } import time // 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) !Response<[]BuildLog> { 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 } // 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> { +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)? + data := c.send_request<[]BuildLog>(Method.get, '/api/v1/logs', params)! return data } // get_build_log returns a specific build log. -pub fn (c &Client) get_build_log(id int) ?Response { - data := c.send_request(Method.get, '/api/v1/logs/$id', {})? +pub fn (c &Client) get_build_log(id int) !Response { + data := c.send_request(Method.get, '/api/v1/logs/$id', {})! return data } // get_build_log_content returns the contents of the build log file. -pub fn (c &Client) get_build_log_content(id int) ?string { - data := c.send_request_raw_response(Method.get, '/api/v1/logs/$id/content', {}, '')? +pub fn (c &Client) get_build_log_content(id int) !string { + data := c.send_request_raw_response(Method.get, '/api/v1/logs/$id/content', {}, '')! return data } // add_build_log adds a new build log to the server. -pub fn (c &Client) add_build_log(target_id int, start_time time.Time, end_time time.Time, arch string, exit_code int, content string) ?Response { +pub fn (c &Client) add_build_log(target_id int, start_time time.Time, end_time time.Time, arch string, exit_code int, content string) !Response { params := { 'target': target_id.str() 'startTime': start_time.unix_time().str() @@ -48,7 +48,7 @@ pub fn (c &Client) add_build_log(target_id int, start_time time.Time, end_time t 'exitCode': exit_code.str() } - data := c.send_request_with_body(Method.post, '/api/v1/logs', params, content)? + data := c.send_request_with_body(Method.post, '/api/v1/logs', params, content)! return data } diff --git a/src/client/targets.v b/src/client/targets.v index c5e44fe..fd4254c 100644 --- a/src/client/targets.v +++ b/src/client/targets.v @@ -5,21 +5,21 @@ import net.http { Method } import web.response { Response } // 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 { params := models.params_from(filter) - data := c.send_request<[]Target>(Method.get, '/api/v1/targets', params)? + data := c.send_request<[]Target>(Method.get, '/api/v1/targets', params)! return data.data } // get_all_targets retrieves *all* targs from the API using the default // limit. -pub fn (c &Client) get_all_targets() ?[]Target { +pub fn (c &Client) get_all_targets() ![]Target { mut targets := []Target{} mut offset := u64(0) for { - sub_targets := c.get_targets(offset: offset)? + sub_targets := c.get_targets(offset: offset)! if sub_targets.len == 0 { break @@ -34,8 +34,8 @@ pub fn (c &Client) get_all_targets() ?[]Target { } // get_target returns the target for a specific id. -pub fn (c &Client) get_target(id int) ?Target { - data := c.send_request(Method.get, '/api/v1/targets/$id', {})? +pub fn (c &Client) get_target(id int) !Target { + data := c.send_request(Method.get, '/api/v1/targets/$id', {})! return data.data } @@ -49,24 +49,24 @@ pub struct NewTarget { } // add_target adds a new target to the server. -pub fn (c &Client) add_target(t NewTarget) ?Response { +pub fn (c &Client) add_target(t NewTarget) !Response { params := models.params_from(t) - data := c.send_request(Method.post, '/api/v1/targets', params)? + data := c.send_request(Method.post, '/api/v1/targets', params)! return data } // remove_target removes the target with the given id from the server. -pub fn (c &Client) remove_target(id int) ?Response { - data := c.send_request(Method.delete, '/api/v1/targets/$id', {})? +pub fn (c &Client) remove_target(id int) !Response { + data := c.send_request(Method.delete, '/api/v1/targets/$id', {})! return data } // patch_target sends a PATCH request to the given target with the params as // payload. -pub fn (c &Client) patch_target(id int, params map[string]string) ?Response { - data := c.send_request(Method.patch, '/api/v1/targets/$id', params)? +pub fn (c &Client) patch_target(id int, params map[string]string) !Response { + data := c.send_request(Method.patch, '/api/v1/targets/$id', params)! return data } diff --git a/src/console/aur/aur.v b/src/console/aur/aur.v index c98f8e6..6a061dd 100644 --- a/src/console/aur/aur.v +++ b/src/console/aur/aur.v @@ -21,12 +21,12 @@ pub fn cmd() cli.Command { name: 'search' description: 'Search for packages.' required_args: 1 - execute: fn (cmd cli.Command) ? { + execute: fn (cmd cli.Command) ! { c := aur.new() - pkgs := c.search(cmd.args[0])? + pkgs := c.search(cmd.args[0])! data := pkgs.map([it.name, it.description]) - println(console.pretty_table(['name', 'description'], data)?) + println(console.pretty_table(['name', 'description'], data)!) } }, cli.Command{ @@ -34,12 +34,12 @@ pub fn cmd() cli.Command { usage: 'repo pkg-name [pkg-name...]' description: 'Add the given AUR package(s) to Vieter. Non-existent packages will be silently ignored.' required_args: 2 - execute: fn (cmd cli.Command) ? { - config_file := cmd.flags.get_string('config-file')? - conf := vconf.load(prefix: 'VIETER_', default_path: config_file)? + execute: fn (cmd cli.Command) ! { + config_file := cmd.flags.get_string('config-file')! + conf := vconf.load(prefix: 'VIETER_', default_path: config_file)! c := aur.new() - pkgs := c.info(cmd.args[1..])? + pkgs := c.info(cmd.args[1..])! vc := client.new(conf.address, conf.api_key) diff --git a/src/console/console.v b/src/console/console.v index caf4cca..5c40de8 100644 --- a/src/console/console.v +++ b/src/console/console.v @@ -13,7 +13,7 @@ pub fn tabbed_table(data [][]string) string { // pretty_table converts a list of string data into a pretty table. Many thanks // to @hungrybluedev in the Vlang Discord for providing this code! // https://ptb.discord.com/channels/592103645835821068/592106336838352923/970278787143045192 -pub fn pretty_table(header []string, data [][]string) ?string { +pub fn pretty_table(header []string, data [][]string) !string { column_count := header.len mut column_widths := []int{len: column_count, init: header[it].len} @@ -26,7 +26,7 @@ pub fn pretty_table(header []string, data [][]string) ?string { } } - single_line_length := arrays.sum(column_widths)? + (column_count + 1) * 3 - 4 + single_line_length := arrays.sum(column_widths)! + (column_count + 1) * 3 - 4 horizontal_line := '+' + strings.repeat(`-`, single_line_length) + '+' mut buffer := strings.new_builder(data.len * single_line_length) @@ -64,12 +64,12 @@ pub fn pretty_table(header []string, data [][]string) ?string { // export_man_pages recursively generates all man pages for the given // cli.Command & writes them to the given directory. -pub fn export_man_pages(cmd cli.Command, path string) ? { +pub fn export_man_pages(cmd cli.Command, path string) ! { man := cmd.manpage() os.write_file(os.join_path_single(path, cmd.full_name().replace(' ', '-') + '.1'), - man)? + man)! for sub_cmd in cmd.commands { - export_man_pages(sub_cmd, path)? + export_man_pages(sub_cmd, path)! } } diff --git a/src/console/logs/logs.v b/src/console/logs/logs.v index 41830c2..6d5ffad 100644 --- a/src/console/logs/logs.v +++ b/src/console/logs/logs.v @@ -63,30 +63,30 @@ pub fn cmd() cli.Command { flag: cli.FlagType.string }, ] - execute: fn (cmd cli.Command) ? { - config_file := cmd.flags.get_string('config-file')? - conf := vconf.load(prefix: 'VIETER_', default_path: config_file)? + execute: fn (cmd cli.Command) ! { + config_file := cmd.flags.get_string('config-file')! + conf := vconf.load(prefix: 'VIETER_', default_path: config_file)! mut filter := BuildLogFilter{} - limit := cmd.flags.get_int('limit')? + limit := cmd.flags.get_int('limit')! if limit != 0 { filter.limit = u64(limit) } - offset := cmd.flags.get_int('offset')? + offset := cmd.flags.get_int('offset')! if offset != 0 { filter.offset = u64(offset) } - target_id := cmd.flags.get_int('target')? + target_id := cmd.flags.get_int('target')! if target_id != 0 { filter.target = target_id } tz_offset := time.offset() - if cmd.flags.get_bool('today')? { + if cmd.flags.get_bool('today')! { today := time.now() filter.after = time.new_time(time.Time{ @@ -98,12 +98,12 @@ pub fn cmd() cli.Command { } // The -today flag overwrites any of the other date flags. else { - day_str := cmd.flags.get_string('day')? - before_str := cmd.flags.get_string('before')? - after_str := cmd.flags.get_string('after')? + day_str := cmd.flags.get_string('day')! + before_str := cmd.flags.get_string('before')! + after_str := cmd.flags.get_string('after')! if day_str != '' { - day := time.parse_rfc3339(day_str)? + day := time.parse_rfc3339(day_str)! day_utc := time.new_time(time.Time{ year: day.year month: day.month @@ -118,24 +118,24 @@ pub fn cmd() cli.Command { filter.before = day_utc.add_days(1) } else { if before_str != '' { - filter.before = time.parse(before_str)?.add_seconds(-tz_offset) + filter.before = time.parse(before_str)!.add_seconds(-tz_offset) } if after_str != '' { - filter.after = time.parse(after_str)?.add_seconds(-tz_offset) + filter.after = time.parse(after_str)!.add_seconds(-tz_offset) } } } - if cmd.flags.get_bool('failed')? { + if cmd.flags.get_bool('failed')! { filter.exit_codes = [ '!0', ] } - raw := cmd.flags.get_bool('raw')? + raw := cmd.flags.get_bool('raw')! - list(conf, filter, raw)? + list(conf, filter, raw)! } }, cli.Command{ @@ -143,12 +143,12 @@ pub fn cmd() cli.Command { 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 := vconf.load(prefix: 'VIETER_', default_path: config_file)? + execute: fn (cmd cli.Command) ! { + config_file := cmd.flags.get_string('config-file')! + conf := vconf.load(prefix: 'VIETER_', default_path: config_file)! id := cmd.args[0].int() - info(conf, id)? + info(conf, id)! } }, cli.Command{ @@ -156,12 +156,12 @@ pub fn cmd() cli.Command { 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 := vconf.load(prefix: 'VIETER_', default_path: config_file)? + execute: fn (cmd cli.Command) ! { + config_file := cmd.flags.get_string('config-file')! + conf := vconf.load(prefix: 'VIETER_', default_path: config_file)! id := cmd.args[0].int() - content(conf, id)? + content(conf, id)! } }, ] @@ -169,46 +169,46 @@ pub fn cmd() cli.Command { } // print_log_list prints a list of logs. -fn print_log_list(logs []BuildLog, raw bool) ? { +fn print_log_list(logs []BuildLog, raw bool) ! { data := logs.map([it.id.str(), it.target_id.str(), it.start_time.local().str(), it.exit_code.str()]) if raw { println(console.tabbed_table(data)) } else { - println(console.pretty_table(['id', 'target', 'start time', 'exit code'], data)?) + println(console.pretty_table(['id', 'target', 'start time', 'exit code'], data)!) } } // 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) - logs := c.get_build_logs(filter)?.data + logs := c.get_build_logs(filter)!.data - print_log_list(logs, raw)? + 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) ? { +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 + logs := c.get_build_logs_for_target(target_id)!.data - print_log_list(logs, raw)? + print_log_list(logs, raw)! } // 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) - log := c.get_build_log(id)?.data + log := c.get_build_log(id)!.data print(log) } // content outputs the contents of the log file for a given build log to // stdout. -fn content(conf Config, id int) ? { +fn content(conf Config, id int) ! { c := client.new(conf.address, conf.api_key) - content := c.get_build_log_content(id)? + content := c.get_build_log_content(id)! println(content) } diff --git a/src/console/man/man.v b/src/console/man/man.v index d91a140..22cb5f7 100644 --- a/src/console/man/man.v +++ b/src/console/man/man.v @@ -11,11 +11,11 @@ pub fn cmd() cli.Command { description: 'Generate all man pages & save them in the given directory.' usage: 'dir' required_args: 1 - execute: fn (cmd cli.Command) ? { + execute: fn (cmd cli.Command) ! { root := cmd.root() - os.mkdir_all(cmd.args[0])? + os.mkdir_all(cmd.args[0])! - console.export_man_pages(root, cmd.args[0])? + console.export_man_pages(root, cmd.args[0])! } } } diff --git a/src/console/schedule/schedule.v b/src/console/schedule/schedule.v index 8fceddd..7ce0516 100644 --- a/src/console/schedule/schedule.v +++ b/src/console/schedule/schedule.v @@ -18,11 +18,11 @@ pub fn cmd() cli.Command { default_value: ['5'] }, ] - execute: fn (cmd cli.Command) ? { - ce := parse_expression(cmd.args.join(' '))? - count := cmd.flags.get_int('count')? + execute: fn (cmd cli.Command) ! { + ce := parse_expression(cmd.args.join(' '))! + count := cmd.flags.get_int('count')! - for t in ce.next_n(time.now(), count)? { + for t in ce.next_n(time.now(), count)! { println(t) } } diff --git a/src/console/targets/build.v b/src/console/targets/build.v index 6337aa3..83ebde2 100644 --- a/src/console/targets/build.v +++ b/src/console/targets/build.v @@ -6,29 +6,29 @@ import os import build // build locally builds the target with the given id. -fn build(conf Config, target_id int) ? { +fn build(conf Config, target_id int) ! { c := client.new(conf.address, conf.api_key) - target := c.get_target(target_id)? + target := c.get_target(target_id)! build_arch := os.uname().machine println('Creating base image...') - image_id := build.create_build_image(conf.base_image)? + image_id := build.create_build_image(conf.base_image)! println('Running build...') - res := build.build_target(conf.address, conf.api_key, image_id, target)? + res := build.build_target(conf.address, conf.api_key, image_id, target)! println('Removing build image...') - mut dd := docker.new_conn()? + mut dd := docker.new_conn()! defer { dd.close() or {} } - dd.remove_image(image_id)? + dd.remove_image(image_id)! println('Uploading logs to Vieter...') c.add_build_log(target.id, res.start_time, res.end_time, build_arch, res.exit_code, - res.logs)? + res.logs)! } diff --git a/src/console/targets/targets.v b/src/console/targets/targets.v index 5640011..774a129 100644 --- a/src/console/targets/targets.v +++ b/src/console/targets/targets.v @@ -39,30 +39,30 @@ pub fn cmd() cli.Command { flag: cli.FlagType.string }, ] - execute: fn (cmd cli.Command) ? { - config_file := cmd.flags.get_string('config-file')? - conf := vconf.load(prefix: 'VIETER_', default_path: config_file)? + execute: fn (cmd cli.Command) ! { + config_file := cmd.flags.get_string('config-file')! + conf := vconf.load(prefix: 'VIETER_', default_path: config_file)! mut filter := TargetFilter{} - limit := cmd.flags.get_int('limit')? + limit := cmd.flags.get_int('limit')! if limit != 0 { filter.limit = u64(limit) } - offset := cmd.flags.get_int('offset')? + offset := cmd.flags.get_int('offset')! if offset != 0 { filter.offset = u64(offset) } - repo := cmd.flags.get_string('repo')? + repo := cmd.flags.get_string('repo')! if repo != '' { filter.repo = repo } - raw := cmd.flags.get_bool('raw')? + raw := cmd.flags.get_bool('raw')! - list(conf, filter, raw)? + list(conf, filter, raw)! } }, cli.Command{ @@ -83,20 +83,20 @@ pub fn cmd() cli.Command { flag: cli.FlagType.string }, ] - execute: fn (cmd cli.Command) ? { - config_file := cmd.flags.get_string('config-file')? - conf := vconf.load(prefix: 'VIETER_', default_path: config_file)? + execute: fn (cmd cli.Command) ! { + config_file := cmd.flags.get_string('config-file')! + conf := vconf.load(prefix: 'VIETER_', default_path: config_file)! t := NewTarget{ - kind: cmd.flags.get_string('kind')? + kind: cmd.flags.get_string('kind')! url: cmd.args[0] repo: cmd.args[1] branch: cmd.flags.get_string('branch') or { '' } } - raw := cmd.flags.get_bool('raw')? + raw := cmd.flags.get_bool('raw')! - add(conf, t, raw)? + add(conf, t, raw)! } }, cli.Command{ @@ -104,11 +104,11 @@ pub fn cmd() cli.Command { required_args: 1 usage: 'id' description: 'Remove a target that matches the given id.' - execute: fn (cmd cli.Command) ? { - config_file := cmd.flags.get_string('config-file')? - conf := vconf.load(prefix: 'VIETER_', default_path: config_file)? + execute: fn (cmd cli.Command) ! { + config_file := cmd.flags.get_string('config-file')! + conf := vconf.load(prefix: 'VIETER_', default_path: config_file)! - remove(conf, cmd.args[0])? + remove(conf, cmd.args[0])! } }, cli.Command{ @@ -116,11 +116,11 @@ pub fn cmd() cli.Command { required_args: 1 usage: 'id' description: 'Show detailed information for the target matching the id.' - execute: fn (cmd cli.Command) ? { - config_file := cmd.flags.get_string('config-file')? - conf := vconf.load(prefix: 'VIETER_', default_path: config_file)? + execute: fn (cmd cli.Command) ! { + config_file := cmd.flags.get_string('config-file')! + conf := vconf.load(prefix: 'VIETER_', default_path: config_file)! - info(conf, cmd.args[0])? + info(conf, cmd.args[0])! } }, cli.Command{ @@ -160,9 +160,9 @@ pub fn cmd() cli.Command { flag: cli.FlagType.string }, ] - execute: fn (cmd cli.Command) ? { - config_file := cmd.flags.get_string('config-file')? - conf := vconf.load(prefix: 'VIETER_', default_path: config_file)? + execute: fn (cmd cli.Command) ! { + config_file := cmd.flags.get_string('config-file')! + conf := vconf.load(prefix: 'VIETER_', default_path: config_file)! found := cmd.flags.get_all_found() @@ -170,11 +170,11 @@ pub fn cmd() cli.Command { for f in found { if f.name != 'config-file' { - params[f.name] = f.get_string()? + params[f.name] = f.get_string()! } } - patch(conf, cmd.args[0], params)? + patch(conf, cmd.args[0], params)! } }, cli.Command{ @@ -182,11 +182,11 @@ pub fn cmd() cli.Command { required_args: 1 usage: 'id' description: 'Build the target with the given id & publish it.' - execute: fn (cmd cli.Command) ? { - config_file := cmd.flags.get_string('config-file')? - conf := vconf.load(prefix: 'VIETER_', default_path: config_file)? + execute: fn (cmd cli.Command) ! { + config_file := cmd.flags.get_string('config-file')! + conf := vconf.load(prefix: 'VIETER_', default_path: config_file)! - build(conf, cmd.args[0].int())? + build(conf, cmd.args[0].int())! } }, ] @@ -197,22 +197,22 @@ pub fn cmd() cli.Command { // ID. If multiple or none are found, an error is raised. // list prints out a list of all repositories. -fn list(conf Config, filter TargetFilter, raw bool) ? { +fn list(conf Config, filter TargetFilter, raw bool) ! { c := client.new(conf.address, conf.api_key) - repos := c.get_targets(filter)? + repos := c.get_targets(filter)! data := repos.map([it.id.str(), it.kind, it.url, it.repo]) if raw { println(console.tabbed_table(data)) } else { - println(console.pretty_table(['id', 'kind', 'url', 'repo'], data)?) + println(console.pretty_table(['id', 'kind', 'url', 'repo'], data)!) } } // 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) - res := c.add_target(t)? + res := c.add_target(t)! if raw { println(res.data) @@ -222,18 +222,18 @@ fn add(conf Config, t &NewTarget, raw bool) ? { } // 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() if id_int != 0 { c := client.new(conf.address, conf.api_key) - res := c.remove_target(id_int)? + res := c.remove_target(id_int)! println(res.message) } } // patch patches a given repository with the provided params. -fn patch(conf Config, id string, params map[string]string) ? { +fn patch(conf Config, id string, params map[string]string) ! { // We check the cron expression first because it's useless to send an // invalid one to the server. if 'schedule' in params && params['schedule'] != '' { @@ -245,14 +245,14 @@ fn patch(conf Config, id string, params map[string]string) ? { id_int := id.int() if id_int != 0 { c := client.new(conf.address, conf.api_key) - res := c.patch_target(id_int, params)? + res := c.patch_target(id_int, params)! println(res.message) } } // 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 { @@ -260,6 +260,6 @@ fn info(conf Config, id string) ? { } c := client.new(conf.address, conf.api_key) - repo := c.get_target(id_int)? + repo := c.get_target(id_int)! println(repo) } diff --git a/src/cron/cli.v b/src/cron/cli.v index 4d95833..0d7a042 100644 --- a/src/cron/cli.v +++ b/src/cron/cli.v @@ -22,11 +22,11 @@ pub fn cmd() cli.Command { return cli.Command{ name: 'cron' description: 'Start the cron service that periodically runs builds.' - execute: fn (cmd cli.Command) ? { - config_file := cmd.flags.get_string('config-file')? - conf := vconf.load(prefix: 'VIETER_', default_path: config_file)? + execute: fn (cmd cli.Command) ! { + config_file := cmd.flags.get_string('config-file')! + conf := vconf.load(prefix: 'VIETER_', default_path: config_file)! - cron(conf)? + cron(conf)! } } } diff --git a/src/cron/cron.v b/src/cron/cron.v index 5f128cf..f1d6b7b 100644 --- a/src/cron/cron.v +++ b/src/cron/cron.v @@ -8,7 +8,7 @@ import os const log_file_name = 'vieter.cron.log' // cron starts a cron daemon & starts periodically scheduling builds. -pub fn cron(conf Config) ? { +pub fn cron(conf Config) ! { // Configure logger log_level := log.level_from_tag(conf.log_level) or { return error('Invalid log level. The allowed values are FATAL, ERROR, WARN, INFO & DEBUG.') @@ -27,7 +27,7 @@ pub fn cron(conf Config) ? { } mut d := daemon.init_daemon(logger, conf.address, conf.api_key, conf.base_image, ce, - conf.max_concurrent_builds, conf.api_update_frequency, conf.image_rebuild_frequency)? + conf.max_concurrent_builds, conf.api_update_frequency, conf.image_rebuild_frequency)! d.run() } diff --git a/src/cron/daemon/daemon.v b/src/cron/daemon/daemon.v index 934d35a..8c6516c 100644 --- a/src/cron/daemon/daemon.v +++ b/src/cron/daemon/daemon.v @@ -53,7 +53,7 @@ mut: // init_daemon initializes a new Daemon object. It renews the targets & // populates the build queue for the first time. -pub fn init_daemon(logger log.Log, address string, api_key string, base_image string, global_schedule CronExpression, max_concurrent_builds int, api_update_frequency int, image_rebuild_frequency int) ?Daemon { +pub fn init_daemon(logger log.Log, address string, api_key string, base_image string, global_schedule CronExpression, max_concurrent_builds int, api_update_frequency int, image_rebuild_frequency int) !Daemon { mut d := Daemon{ client: client.new(address, api_key) base_image: base_image @@ -207,7 +207,7 @@ fn (mut d Daemon) renew_queue() { // For some reason, using // ```v - // for d.queue.len() > 0 && d.queue.peek() ?.timestamp < now { + // for d.queue.len() > 0 && d.queue.peek() !.timestamp < now { //``` // here causes the function to prematurely just exit, without any errors or anything, very weird // https://github.com/vlang/v/issues/14042 diff --git a/src/cron/daemon/log.v b/src/cron/daemon/log.v index 003898b..95a50e7 100644 --- a/src/cron/daemon/log.v +++ b/src/cron/daemon/log.v @@ -3,33 +3,33 @@ module daemon import log // log reate a log message with the given level -pub fn (mut d Daemon) log(msg &string, level log.Level) { +pub fn (mut d Daemon) log(msg string, level log.Level) { lock d.logger { d.logger.send_output(msg, level) } } // lfatal create a log message with the fatal level -pub fn (mut d Daemon) lfatal(msg &string) { +pub fn (mut d Daemon) lfatal(msg string) { d.log(msg, log.Level.fatal) } // lerror create a log message with the error level -pub fn (mut d Daemon) lerror(msg &string) { +pub fn (mut d Daemon) lerror(msg string) { d.log(msg, log.Level.error) } // lwarn create a log message with the warn level -pub fn (mut d Daemon) lwarn(msg &string) { +pub fn (mut d Daemon) lwarn(msg string) { d.log(msg, log.Level.warn) } // linfo create a log message with the info level -pub fn (mut d Daemon) linfo(msg &string) { +pub fn (mut d Daemon) linfo(msg string) { d.log(msg, log.Level.info) } // ldebug create a log message with the debug level -pub fn (mut d Daemon) ldebug(msg &string) { +pub fn (mut d Daemon) ldebug(msg string) { d.log(msg, log.Level.debug) } diff --git a/src/cron/expression/expression.v b/src/cron/expression/expression.v index 17d2dde..438805d 100644 --- a/src/cron/expression/expression.v +++ b/src/cron/expression/expression.v @@ -12,7 +12,7 @@ pub struct CronExpression { // next calculates the earliest time this cron expression is valid. It will // always pick a moment in the future, even if ref matches completely up to the // minute. This function conciously does not take gap years into account. -pub fn (ce &CronExpression) next(ref time.Time) ?time.Time { +pub fn (ce &CronExpression) next(ref time.Time) !time.Time { // If the given ref matches the next cron occurence up to the minute, it // will return that value. Because we always want to return a value in the // future, we artifically shift the ref 60 seconds to make sure we always @@ -117,19 +117,19 @@ pub fn (ce &CronExpression) next(ref time.Time) ?time.Time { // next_from_now returns the result of ce.next(ref) where ref is the result of // time.now(). -pub fn (ce &CronExpression) next_from_now() ?time.Time { +pub fn (ce &CronExpression) next_from_now() !time.Time { return ce.next(time.now()) } // next_n returns the n next occurences of the expression, given a starting // time. -pub fn (ce &CronExpression) next_n(ref time.Time, n int) ?[]time.Time { +pub fn (ce &CronExpression) next_n(ref time.Time, n int) ![]time.Time { mut times := []time.Time{cap: n} - times << ce.next(ref)? + times << ce.next(ref)! for i in 1 .. n { - times << ce.next(times[i - 1])? + times << ce.next(times[i - 1])! } return times @@ -137,7 +137,7 @@ pub fn (ce &CronExpression) next_n(ref time.Time, n int) ?[]time.Time { // parse_range parses a given string into a range of sorted integers, if // possible. -fn parse_range(s string, min int, max int, mut bitv []bool) ? { +fn parse_range(s string, min int, max int, mut bitv []bool) ! { mut start := min mut end := max mut interval := 1 @@ -228,11 +228,11 @@ fn bitv_to_ints(bitv []bool, min int) []int { // parse_part parses a given part of a cron expression & returns the // corresponding array of ints. -fn parse_part(s string, min int, max int) ?[]int { +fn parse_part(s string, min int, max int) ![]int { mut bitv := []bool{len: max - min + 1, init: false} for range in s.split(',') { - parse_range(range, min, max, mut bitv)? + parse_range(range, min, max, mut bitv)! } return bitv_to_ints(bitv, min) @@ -240,7 +240,7 @@ fn parse_part(s string, min int, max int) ?[]int { // parse_expression parses an entire cron expression string into a // CronExpression object, if possible. -pub fn parse_expression(exp string) ?CronExpression { +pub fn parse_expression(exp string) !CronExpression { // The filter allows for multiple spaces between parts mut parts := exp.split(' ').filter(it != '') diff --git a/src/package/package.v b/src/package/package.v index 9eaf5a2..aadf6f2 100644 --- a/src/package/package.v +++ b/src/package/package.v @@ -43,12 +43,12 @@ pub mut: } // checksum calculates the sha256 hash of the package -pub fn (p &Pkg) checksum() ?string { +pub fn (p &Pkg) checksum() !string { return util.hash_file(p.path) } // parse_pkg_info_string parses a PkgInfo object from a string -fn parse_pkg_info_string(pkg_info_str &string) ?PkgInfo { +fn parse_pkg_info_string(pkg_info_str &string) !PkgInfo { mut pkg_info := PkgInfo{} // Iterate over the entire string @@ -101,7 +101,7 @@ fn parse_pkg_info_string(pkg_info_str &string) ?PkgInfo { // read_pkg_archive extracts the file list & .PKGINFO contents from an archive // NOTE: this command only supports zstd-, xz- & gzip-compressed tarballs. -pub fn read_pkg_archive(pkg_path string) ?Pkg { +pub fn read_pkg_archive(pkg_path string) !Pkg { if !os.is_file(pkg_path) { return error("'$pkg_path' doesn't exist or isn't a file.") } @@ -159,7 +159,7 @@ pub fn read_pkg_archive(pkg_path string) ?Pkg { pkg_text := unsafe { buf.vstring_with_len(size).clone() } - pkg_info = parse_pkg_info_string(pkg_text)? + pkg_info = parse_pkg_info_string(pkg_text)! } else { C.archive_read_data_skip(a) } @@ -201,7 +201,7 @@ pub fn (pkg &Pkg) filename() string { } // to_desc returns a desc file valid string representation -pub fn (pkg &Pkg) to_desc() ?string { +pub fn (pkg &Pkg) to_desc() !string { p := pkg.info // filename @@ -222,7 +222,7 @@ pub fn (pkg &Pkg) to_desc() ?string { desc += format_entry('CSIZE', p.csize.str()) desc += format_entry('ISIZE', p.size.str()) - sha256sum := pkg.checksum()? + sha256sum := pkg.checksum()! desc += format_entry('SHA256SUM', sha256sum) diff --git a/src/server/cli.v b/src/server/cli.v index 6fd09c5..26ee0f1 100644 --- a/src/server/cli.v +++ b/src/server/cli.v @@ -18,11 +18,11 @@ pub fn cmd() cli.Command { return cli.Command{ name: 'server' description: 'Start the Vieter server.' - execute: fn (cmd cli.Command) ? { - config_file := cmd.flags.get_string('config-file')? - conf := vconf.load(prefix: 'VIETER_', default_path: config_file)? + execute: fn (cmd cli.Command) ! { + config_file := cmd.flags.get_string('config-file')! + conf := vconf.load(prefix: 'VIETER_', default_path: config_file)! - server(conf)? + server(conf)! } } } diff --git a/src/server/server.v b/src/server/server.v index 9903cea..d5f6135 100644 --- a/src/server/server.v +++ b/src/server/server.v @@ -24,7 +24,7 @@ pub mut: } // server starts the web server & starts listening for requests -pub fn server(conf Config) ? { +pub fn server(conf Config) ! { // Prevent using 'any' as the default arch if conf.default_arch == 'any' { util.exit_with_message(1, "'any' is not allowed as the value for default_arch.") diff --git a/src/util/stream.v b/src/util/stream.v index 06397aa..15cc618 100644 --- a/src/util/stream.v +++ b/src/util/stream.v @@ -5,7 +5,7 @@ import io import os // reader_to_writer tries to consume the entire reader & write it to the writer. -pub fn reader_to_writer(mut reader io.Reader, mut writer io.Writer) ? { +pub fn reader_to_writer(mut reader io.Reader, mut writer io.Writer) ! { mut buf := []u8{len: 10 * 1024} for { @@ -21,8 +21,8 @@ pub fn reader_to_writer(mut reader io.Reader, mut writer io.Writer) ? { } // reader_to_file writes the contents of a BufferedReader to a file -pub fn reader_to_file(mut reader io.BufferedReader, length int, path string) ? { - mut file := os.create(path)? +pub fn reader_to_file(mut reader io.BufferedReader, length int, path string) ! { + mut file := os.create(path)! defer { file.close() } @@ -69,11 +69,11 @@ pub fn match_array_in_array(a1 []T, a2 []T) int { // read_until_separator consumes an io.Reader until it encounters some // separator array. The data read is stored inside the provided res array. -pub fn read_until_separator(mut reader io.Reader, mut res []u8, sep []u8) ? { +pub fn read_until_separator(mut reader io.Reader, mut res []u8, sep []u8) ! { mut buf := []u8{len: sep.len} for { - c := reader.read(mut buf)? + c := reader.read(mut buf)! res << buf[..c] match_len := match_array_in_array(buf[..c], sep) @@ -84,7 +84,7 @@ pub fn read_until_separator(mut reader io.Reader, mut res []u8, sep []u8) ? { if match_len > 0 { match_left := sep.len - match_len - c2 := reader.read(mut buf[..match_left])? + c2 := reader.read(mut buf[..match_left])! res << buf[..c2] if buf[..c2] == sep[match_len..] { diff --git a/src/util/util.v b/src/util/util.v index 4cd374e..213104c 100644 --- a/src/util/util.v +++ b/src/util/util.v @@ -23,7 +23,7 @@ pub fn exit_with_message(code int, msg string) { } // hash_file returns the sha256 hash of a given file -pub fn hash_file(path &string) ?string { +pub fn hash_file(path &string) !string { file := os.open(path) or { return error('Failed to open file.') } mut sha256sum := sha256.new() @@ -39,7 +39,7 @@ pub fn hash_file(path &string) ?string { // This function never actually fails, but returns an option to follow // the Writer interface. - sha256sum.write(buf[..bytes_read])? + sha256sum.write(buf[..bytes_read])! } return sha256sum.checksum().hex() diff --git a/src/web/logging.v b/src/web/logging.v index fc697ff..12b07d7 100644 --- a/src/web/logging.v +++ b/src/web/logging.v @@ -3,33 +3,33 @@ module web import log // log reate a log message with the given level -pub fn (mut ctx Context) log(msg &string, level log.Level) { +pub fn (mut ctx Context) log(msg string, level log.Level) { lock ctx.logger { ctx.logger.send_output(msg, level) } } // lfatal create a log message with the fatal level -pub fn (mut ctx Context) lfatal(msg &string) { +pub fn (mut ctx Context) lfatal(msg string) { ctx.log(msg, log.Level.fatal) } // lerror create a log message with the error level -pub fn (mut ctx Context) lerror(msg &string) { +pub fn (mut ctx Context) lerror(msg string) { ctx.log(msg, log.Level.error) } // lwarn create a log message with the warn level -pub fn (mut ctx Context) lwarn(msg &string) { +pub fn (mut ctx Context) lwarn(msg string) { ctx.log(msg, log.Level.warn) } // linfo create a log message with the info level -pub fn (mut ctx Context) linfo(msg &string) { +pub fn (mut ctx Context) linfo(msg string) { ctx.log(msg, log.Level.info) } // ldebug create a log message with the debug level -pub fn (mut ctx Context) ldebug(msg &string) { +pub fn (mut ctx Context) ldebug(msg string) { ctx.log(msg, log.Level.debug) }