Current section
Files
Jump to
Current section
Files
src/go_over.gleam
import gleam/function
import gleam/int
import gleam/io
import gleam/json
import gleam/list
import gleam/option.{None, Some}
import gleam/string
import go_over/advisories/advisories
import go_over/config.{type Config, Config}
import go_over/packages.{type Package}
import go_over/retired/outdated
import go_over/retired/retired
import go_over/util/constants
import go_over/util/print
import go_over/util/spinner
import go_over/warning.{
type Warning, Direct, Indirect, Retired, Vulnerable, Warning,
}
import gxyz/gxyz_function
import gxyz/gxyz_tuple
import shellout
import simplifile
fn get_vulnerable_packages(pkgs: List(Package), conf: Config) -> List(Warning) {
advisories.check_for_advisories(pkgs, conf.force, conf.verbose)
|> list.map(fn(p) {
gxyz_tuple.map2_1(p, config.filter_advisory_ids(conf, _))
})
|> list.filter(fn(p) { gxyz_tuple.at2_1(p) == [] })
|> list.flat_map(gxyz_tuple.apply_from2(_, warning.adv_to_warning))
}
fn get_retired_packages(pkgs: List(Package), conf: Config) -> List(Warning) {
pkgs
|> list.map(fn(pkg) {
retired.check_retired(pkg, conf.force, conf.verbose)
|> option.map(fn(ret) { #(pkg, ret) })
})
|> option.values()
|> list.map(gxyz_tuple.apply_from2(_, warning.retired_to_warning))
}
fn get_outdated_packages(pkgs: List(Package), conf: Config) -> List(Warning) {
pkgs
|> list.map(fn(pkg) {
case outdated.check_outdated(pkg, conf.force, conf.verbose) {
Some(ret) -> Some(#(pkg, ret))
None -> None
}
})
|> option.values()
|> list.map(gxyz_tuple.apply_from2(_, warning.outdated_to_warning))
}
fn print_warnings_count(vulns: List(Warning)) -> Nil {
{
"⛔ "
<> int.to_string(list.length(vulns))
<> " WARNING(s) FOUND!"
<> constants.long_ass_dashes
}
|> io.print_error
}
fn print_warnings(vulns: List(Warning), conf: Config) -> Nil {
case conf.format {
config.Minimal ->
vulns
|> function.tap(print_warnings_count)
|> list.map(warning.format_as_string_minimal)
|> string.join("")
|> io.print_error()
config.JSON ->
vulns
|> list.map(warning.format_as_json)
|> json.preprocessed_array()
|> json.to_string()
|> io.print_error()
_ ->
vulns
|> function.tap(print_warnings_count)
|> list.map(warning.format_as_string)
|> string.join(constants.long_ass_dashes)
|> io.print_error()
}
shellout.exit(1)
}
pub fn main() {
let conf = case
config.spin_up(config.read_config("gleam.toml"), shellout.arguments())
{
Error(e) -> {
io.println_error(e)
shellout.exit(0)
panic as "Unreachable, please create an issue in https://github.com/bwireman/go-over if you see this"
}
Ok(conf) -> conf
}
let spinner = spinner.new_spinner("Let's do this!", conf.verbose)
gxyz_function.ignore_result(
conf.force,
gxyz_function.freeze1(simplifile.delete, constants.go_over_path()),
)
spinner.set_text_spinner(spinner, "Reading manifest", conf.verbose)
let pkgs =
packages.read_manifest("manifest.toml")
|> config.filter_dev_dependencies(conf, _)
|> config.filter_packages(conf, _)
|> config.filter_indirect(conf, _)
spinner.set_text_spinner(
spinner,
"Checking packages: " <> print.raw("vulnerable", "red"),
conf.verbose,
)
let vulnerable_packages = get_vulnerable_packages(pkgs, conf)
spinner.set_text_spinner(
spinner,
"Checking packages: " <> print.raw("retired", "yellow"),
conf.verbose,
)
let retired_packages = get_retired_packages(pkgs, conf)
spinner.set_text_spinner(
spinner,
"Checking packages: " <> print.raw("outdated", "brightmagenta"),
conf.verbose,
)
let outdated_packages =
gxyz_function.iff(
conf.outdated,
gxyz_function.freeze2(get_outdated_packages, pkgs, conf),
[],
)
gxyz_function.iff_nil(
conf.fake,
gxyz_function.freeze2(print_warnings, example_warnings, conf),
)
spinner.set_text_spinner(spinner, "Filtering warnings", conf.verbose)
let warnings =
list.append(retired_packages, vulnerable_packages)
|> list.append(outdated_packages)
|> config.filter_severity(conf, _)
spinner.stop_spinner(spinner)
case warnings {
[] -> print.success("✅ No warnings found!")
vulns -> print_warnings(vulns, conf)
}
}
const example_warnings = [
Warning(None, "fake", "x.y.z", "Retired", Vulnerable, "Critical", Direct),
Warning(
None,
"another_fake",
"1.2.3",
"Vulnerable",
Vulnerable,
"High",
Direct,
),
Warning(
None,
"and_another",
"4.5.6",
"Vulnerable",
Vulnerable,
"Moderate",
Direct,
),
Warning(None, "one_more", "7.8.9", "Vulnerable", Vulnerable, "LOW", Indirect),
Warning(
None,
"this_one_was_retired",
"10.11.12",
"Retired",
Retired,
"Package Retired",
Indirect,
),
]