From 9b9b91229146dba625e0543611e26c0e81ad38c4 Mon Sep 17 00:00:00 2001 From: Mikail Bagishov Date: Sat, 1 May 2021 01:02:46 +0300 Subject: [PATCH 1/7] Exclude components moved to other repos --- Cargo.lock | 4451 ++++------------- Cargo.toml | 27 +- src/cli/Cargo.toml | 4 +- src/invoker-api/Cargo.toml | 13 - src/invoker-api/src/judge_log.rs | 51 - src/invoker-api/src/lib.rs | 139 - src/invoker-api/src/valuer_proto.rs | 124 - src/invoker/Cargo.toml | 49 - src/invoker/Dockerfile | 7 - src/invoker/src/api.rs | 76 - src/invoker/src/config.rs | 58 - src/invoker/src/controller.rs | 208 - src/invoker/src/controller/notify.rs | 93 - src/invoker/src/controller/task_loading.rs | 210 - src/invoker/src/controller/toolchains.rs | 184 - src/invoker/src/init.rs | 42 - src/invoker/src/lib.rs | 8 - src/invoker/src/main.rs | 214 - src/invoker/src/scheduler.rs | 242 - src/invoker/src/sources.rs | 4 - src/invoker/src/sources/api_source.rs | 201 - src/invoker/src/sources/cli_source.rs | 138 - src/invoker/src/worker.rs | 331 -- src/invoker/src/worker/compiler.rs | 89 - src/invoker/src/worker/exec_test.rs | 255 - .../src/worker/exec_test/checker_proto.rs | 58 - src/invoker/src/worker/invoke_util.rs | 141 - src/invoker/src/worker/os_util.rs | 64 - src/invoker/src/worker/transform_judge_log.rs | 145 - src/invoker/src/worker/valuer.rs | 115 - src/invoker/tests/separated_feedback.rs | 4 - src/jtl/CMakeLists.txt | 34 - src/jtl/Dockerfile | 2 - src/jtl/JtlConfig.cmake | 11 - src/jtl/cbindgen.toml | 8 - src/jtl/include/checker.h | 70 - src/jtl/include/jtl.h | 33 - src/jtl/include/testgen.h | 46 - src/jtl/src/builtin/checker-cmp-tokens.cpp | 94 - .../src/builtin/checker-polygon-compat.cpp | 80 - src/jtl/src/checker.cpp | 198 - src/jtl/src/jtl.cpp | 48 - src/jtl/src/proto.cpp | 75 - src/jtl/src/proto.h | 18 - src/jtl/src/testgen.cpp | 51 - src/jtl/src/util.cpp | 10 - src/jtl/src/util.h | 11 - src/pom/Cargo.toml | 9 - src/pom/src/lib.rs | 132 - src/pps/Readme.md | 2 - src/pps/api/Cargo.toml | 14 - src/pps/api/src/compile_problem.rs | 35 - src/pps/api/src/import_problem.rs | 52 - src/pps/api/src/lib.rs | 48 - src/pps/cli/Cargo.toml | 19 - src/pps/cli/Dockerfile | 7 - src/pps/cli/src/client_util.rs | 30 - src/pps/cli/src/compile.rs | 73 - src/pps/cli/src/import.rs | 88 - src/pps/cli/src/main.rs | 56 - src/pps/cli/src/progress_notifier.rs | 46 - src/pps/server/Cargo.toml | 32 - src/pps/server/src/command.rs | 97 - src/pps/server/src/compile.rs | 70 - src/pps/server/src/compile/build.rs | 130 - src/pps/server/src/compile/builder.rs | 472 -- src/pps/server/src/import.rs | 93 - src/pps/server/src/import/checker_tpl.cmake | 4 - src/pps/server/src/import/contest_import.rs | 64 - .../src/import/default_valuer_config.yaml | 4 - src/pps/server/src/import/gen.cmake | 8 - src/pps/server/src/import/problem_importer.rs | 472 -- src/pps/server/src/import/solution.cmake | 5 - src/pps/server/src/import/template.rs | 10 - src/pps/server/src/import/valuer_cfg.pest | 36 - src/pps/server/src/import/valuer_cfg.rs | 143 - src/pps/server/src/lib.rs | 110 - src/pps/server/src/manifest.rs | 299 -- src/problem-loader/Cargo.toml | 22 - src/problem-loader/src/lib.rs | 105 - src/problem-loader/src/registry.rs | 142 - src/svaluer/Cargo.toml | 20 - src/svaluer/Dockerfile | 4 - src/svaluer/src/cfg.rs | 199 - src/svaluer/src/fiber.rs | 396 -- src/svaluer/src/fiber/group.rs | 363 -- src/svaluer/src/lib.rs | 185 - src/svaluer/src/main.rs | 275 - src/svaluer/src/tests.rs | 287 -- 89 files changed, 1089 insertions(+), 12103 deletions(-) delete mode 100644 src/invoker-api/Cargo.toml delete mode 100644 src/invoker-api/src/judge_log.rs delete mode 100644 src/invoker-api/src/lib.rs delete mode 100644 src/invoker-api/src/valuer_proto.rs delete mode 100644 src/invoker/Cargo.toml delete mode 100644 src/invoker/Dockerfile delete mode 100644 src/invoker/src/api.rs delete mode 100644 src/invoker/src/config.rs delete mode 100644 src/invoker/src/controller.rs delete mode 100644 src/invoker/src/controller/notify.rs delete mode 100644 src/invoker/src/controller/task_loading.rs delete mode 100644 src/invoker/src/controller/toolchains.rs delete mode 100644 src/invoker/src/init.rs delete mode 100644 src/invoker/src/lib.rs delete mode 100644 src/invoker/src/main.rs delete mode 100644 src/invoker/src/scheduler.rs delete mode 100644 src/invoker/src/sources.rs delete mode 100644 src/invoker/src/sources/api_source.rs delete mode 100644 src/invoker/src/sources/cli_source.rs delete mode 100644 src/invoker/src/worker.rs delete mode 100644 src/invoker/src/worker/compiler.rs delete mode 100644 src/invoker/src/worker/exec_test.rs delete mode 100644 src/invoker/src/worker/exec_test/checker_proto.rs delete mode 100644 src/invoker/src/worker/invoke_util.rs delete mode 100644 src/invoker/src/worker/os_util.rs delete mode 100644 src/invoker/src/worker/transform_judge_log.rs delete mode 100644 src/invoker/src/worker/valuer.rs delete mode 100644 src/invoker/tests/separated_feedback.rs delete mode 100644 src/jtl/CMakeLists.txt delete mode 100644 src/jtl/Dockerfile delete mode 100644 src/jtl/JtlConfig.cmake delete mode 100644 src/jtl/cbindgen.toml delete mode 100644 src/jtl/include/checker.h delete mode 100644 src/jtl/include/jtl.h delete mode 100644 src/jtl/include/testgen.h delete mode 100644 src/jtl/src/builtin/checker-cmp-tokens.cpp delete mode 100644 src/jtl/src/builtin/checker-polygon-compat.cpp delete mode 100644 src/jtl/src/checker.cpp delete mode 100644 src/jtl/src/jtl.cpp delete mode 100644 src/jtl/src/proto.cpp delete mode 100644 src/jtl/src/proto.h delete mode 100644 src/jtl/src/testgen.cpp delete mode 100644 src/jtl/src/util.cpp delete mode 100644 src/jtl/src/util.h delete mode 100644 src/pom/Cargo.toml delete mode 100644 src/pom/src/lib.rs delete mode 100644 src/pps/Readme.md delete mode 100644 src/pps/api/Cargo.toml delete mode 100644 src/pps/api/src/compile_problem.rs delete mode 100644 src/pps/api/src/import_problem.rs delete mode 100644 src/pps/api/src/lib.rs delete mode 100644 src/pps/cli/Cargo.toml delete mode 100644 src/pps/cli/Dockerfile delete mode 100644 src/pps/cli/src/client_util.rs delete mode 100644 src/pps/cli/src/compile.rs delete mode 100644 src/pps/cli/src/import.rs delete mode 100644 src/pps/cli/src/main.rs delete mode 100644 src/pps/cli/src/progress_notifier.rs delete mode 100644 src/pps/server/Cargo.toml delete mode 100644 src/pps/server/src/command.rs delete mode 100644 src/pps/server/src/compile.rs delete mode 100644 src/pps/server/src/compile/build.rs delete mode 100644 src/pps/server/src/compile/builder.rs delete mode 100644 src/pps/server/src/import.rs delete mode 100644 src/pps/server/src/import/checker_tpl.cmake delete mode 100644 src/pps/server/src/import/contest_import.rs delete mode 100644 src/pps/server/src/import/default_valuer_config.yaml delete mode 100644 src/pps/server/src/import/gen.cmake delete mode 100644 src/pps/server/src/import/problem_importer.rs delete mode 100644 src/pps/server/src/import/solution.cmake delete mode 100644 src/pps/server/src/import/template.rs delete mode 100644 src/pps/server/src/import/valuer_cfg.pest delete mode 100644 src/pps/server/src/import/valuer_cfg.rs delete mode 100644 src/pps/server/src/lib.rs delete mode 100644 src/pps/server/src/manifest.rs delete mode 100644 src/problem-loader/Cargo.toml delete mode 100644 src/problem-loader/src/lib.rs delete mode 100644 src/problem-loader/src/registry.rs delete mode 100644 src/svaluer/Cargo.toml delete mode 100644 src/svaluer/Dockerfile delete mode 100644 src/svaluer/src/cfg.rs delete mode 100644 src/svaluer/src/fiber.rs delete mode 100644 src/svaluer/src/fiber/group.rs delete mode 100644 src/svaluer/src/lib.rs delete mode 100644 src/svaluer/src/main.rs delete mode 100644 src/svaluer/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index b06636a9..710f1187 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,3693 +1,1718 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "Inflector" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -dependencies = [ - "lazy_static", - "regex", -] +version = 3 [[package]] -name = "actix-codec" -version = "0.3.0" +name = "adler" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78d1833b3838dbe990df0f1f87baf640cf6146e898166afe401839d1b001e570" -dependencies = [ - "bitflags", - "bytes", - "futures-core", - "futures-sink", - "log", - "pin-project 0.4.27", - "tokio", - "tokio-util", -] +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] -name = "actix-connect" -version = "2.0.0" +name = "aho-corasick" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177837a10863f15ba8d3ae3ec12fac1099099529ed20083a27fdfe247381d0dc" +checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "derive_more", - "either", - "futures-util", - "http", - "log", - "openssl", - "tokio-openssl", - "trust-dns-proto", - "trust-dns-resolver", + "memchr", ] [[package]] -name = "actix-http" -version = "2.1.0" +name = "ansi_term" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "404df68c297f73b8d36c9c9056404913d25905a8f80127b0e5fe147c9c4b9f02" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "actix-codec", - "actix-connect", - "actix-rt", - "actix-service", - "actix-threadpool", - "actix-tls", - "actix-utils", - "base64 0.13.0", - "bitflags", - "bytes", - "cookie", - "copyless", - "derive_more", - "either", - "encoding_rs", - "futures-channel", - "futures-core", - "futures-util", - "fxhash", - "h2", - "http", - "httparse", - "indexmap", - "itoa", - "language-tags", - "lazy_static", - "log", - "mime 0.3.16", - "percent-encoding", - "pin-project 1.0.1", - "rand 0.7.3", - "regex", - "serde", - "serde_json", - "serde_urlencoded", - "sha-1 0.9.1", - "slab", - "time 0.2.22", + "winapi 0.3.9", ] [[package]] -name = "actix-macros" -version = "0.1.2" +name = "anyhow" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a60f9ba7c4e6df97f3aacb14bb5c0cd7d98a49dcbaed0d7f292912ad9a6a3ed2" -dependencies = [ - "quote 1.0.7", - "syn 1.0.48", -] +checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" [[package]] -name = "actix-router" -version = "0.2.5" +name = "async-trait" +version = "0.1.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd1f7dbda1645bf7da33554db60891755f6c01c1b2169e2f4c492098d30c235" +checksum = "0b98e84bbb4cbcdd97da190ba0c58a1bb0de2c1fdf67d159e192ed766aeca722" dependencies = [ - "bytestring", - "http", - "log", - "regex", - "serde", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "actix-rt" -version = "1.1.1" +name = "atty" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143fcc2912e0d1de2bcf4e2f720d2a60c28652ab4179685a1ee159e0fb3db227" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "actix-macros", - "actix-threadpool", - "copyless", - "futures-channel", - "futures-util", - "smallvec 1.4.2", - "tokio", + "hermit-abi", + "libc", + "winapi 0.3.9", ] [[package]] -name = "actix-server" -version = "1.0.4" +name = "autocfg" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45407e6e672ca24784baa667c5d32ef109ccdd8d5e0b5ebb9ef8a67f4dfb708e" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "futures-channel", - "futures-util", - "log", - "mio", - "mio-uds", - "num_cpus", - "slab", - "socket2", -] +checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" [[package]] -name = "actix-service" -version = "1.0.6" +name = "autocfg" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0052435d581b5be835d11f4eb3bce417c8af18d87ddf8ace99f8e67e595882bb" -dependencies = [ - "futures-util", - "pin-project 0.4.27", -] +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] -name = "actix-testing" -version = "1.0.1" +name = "base64" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47239ca38799ab74ee6a8a94d1ce857014b2ac36f242f70f3f75a66f691e791c" -dependencies = [ - "actix-macros", - "actix-rt", - "actix-server", - "actix-service", - "log", - "socket2", -] +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] -name = "actix-threadpool" -version = "0.3.3" +name = "bitflags" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d209f04d002854b9afd3743032a27b066158817965bf5d036824d19ac2cc0e30" -dependencies = [ - "derive_more", - "futures-channel", - "lazy_static", - "log", - "num_cpus", - "parking_lot 0.11.0", - "threadpool", -] +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] -name = "actix-tls" -version = "2.0.0" +name = "bstr" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24789b7d7361cf5503a504ebe1c10806896f61e96eca9a7350e23001aca715fb" +checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d" dependencies = [ - "actix-codec", - "actix-service", - "actix-utils", - "futures-util", - "openssl", - "tokio-openssl", + "memchr", ] [[package]] -name = "actix-utils" -version = "2.0.0" +name = "bumpalo" +version = "3.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9022dec56632d1d7979e59af14f0597a28a830a9c1c7fec8b2327eb9f16b5a" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "bitflags", - "bytes", - "either", - "futures-channel", - "futures-sink", - "futures-util", - "log", - "pin-project 0.4.27", - "slab", -] +checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" [[package]] -name = "actix-web" -version = "3.2.0" +name = "byteorder" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88344b7a5ef27e5e09e73565379f69273dd3e2d29e82afc381b84d170d0a5631" -dependencies = [ - "actix-codec", - "actix-http", - "actix-macros", - "actix-router", - "actix-rt", - "actix-server", - "actix-service", - "actix-testing", - "actix-threadpool", - "actix-tls", - "actix-utils", - "actix-web-codegen", - "awc", - "bytes", - "derive_more", - "encoding_rs", - "futures-channel", - "futures-core", - "futures-util", - "fxhash", - "log", - "mime 0.3.16", - "openssl", - "pin-project 1.0.1", - "regex", - "serde", - "serde_json", - "serde_urlencoded", - "socket2", - "time 0.2.22", - "tinyvec 1.0.1", - "url", -] +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] -name = "actix-web-codegen" -version = "0.4.0" +name = "bytes" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad26f77093333e0e7c6ffe54ebe3582d908a104e448723eec6d43d08b07143fb" -dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", -] +checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" [[package]] -name = "addr2line" -version = "0.14.0" +name = "bytes" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423" -dependencies = [ - "gimli", -] +checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" [[package]] -name = "adler" -version = "0.2.3" +name = "cc" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" +checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" [[package]] -name = "adler32" -version = "1.2.0" +name = "cfg-if" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] -name = "aho-corasick" -version = "0.7.14" +name = "cfg-if" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b476ce7103678b0c6d3d395dbbae31d48ff910bd28be979ba5d48c6351131d0d" -dependencies = [ - "memchr", -] +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "ansi_term" -version = "0.12.1" +name = "chrono" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" dependencies = [ + "libc", + "num-integer", + "num-traits", "winapi 0.3.9", ] [[package]] -name = "anyhow" -version = "1.0.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1fd36ffbb1fb7c834eac128ea8d0e310c5aeb635548f9d58861e1308d46e71c" - -[[package]] -name = "arc-swap" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" - -[[package]] -name = "array_tool" -version = "1.0.3" +name = "clap" +version = "3.0.0-beta.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f8cb5d814eb646a863c4f24978cff2880c4be96ad8cde2c0f0678732902e271" +checksum = "4bd1061998a501ee7d4b6d449020df3266ca3124b941ec56cf2005c3779ca142" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "indexmap", + "lazy_static", + "os_str_bytes", + "strsim", + "termcolor", + "textwrap", + "unicode-width", + "vec_map", +] [[package]] -name = "arrayref" -version = "0.3.6" +name = "clap_derive" +version = "3.0.0-beta.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" +checksum = "370f715b81112975b1b69db93e0b56ea4cd4e5002ac43b2da8474106a54096a1" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "arrayvec" -version = "0.5.2" +name = "clap_generate" +version = "3.0.0-beta.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +checksum = "adf420f8b687b628d2915ccfd43a660c437a170432e3fbcb66944e8717a0d68f" +dependencies = [ + "clap", +] [[package]] -name = "async-compression" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9021768bcce77296b64648cc7a7460e3df99979b97ed5c925c38d1cc83778d98" +name = "cli" +version = "0.1.0" dependencies = [ - "bytes", + "anyhow", + "base64", + "clap", + "clap_generate", + "client", + "dialoguer", + "either", "flate2", - "futures-core", - "memchr", - "pin-project-lite", + "futures 0.3.14", + "humansize", + "log", + "pom", + "serde", + "serde_json", + "serde_yaml", + "tar", + "tokio", + "util", + "xdg", ] [[package]] -name = "async-mpmc" +name = "client" version = "0.1.0" -source = "git+https://github.com/jjs-dev/commons#f25926f9adecfb364ceb2e791867d4a7afa11fab" dependencies = [ + "anyhow", + "async-trait", + "http", + "hyper", + "openapi", + "serde", + "serde_json", + "serde_yaml", "tokio", "tracing", "tracing-futures", - "triomphe", -] - -[[package]] -name = "async-stream" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3670df70cbc01729f901f94c887814b3c68db038aad1329a418bae178bc5295c" -dependencies = [ - "async-stream-impl", - "futures-core", + "url", + "xdg", ] [[package]] -name = "async-stream-impl" -version = "0.3.0" +name = "cloudabi" +version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3548b8efc9f8e8a5a0a2808c5bd8451a9031b9e5b879a79590304ae928b0a70" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", + "bitflags", ] [[package]] -name = "async-trait" -version = "0.1.41" +name = "console" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b246867b8b3b6ae56035f1eb1ed557c1d8eae97f0d53696138a50fa0e3a3b8c0" +checksum = "3993e6445baa160675931ec041a5e03ca84b9c6e32a056150d3aa2bdda0a1f45" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", + "encode_unicode", + "lazy_static", "libc", + "regex", + "terminal_size", + "unicode-width", "winapi 0.3.9", ] [[package]] -name = "autocfg" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "awc" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "425980a1e58e5030a3e4b065a3d577c8f0e16142ea9d81f30614eae810c98577" -dependencies = [ - "actix-codec", - "actix-http", - "actix-rt", - "actix-service", - "base64 0.13.0", - "bytes", - "cfg-if 1.0.0", - "derive_more", - "futures-core", - "log", - "mime 0.3.16", - "openssl", - "percent-encoding", - "rand 0.7.3", - "serde", - "serde_json", - "serde_urlencoded", -] - -[[package]] -name = "backtrace" -version = "0.3.54" +name = "core-foundation" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2baad346b2d4e94a24347adeee9c7a93f412ee94b9cc26e5b59dea23848e9f28" +checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" dependencies = [ - "addr2line", - "cfg-if 1.0.0", + "core-foundation-sys", "libc", - "miniz_oxide", - "object", - "rustc-demangle", ] [[package]] -name = "base-x" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b20b618342cf9891c292c4f5ac2cde7287cc5c87e87e9c769d617793607dec1" - -[[package]] -name = "base64" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" - -[[package]] -name = "base64" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" - -[[package]] -name = "base64" -version = "0.13.0" +name = "core-foundation-sys" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" [[package]] -name = "bitflags" +name = "crc32fast" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" - -[[package]] -name = "blake2b_simd" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" -dependencies = [ - "arrayref", - "arrayvec", - "constant_time_eq", -] - -[[package]] -name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -dependencies = [ - "block-padding", - "byte-tools", - "byteorder", - "generic-array 0.12.3", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array 0.14.4", -] - -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -dependencies = [ - "byte-tools", -] - -[[package]] -name = "bson" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c11f16001d679cb13d14b2c93c7d0fa13bb484a87c34a6c4c39707ad936499b5" -dependencies = [ - "base64 0.12.3", - "chrono", - "hex", - "lazy_static", - "linked-hash-map", - "rand 0.7.3", - "serde", - "serde_json", -] - -[[package]] -name = "bstr" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "473fc6b38233f9af7baa94fb5852dca389e3d95b8e21c8e3719301462c5d9faf" -dependencies = [ - "memchr", -] - -[[package]] -name = "bumpalo" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" - -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - -[[package]] -name = "byteorder" -version = "1.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" - -[[package]] -name = "bytes" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" - -[[package]] -name = "bytestring" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7c05fa5172da78a62d9949d662d2ac89d4cc7355d7b49adee5163f1fb3f363" -dependencies = [ - "bytes", -] - -[[package]] -name = "cc" -version = "1.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed67cbde08356238e75fc4656be4749481eeffb09e19f320a25237d5221c985d" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" dependencies = [ - "libc", - "num-integer", - "num-traits", - "serde", - "time 0.1.44", - "winapi 0.3.9", + "cfg-if 1.0.0", ] [[package]] -name = "clap" -version = "3.0.0-beta.2" +name = "crossbeam-utils" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd1061998a501ee7d4b6d449020df3266ca3124b941ec56cf2005c3779ca142" +checksum = "4feb231f0d4d6af81aed15928e58ecf5816aa62a2393e2c82f46973e92a9a278" dependencies = [ - "atty", - "bitflags", - "clap_derive", - "indexmap", + "autocfg 1.0.1", + "cfg-if 1.0.0", "lazy_static", - "os_str_bytes", - "strsim 0.10.0", - "termcolor", - "textwrap", - "unicode-width", - "vec_map", -] - -[[package]] -name = "clap_derive" -version = "3.0.0-beta.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "370f715b81112975b1b69db93e0b56ea4cd4e5002ac43b2da8474106a54096a1" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", -] - -[[package]] -name = "clap_generate" -version = "3.0.0-beta.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adf420f8b687b628d2915ccfd43a660c437a170432e3fbcb66944e8717a0d68f" -dependencies = [ - "clap", ] [[package]] -name = "cli" +name = "devtool" version = "0.1.0" dependencies = [ "anyhow", - "base64 0.13.0", + "atty", "clap", - "clap_generate", - "client", - "dialoguer", - "either", - "flate2", - "futures 0.3.7", - "humansize", + "env_logger", + "ignore", + "lazy_static", "log", - "pom", "serde", "serde_json", - "serde_yaml", - "tar", - "tokio", + "tempfile", + "toml", "util", - "xdg", -] - -[[package]] -name = "client" -version = "0.1.0" -dependencies = [ - "anyhow", - "async-trait", - "http", - "hyper", - "openapi", - "serde", - "serde_json", - "serde_yaml", - "tokio", - "tracing", - "tracing-futures", - "url", - "xdg", ] [[package]] -name = "cloudabi" -version = "0.0.3" +name = "dialoguer" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +checksum = "c9dd058f8b65922819fabb4a41e7d1964e56344042c26efbccd465202c23fa0c" dependencies = [ - "bitflags", + "console", + "lazy_static", + "tempfile", + "zeroize", ] [[package]] -name = "cloudabi" +name = "dist-builder" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467" -dependencies = [ - "bitflags", -] - -[[package]] -name = "colored" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" -dependencies = [ - "atty", - "lazy_static", - "winapi 0.3.9", -] - -[[package]] -name = "console" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a50aab2529019abfabfa93f1e6c41ef392f91fbf179b347a7e96abb524884a08" -dependencies = [ - "encode_unicode", - "lazy_static", - "libc", - "regex", - "terminal_size", - "unicode-width", - "winapi 0.3.9", - "winapi-util", -] - -[[package]] -name = "const_fn" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce90df4c658c62f12d78f7508cf92f9173e5184a539c10bfe54a3107b3ffd0f2" - -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - -[[package]] -name = "cookie" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1373a16a4937bc34efec7b391f9c1500c30b8478a701a4f44c9165cc0475a6e0" -dependencies = [ - "percent-encoding", - "time 0.2.22", - "version_check", -] - -[[package]] -name = "copyless" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536" - -[[package]] -name = "core-foundation" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" - -[[package]] -name = "cpuid-bool" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" - -[[package]] -name = "crc32fast" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils 0.8.0", -] - -[[package]] -name = "crossbeam-utils" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" -dependencies = [ - "autocfg 1.0.1", - "cfg-if 0.1.10", - "lazy_static", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec91540d98355f690a86367e566ecad2e9e579f230230eb7c21398372be73ea5" -dependencies = [ - "autocfg 1.0.1", - "cfg-if 1.0.0", - "const_fn", - "lazy_static", -] - -[[package]] -name = "crypto-mac" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" -dependencies = [ - "generic-array 0.12.3", - "subtle", -] - -[[package]] -name = "darling" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2 1.0.24", - "quote 1.0.7", - "strsim 0.9.3", - "syn 1.0.48", -] - -[[package]] -name = "darling_macro" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" -dependencies = [ - "darling_core", - "quote 1.0.7", - "syn 1.0.48", -] - -[[package]] -name = "derivative" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb582b60359da160a9477ee80f15c8d784c477e69c217ef2cdd4169c24ea380f" -dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", -] - -[[package]] -name = "derive_more" -version = "0.99.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c" -dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", -] - -[[package]] -name = "devtool" -version = "0.1.0" -dependencies = [ - "anyhow", - "atty", - "clap", - "env_logger 0.8.1", - "ignore", - "lazy_static", - "log", - "serde", - "serde_json", - "tempfile", - "toml", - "util", -] - -[[package]] -name = "dialoguer" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70f807b2943dc90f9747497d9d65d7e92472149be0b88bf4ce1201b4ac979c26" -dependencies = [ - "console", - "lazy_static", - "tempfile", - "zeroize", -] - -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.3", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array 0.14.4", -] - -[[package]] -name = "dirs" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "142995ed02755914747cc6ca76fc7e4583cd18578746716d0508ea6ed558b9ff" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a" -dependencies = [ - "libc", - "redox_users", - "winapi 0.3.9", -] - -[[package]] -name = "discard" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" - -[[package]] -name = "dist-builder" -version = "0.1.0" -dependencies = [ - "anyhow", - "clap", - "log", - "serde", - "serde_json", - "util", -] - -[[package]] -name = "dist-files-generator" -version = "0.1.0" -dependencies = [ - "anyhow", - "clap", - "fs_extra", - "serde", - "util", -] - -[[package]] -name = "dkregistry" -version = "0.4.1-alpha.0" -source = "git+https://github.com/mikailbag/dkregistry-rs?branch=all#64685799a00a8088b0f83c6f4ca17c729c4157d5" -dependencies = [ - "async-stream", - "base64 0.12.3", - "futures 0.3.7", - "http", - "libflate", - "log", - "mime 0.3.16", - "regex", - "reqwest", - "serde", - "serde_ignored", - "serde_json", - "sha2 0.9.1", - "strum", - "strum_macros", - "tar", - "thiserror", - "tokio", - "url", -] - -[[package]] -name = "dotenv" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" - -[[package]] -name = "dtoa" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b" - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - -[[package]] -name = "encoding_rs" -version = "0.8.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a51b8cf747471cb9499b6d59e59b0444f4c90eba8968c4e44874e92b5b64ace2" -dependencies = [ - "cfg-if 0.1.10", -] - -[[package]] -name = "enum-as-inner" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595" -dependencies = [ - "heck", - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", -] - -[[package]] -name = "env_logger" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" -dependencies = [ - "atty", - "humantime 1.3.0", - "log", - "regex", - "termcolor", -] - -[[package]] -name = "env_logger" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54532e3223c5af90a6a757c90b5c5521564b07e5e7a958681bcd2afad421cdcd" -dependencies = [ - "atty", - "humantime 2.0.1", - "log", - "regex", - "termcolor", -] - -[[package]] -name = "err-derive" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22deed3a8124cff5fa835713fa105621e43bbdc46690c3a6b68328a012d350d4" -dependencies = [ - "proc-macro-error", - "proc-macro2 1.0.24", - "quote 1.0.7", - "rustversion", - "syn 1.0.48", - "synstructure 0.12.4", -] - -[[package]] -name = "errno" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa68f2fb9cae9d37c9b2b3584aba698a2e97f72d7aef7b9f7aa71d8b54ce46fe" -dependencies = [ - "errno-dragonfly", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067" -dependencies = [ - "gcc", - "libc", -] - -[[package]] -name = "error-chain" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" -dependencies = [ - "backtrace", - "version_check", -] - -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - -[[package]] -name = "filetime" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed85775dcc68644b5c950ac06a2b23768d3bc9390464151aaf27136998dcf9e" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "redox_syscall", - "winapi 0.3.9", -] - -[[package]] -name = "flate2" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da80be589a72651dcda34d8b35bcdc9b7254ad06325611074d9cc0fbb19f60ee" -dependencies = [ - "cfg-if 0.1.10", - "crc32fast", - "libc", - "miniz_oxide", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "formatf" -version = "0.1.0" -source = "git+https://github.com/mikailbag/formatf#1447dffec6cc32c430b55dfb4d3677486c411527" -dependencies = [ - "itoa", -] - -[[package]] -name = "fs_extra" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" - -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags", - "fuchsia-zircon-sys", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - -[[package]] -name = "futures" -version = "0.1.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7e4c2612746b0df8fed4ce0c69156021b704c9aefa360311c04e6e9e002eed" - -[[package]] -name = "futures" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95314d38584ffbfda215621d723e0a3906f032e03ae5551e650058dac83d4797" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0448174b01148032eed37ac4aed28963aaaa8cfa93569a08e5b479bbc6c2c151" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18eaa56102984bed2c88ea39026cff3ce3b4c7f508ca970cedf2450ea10d4e46" - -[[package]] -name = "futures-executor" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5f8e0c9258abaea85e78ebdda17ef9666d390e987f006be6080dfe354b708cb" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-intrusive" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc1529d07bd55fa54fc6c2d8460f621cfde0ae3fd2b96b2fa7eb4883478e1703" -dependencies = [ - "futures-core", - "lock_api 0.3.4", - "parking_lot 0.10.2", -] - -[[package]] -name = "futures-io" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1798854a4727ff944a7b12aa999f58ce7aa81db80d2dfaaf2ba06f065ddd2b" - -[[package]] -name = "futures-macro" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36fccf3fc58563b4a14d265027c627c3b665d7fed489427e88e7cc929559efe" -dependencies = [ - "proc-macro-hack", - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", -] - -[[package]] -name = "futures-sink" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e3ca3f17d6e8804ae5d3df7a7d35b2b3a6fe89dac84b31872720fc3060a0b11" - -[[package]] -name = "futures-task" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d502af37186c4fef99453df03e374683f8a1eec9dcc1e66b3b82dc8278ce3c" -dependencies = [ - "once_cell", -] - -[[package]] -name = "futures-util" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abcb44342f62e6f3e8ac427b8aa815f724fd705dfad060b18ac7866c15bb8e34" -dependencies = [ - "futures 0.1.30", - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project 1.0.1", - "pin-utils", - "proc-macro-hack", - "proc-macro-nested", - "slab", -] - -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - -[[package]] -name = "gcc" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" - -[[package]] -name = "generator" -version = "0.6.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cdc09201b2e8ca1b19290cf7e65de2246b8e91fb6874279722189c4de7b94dc" -dependencies = [ - "cc", - "libc", - "log", - "rustc_version", - "winapi 0.3.9", -] - -[[package]] -name = "generic-array" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" -dependencies = [ - "typenum", -] - -[[package]] -name = "generic-array" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee8025cf36f917e6a52cce185b7c7177689b838b7ec138364e50cc2277a56cf4" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "gimli" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce" - -[[package]] -name = "glob" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" - -[[package]] -name = "globset" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c152169ef1e421390738366d2f796655fec62621dabbd0fd476f905934061e4a" -dependencies = [ - "aho-corasick", - "bstr", - "fnv", - "log", - "regex", -] - -[[package]] -name = "h2" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", - "tracing-futures", -] - -[[package]] -name = "hashbrown" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" - -[[package]] -name = "heck" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "hermit-abi" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" -dependencies = [ - "libc", -] - -[[package]] -name = "hex" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" - -[[package]] -name = "hmac" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" -dependencies = [ - "crypto-mac", - "digest 0.8.1", -] - -[[package]] -name = "hostname" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -dependencies = [ - "libc", - "match_cfg", - "winapi 0.3.9", -] - -[[package]] -name = "http" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "httparse" -version = "1.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" - -[[package]] -name = "httpdate" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" - -[[package]] -name = "humansize" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e" - -[[package]] -name = "humantime" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" -dependencies = [ - "quick-error", -] - -[[package]] -name = "humantime" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a" - -[[package]] -name = "hyper" -version = "0.13.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f3afcfae8af5ad0576a31e768415edb627824129e8e5a29b8bfccb2f234e835" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project 0.4.27", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37743cc83e8ee85eacfce90f2f4102030d9ff0a95244098d781e9bee4a90abb6" -dependencies = [ - "bytes", - "futures-util", - "hyper", - "log", - "rustls 0.18.1", - "tokio", - "tokio-rustls 0.14.1", - "webpki", -] - -[[package]] -name = "hyper-tls" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d979acc56dcb5b8dddba3917601745e877576475aa046df3226eabdecef78eed" -dependencies = [ - "bytes", - "hyper", - "native-tls", - "tokio", - "tokio-tls", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "ignore" -version = "0.4.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22dcbf2a4a289528dbef21686354904e1c694ac642610a9bff9e7df730d9ec72" -dependencies = [ - "crossbeam-utils 0.7.2", - "globset", - "lazy_static", - "log", - "memchr", - "regex", - "same-file", - "thread_local", - "walkdir", - "winapi-util", -] - -[[package]] -name = "indexmap" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2" -dependencies = [ - "autocfg 1.0.1", - "hashbrown", -] - -[[package]] -name = "instant" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb1fc4429a33e1f80d41dc9fea4d108a88bec1de8053878898ae448a0b52f613" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "invoker" -version = "0.1.0" -dependencies = [ - "actix-rt", - "actix-web", - "aho-corasick", - "anyhow", - "async-mpmc", - "async-trait", - "base64 0.13.0", - "bitflags", - "chrono", - "client", - "dkregistry", - "dotenv", - "fs_extra", - "invoker-api", - "k8s-openapi", - "kube", - "libc", - "minion", - "multiwake", - "nix 0.19.0", - "num_cpus", - "once_cell", - "openssl", - "pom", - "problem-loader", - "puller", - "serde", - "serde_json", - "serde_yaml", - "strum", - "strum_macros", - "tempfile", - "thiserror", - "tokio", - "tracing", - "tracing-futures", - "util", - "uuid", -] - -[[package]] -name = "invoker-api" -version = "0.1.0" -dependencies = [ - "bitflags", - "pom", - "serde", - "strum", - "strum_macros", - "uuid", -] - -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - -[[package]] -name = "ipconfig" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" -dependencies = [ - "socket2", - "widestring", - "winapi 0.3.9", - "winreg 0.6.2", -] - -[[package]] -name = "ipnet" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135" - -[[package]] -name = "itoa" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" - -[[package]] -name = "js-sys" -version = "0.3.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca059e81d9486668f12d455a4ea6daa600bd408134cd17e3d3fb5a32d1f016f8" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "jsonpath_lib" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8727f6987896c010ec9add275f59de2ae418b672fafa77bc3673b4cee1f09ca" -dependencies = [ - "array_tool", - "env_logger 0.7.1", - "log", - "serde", - "serde_json", -] - -[[package]] -name = "k8s-openapi" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57f95fd36c08ce592e67400a0f1a66f432196997d5a7e9a97e8743c33d8a9312" -dependencies = [ - "base64 0.12.3", - "bytes", - "chrono", - "serde", - "serde-value", - "serde_json", -] - -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - -[[package]] -name = "kube" -version = "0.43.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3787d41d01ff816f93f1a73d20252f8a65887682206cfbf2d0f7d2d2b1b73fa" -dependencies = [ - "Inflector", - "base64 0.12.3", - "bytes", - "chrono", - "dirs", - "either", - "futures 0.3.7", - "futures-util", - "http", - "jsonpath_lib", - "k8s-openapi", - "log", - "openssl", - "pem", - "reqwest", - "serde", - "serde_json", - "serde_yaml", - "static_assertions", - "thiserror", - "time 0.2.22", - "tokio", - "url", -] - -[[package]] -name = "language-tags" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" - -[[package]] -name = "libflate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389de7875e06476365974da3e7ff85d55f1972188ccd9f6020dd7c8156e17914" -dependencies = [ - "adler32", - "crc32fast", - "libflate_lz77", - "rle-decode-fast", -] - -[[package]] -name = "libflate_lz77" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3286f09f7d4926fc486334f28d8d2e6ebe4f7f9994494b6dab27ddfad2c9b11b" - -[[package]] -name = "linked-hash-map" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" - -[[package]] -name = "lock_api" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "lock_api" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "lock_api" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" -dependencies = [ - "cfg-if 0.1.10", -] - -[[package]] -name = "loom" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0e8460f2f2121162705187214720353c517b97bdfb3494c0b1e33d83ebe4bed" -dependencies = [ - "cfg-if 0.1.10", - "generator", - "scoped-tls", - "serde", - "serde_json", -] - -[[package]] -name = "lru-cache" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "maplit" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" - -[[package]] -name = "match_cfg" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" - -[[package]] -name = "matchers" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" -dependencies = [ - "regex-automata", -] - -[[package]] -name = "matches" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" - -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - -[[package]] -name = "md-5" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18af3dcaf2b0219366cdb4e2af65a6101457b415c3d1a5c71dd9c2b7c77b9c8" -dependencies = [ - "block-buffer 0.7.3", - "digest 0.8.1", - "opaque-debug 0.2.3", -] - -[[package]] -name = "memchr" -version = "2.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" - -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[package]] -name = "mime" -version = "0.4.0-a.0" -source = "git+https://github.com/hyperium/mime#938484de95445a2af931515d2b7252612c575da7" -dependencies = [ - "mime-parse", - "quoted-string", -] - -[[package]] -name = "mime-parse" -version = "0.0.0" -source = "git+https://github.com/hyperium/mime#938484de95445a2af931515d2b7252612c575da7" - -[[package]] -name = "mime_guess" -version = "2.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" -dependencies = [ - "mime 0.3.16", - "unicase", -] - -[[package]] -name = "minion" -version = "0.1.0" -source = "git+https://github.com/jjs-dev/minion#0e6a3edfdc964e9d7e240269955db4a8671cb694" dependencies = [ "anyhow", - "backtrace", - "errno", - "libc", - "nix 0.19.0", - "procfs", - "rand 0.7.3", - "serde", - "serde_json", - "thiserror", - "tiny-nix-ipc", -] - -[[package]] -name = "miniz_oxide" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" -dependencies = [ - "adler", - "autocfg 1.0.1", -] - -[[package]] -name = "mio" -version = "0.6.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" -dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "libc", - "log", - "miow 0.2.1", - "net2", - "slab", - "winapi 0.2.8", -] - -[[package]] -name = "mio-named-pipes" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656" -dependencies = [ - "log", - "mio", - "miow 0.3.5", - "winapi 0.3.9", -] - -[[package]] -name = "mio-uds" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" -dependencies = [ - "iovec", - "libc", - "mio", -] - -[[package]] -name = "miow" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", -] - -[[package]] -name = "miow" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e" -dependencies = [ - "socket2", - "winapi 0.3.9", -] - -[[package]] -name = "mongodb" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a726495d7418c4579ecc9465b53ddade8187c0299e5db0e7250672b67d196913" -dependencies = [ - "async-trait", - "base64 0.11.0", - "bitflags", - "bson", - "chrono", - "derivative", - "err-derive", - "futures 0.3.7", - "futures-intrusive", - "hex", - "hmac", - "lazy_static", - "md-5", - "os_info", - "pbkdf2", - "percent-encoding", - "rand 0.7.3", - "reqwest", - "rustls 0.17.0", - "serde", - "serde_bytes", - "serde_with", - "sha-1 0.8.2", - "sha2 0.8.2", - "socket2", - "stringprep", - "strsim 0.10.0", - "take_mut", - "time 0.1.44", - "tokio", - "tokio-rustls 0.13.1", - "trust-dns-proto", - "trust-dns-resolver", - "typed-builder", - "uuid", - "version_check", - "webpki", - "webpki-roots 0.18.0", -] - -[[package]] -name = "multiwake" -version = "0.1.0" -source = "git+https://github.com/jjs-dev/commons#f25926f9adecfb364ceb2e791867d4a7afa11fab" - -[[package]] -name = "native-tls" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b0d88c06fe90d5ee94048ba40409ef1d9315d86f6f38c2efdaad4fb50c58b2d" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "net2" -version = "0.2.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ebc3ec692ed7c9a255596c67808dee269f64655d8baf7b4f0638e51ba1d6853" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "nix" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229" -dependencies = [ - "bitflags", - "cc", - "cfg-if 0.1.10", - "libc", - "void", -] - -[[package]] -name = "nix" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85db2feff6bf70ebc3a4793191517d5f0331100a2f10f9bf93b5e5214f32b7b7" -dependencies = [ - "bitflags", - "cc", - "cfg-if 0.1.10", - "libc", -] - -[[package]] -name = "nodrop" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" - -[[package]] -name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg 1.0.1", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg 1.0.1", -] - -[[package]] -name = "num_cpus" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" - -[[package]] -name = "once_cell" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad" - -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "openapi" -version = "0.1.0" -dependencies = [ - "async-trait", - "bytes", - "futures 0.3.7", - "http", - "lazy_static", - "log", - "mime 0.4.0-a.0", - "mime_guess", - "parking_lot 0.8.0", - "reqwest", - "serde", - "serde_json", - "serde_yaml", - "thiserror", - "tokio", - "tokio-util", - "url", -] - -[[package]] -name = "openssl" -version = "0.10.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4" -dependencies = [ - "bitflags", - "cfg-if 0.1.10", - "foreign-types", - "lazy_static", - "libc", - "openssl-sys", -] - -[[package]] -name = "openssl-probe" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" - -[[package]] -name = "openssl-sys" -version = "0.9.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de" -dependencies = [ - "autocfg 1.0.1", - "cc", - "libc", - "pkg-config", - "vcpkg", + "clap", + "log", + "serde", + "serde_json", + "util", ] [[package]] -name = "ordered-float" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fe9037165d7023b1228bc4ae9a2fa1a2b0095eca6c2998c624723dfd01314a5" +name = "dist-files-generator" +version = "0.1.0" dependencies = [ - "num-traits", + "anyhow", + "clap", + "fs_extra", + "serde", + "util", ] [[package]] -name = "os_info" -version = "2.0.8" +name = "dtoa" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc1b4330bb29087e791ae2a5cf56be64fb8946a4ff5aec2ba11c6ca51f5d60" -dependencies = [ - "log", - "winapi 0.3.9", -] +checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" [[package]] -name = "os_str_bytes" -version = "2.3.2" +name = "either" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ac6fe3538f701e339953a3ebbe4f39941aababa8a3f6964635b24ab526daeac" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] -name = "parking_lot" -version = "0.8.0" +name = "encode_unicode" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7" -dependencies = [ - "lock_api 0.2.0", - "parking_lot_core 0.5.0", - "rustc_version", -] +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] -name = "parking_lot" -version = "0.10.2" +name = "encoding_rs" +version = "0.8.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" +checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065" dependencies = [ - "lock_api 0.3.4", - "parking_lot_core 0.7.2", + "cfg-if 1.0.0", ] [[package]] -name = "parking_lot" -version = "0.11.0" +name = "env_logger" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733" +checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f" dependencies = [ - "instant", - "lock_api 0.4.1", - "parking_lot_core 0.8.0", + "atty", + "humantime", + "log", + "regex", + "termcolor", ] [[package]] -name = "parking_lot_core" -version = "0.5.0" +name = "filetime" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c" +checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8" dependencies = [ - "cfg-if 0.1.10", - "cloudabi 0.0.3", + "cfg-if 1.0.0", "libc", - "rand 0.6.5", - "redox_syscall", - "rustc_version", - "smallvec 0.6.13", + "redox_syscall 0.2.7", "winapi 0.3.9", ] [[package]] -name = "parking_lot_core" -version = "0.7.2" +name = "flate2" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" +checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0" dependencies = [ - "cfg-if 0.1.10", - "cloudabi 0.0.3", + "cfg-if 1.0.0", + "crc32fast", "libc", - "redox_syscall", - "smallvec 1.4.2", - "winapi 0.3.9", + "miniz_oxide", ] [[package]] -name = "parking_lot_core" -version = "0.8.0" +name = "fnv" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b" -dependencies = [ - "cfg-if 0.1.10", - "cloudabi 0.1.0", - "instant", - "libc", - "redox_syscall", - "smallvec 1.4.2", - "winapi 0.3.9", -] +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "pbkdf2" -version = "0.3.0" +name = "foreign-types" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "byteorder", - "crypto-mac", + "foreign-types-shared", ] [[package]] -name = "pem" -version = "0.8.1" +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59698ea79df9bf77104aefd39cc3ec990cb9693fb59c3b0a70ddf2646fdffb4b" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" dependencies = [ - "base64 0.12.3", - "once_cell", - "regex", + "matches", + "percent-encoding", ] [[package]] -name = "percent-encoding" -version = "2.1.0" +name = "fs_extra" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" [[package]] -name = "pest" -version = "2.1.3" +name = "fuchsia-cprng" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" -dependencies = [ - "ucd-trie", -] +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] -name = "pest_derive" -version = "2.1.0" +name = "fuchsia-zircon" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" dependencies = [ - "pest", - "pest_generator", + "bitflags", + "fuchsia-zircon-sys", ] [[package]] -name = "pest_generator" -version = "2.1.3" +name = "fuchsia-zircon-sys" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", -] +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" [[package]] -name = "pest_meta" -version = "2.1.3" +name = "futures" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" -dependencies = [ - "maplit", - "pest", - "sha-1 0.8.2", -] +checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" [[package]] -name = "pin-project" -version = "0.4.27" +name = "futures" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffbc8e94b38ea3d2d8ba92aea2983b503cd75d0888d75b86bb37970b5698e15" +checksum = "a9d5813545e459ad3ca1bff9915e9ad7f1a47dc6a91b627ce321d5863b7dd253" dependencies = [ - "pin-project-internal 0.4.27", + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", ] [[package]] -name = "pin-project" -version = "1.0.1" +name = "futures-channel" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee41d838744f60d959d7074e3afb6b35c7456d0f61cad38a24e35e6553f73841" +checksum = "ce79c6a52a299137a6013061e0cf0e688fce5d7f1bc60125f520912fdb29ec25" dependencies = [ - "pin-project-internal 1.0.1", + "futures-core", + "futures-sink", ] [[package]] -name = "pin-project-internal" -version = "0.4.27" +name = "futures-core" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65ad2ae56b6abe3a1ee25f15ee605bacadb9a764edaba9c2bf4103800d4a1895" -dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", -] +checksum = "098cd1c6dda6ca01650f1a37a794245eb73181d0d4d4e955e2f3c37db7af1815" [[package]] -name = "pin-project-internal" -version = "1.0.1" +name = "futures-executor" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81a4ffa594b66bff340084d4081df649a7dc049ac8d7fc458d8e628bfbbb2f86" +checksum = "10f6cb7042eda00f0049b1d2080aa4b93442997ee507eb3828e8bd7577f94c9d" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", + "futures-core", + "futures-task", + "futures-util", ] [[package]] -name = "pin-project-lite" -version = "0.1.11" +name = "futures-io" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b" +checksum = "365a1a1fb30ea1c03a830fdb2158f5236833ac81fa0ad12fe35b29cddc35cb04" [[package]] -name = "pin-utils" -version = "0.1.0" +name = "futures-macro" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "668c6733a182cd7deb4f1de7ba3bf2120823835b3bcfbeacf7d2c4a773c1bb8b" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "pkg-config" -version = "0.3.19" +name = "futures-sink" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +checksum = "5c5629433c555de3d82861a7a4e3794a4c40040390907cfbfd7143a92a426c23" [[package]] -name = "pom" -version = "0.1.0" +name = "futures-task" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba7aa51095076f3ba6d9a1f702f74bd05ec65f555d70d2033d55ba8d69f581bc" + +[[package]] +name = "futures-util" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c144ad54d60f23927f0a6b6d816e4271278b64f005ad65e4e35291d2de9c025" dependencies = [ - "serde", + "futures 0.1.31", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite 0.2.6", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", ] [[package]] -name = "pps-api" -version = "0.1.0" +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" dependencies = [ - "anyhow", - "reqwest", - "rpc", - "serde", - "serde_json", - "tokio", - "tracing", + "cfg-if 1.0.0", + "libc", + "wasi", ] [[package]] -name = "pps-cli" -version = "0.1.0" +name = "globset" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c152169ef1e421390738366d2f796655fec62621dabbd0fd476f905934061e4a" dependencies = [ - "anyhow", - "clap", - "pps-api", - "pps-server", - "rand 0.7.3", - "rpc", - "serde", - "serde_json", - "tokio", - "tracing", - "tracing-futures", - "util", + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", ] [[package]] -name = "pps-server" -version = "0.1.0" +name = "h2" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535" dependencies = [ - "anyhow", - "async-trait", - "either", - "formatf", + "bytes 0.5.6", + "fnv", + "futures-core", + "futures-sink", "futures-util", - "getrandom 0.2.0", - "glob", - "hex", - "hyper", - "libc", - "pest", - "pest_derive", - "pom", - "pps-api", - "roxmltree", - "rpc", - "serde", - "serde_json", - "serde_yaml", - "svaluer", - "thiserror", + "http", + "indexmap", + "slab", "tokio", - "toml", + "tokio-util", "tracing", "tracing-futures", ] [[package]] -name = "ppv-lite86" -version = "0.2.9" +name = "hashbrown" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20" +checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" [[package]] -name = "problem-loader" -version = "0.1.0" +name = "heck" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" dependencies = [ - "anyhow", - "async-trait", - "bson", - "flate2", - "fs_extra", - "mongodb", - "pom", - "serde", - "serde_json", - "tar", - "tokio", - "tracing", - "tracing-futures", - "url", + "unicode-segmentation", ] [[package]] -name = "proc-macro-error" -version = "1.0.4" +name = "hermit-abi" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" dependencies = [ - "proc-macro-error-attr", - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", - "version_check", + "libc", ] [[package]] -name = "proc-macro-error-attr" -version = "1.0.4" +name = "http" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.7", - "version_check", + "bytes 1.0.1", + "fnv", + "itoa", ] [[package]] -name = "proc-macro-hack" -version = "0.5.19" +name = "http-body" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" +checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" +dependencies = [ + "bytes 0.5.6", + "http", +] [[package]] -name = "proc-macro-nested" -version = "0.1.6" +name = "httparse" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a" +checksum = "4a1ce40d6fc9764887c2fdc7305c3dcc429ba11ff981c1509416afd5697e4437" [[package]] -name = "proc-macro2" -version = "0.4.30" +name = "httpdate" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -dependencies = [ - "unicode-xid 0.1.0", -] +checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" [[package]] -name = "proc-macro2" -version = "1.0.24" +name = "humansize" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" -dependencies = [ - "unicode-xid 0.2.1", -] +checksum = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e" [[package]] -name = "procfs" -version = "0.7.9" +name = "humantime" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c434e93ef69c216e68e4f417c927b4f31502c3560b72cfdb6827e2321c5c6b3e" -dependencies = [ - "bitflags", - "byteorder", - "chrono", - "hex", - "lazy_static", - "libc", - "libflate", -] +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] -name = "puller" -version = "0.1.0" -source = "git+https://github.com/jjs-dev/commons#f25926f9adecfb364ceb2e791867d4a7afa11fab" +name = "hyper" +version = "0.13.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a6f157065790a3ed2f88679250419b5cdd96e714a0d65f7797fd337186e96bb" dependencies = [ - "base64 0.12.3", - "dkregistry", + "bytes 0.5.6", + "futures-channel", + "futures-core", + "futures-util", + "h2", "http", - "serde_json", - "thiserror", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project", + "socket2", "tokio", + "tower-service", "tracing", - "tracing-futures", + "want", ] [[package]] -name = "quick-error" -version = "1.2.3" +name = "hyper-tls" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +checksum = "d979acc56dcb5b8dddba3917601745e877576475aa046df3226eabdecef78eed" +dependencies = [ + "bytes 0.5.6", + "hyper", + "native-tls", + "tokio", + "tokio-tls", +] [[package]] -name = "quote" -version = "0.6.13" +name = "idna" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" dependencies = [ - "proc-macro2 0.4.30", + "matches", + "unicode-bidi", + "unicode-normalization", ] [[package]] -name = "quote" -version = "1.0.7" +name = "ignore" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +checksum = "b287fb45c60bb826a0dc68ff08742b9d88a2fea13d6e0c286b3172065aaf878c" dependencies = [ - "proc-macro2 1.0.24", + "crossbeam-utils", + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", ] [[package]] -name = "quoted-string" -version = "0.2.2" +name = "indexmap" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9586f8867f39941d8e796c18340a9cb5221a018df021169dc3e61c87d9f5f567" +checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" dependencies = [ - "quick-error", + "autocfg 1.0.1", + "hashbrown", ] [[package]] -name = "rand" -version = "0.6.5" +name = "iovec" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" dependencies = [ - "autocfg 0.1.7", "libc", - "rand_chacha 0.1.1", - "rand_core 0.4.2", - "rand_hc 0.1.0", - "rand_isaac", - "rand_jitter", - "rand_os", - "rand_pcg", - "rand_xorshift", - "winapi 0.3.9", ] [[package]] -name = "rand" -version = "0.7.3" +name = "ipnet" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.15", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc 0.2.0", -] +checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135" [[package]] -name = "rand_chacha" -version = "0.1.1" +name = "itoa" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" + +[[package]] +name = "js-sys" +version = "0.3.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d99f9e3e84b8f67f846ef5b4cbbc3b1c29f6c759fcbce6f01aa0e73d932a24c" dependencies = [ - "autocfg 0.1.7", - "rand_core 0.3.1", + "wasm-bindgen", ] [[package]] -name = "rand_chacha" +name = "kernel32-sys" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", + "winapi 0.2.8", + "winapi-build", ] [[package]] -name = "rand_core" -version = "0.3.1" +name = "lazy_static" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] -name = "rand_core" -version = "0.4.2" +name = "libc" +version = "0.2.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" +checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" [[package]] -name = "rand_core" -version = "0.5.1" +name = "linked-hash-map" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" + +[[package]] +name = "lock_api" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +checksum = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff" dependencies = [ - "getrandom 0.1.15", + "scopeguard", ] [[package]] -name = "rand_hc" -version = "0.1.0" +name = "log" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "rand_core 0.3.1", + "cfg-if 1.0.0", ] [[package]] -name = "rand_hc" -version = "0.2.0" +name = "matchers" +version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" dependencies = [ - "rand_core 0.5.1", + "regex-automata", ] [[package]] -name = "rand_isaac" -version = "0.1.1" +name = "matches" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "memchr" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "mime" +version = "0.4.0-a.0" +source = "git+https://github.com/hyperium/mime#938484de95445a2af931515d2b7252612c575da7" dependencies = [ - "rand_core 0.3.1", + "mime-parse", + "quoted-string", ] [[package]] -name = "rand_jitter" -version = "0.1.4" +name = "mime-parse" +version = "0.0.0" +source = "git+https://github.com/hyperium/mime#938484de95445a2af931515d2b7252612c575da7" + +[[package]] +name = "mime_guess" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" dependencies = [ - "libc", - "rand_core 0.4.2", - "winapi 0.3.9", + "mime 0.3.16", + "unicase", ] [[package]] -name = "rand_os" -version = "0.1.3" +name = "miniz_oxide" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" dependencies = [ - "cloudabi 0.0.3", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "winapi 0.3.9", + "adler", + "autocfg 1.0.1", ] [[package]] -name = "rand_pcg" -version = "0.1.2" +name = "mio" +version = "0.6.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" dependencies = [ - "autocfg 0.1.7", - "rand_core 0.4.2", + "cfg-if 0.1.10", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow 0.2.2", + "net2", + "slab", + "winapi 0.2.8", ] [[package]] -name = "rand_xorshift" -version = "0.1.1" +name = "mio-named-pipes" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656" dependencies = [ - "rand_core 0.3.1", + "log", + "mio", + "miow 0.3.7", + "winapi 0.3.9", ] [[package]] -name = "rdrand" -version = "0.4.0" +name = "mio-uds" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" dependencies = [ - "rand_core 0.3.1", + "iovec", + "libc", + "mio", ] [[package]] -name = "redox_syscall" -version = "0.1.57" +name = "miow" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] [[package]] -name = "redox_users" -version = "0.3.5" +name = "miow" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" dependencies = [ - "getrandom 0.1.15", - "redox_syscall", - "rust-argon2", + "winapi 0.3.9", ] [[package]] -name = "regex" -version = "1.4.1" +name = "native-tls" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8963b85b8ce3074fecffde43b4b0dded83ce2f367dc8d363afc56679f3ee820b" +checksum = "b8d96b2e1c8da3957d58100b09f102c6d9cfdfced01b7ec5a8974044bb09dbd4" dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", - "thread_local", + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", ] [[package]] -name = "regex-automata" -version = "0.1.9" +name = "net2" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" +checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" dependencies = [ - "byteorder", - "regex-syntax", + "cfg-if 0.1.10", + "libc", + "winapi 0.3.9", ] [[package]] -name = "regex-syntax" -version = "0.6.20" +name = "num-integer" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cab7a364d15cde1e505267766a2d3c4e22a843e1a601f0fa7564c0f82ced11c" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg 1.0.1", + "num-traits", +] [[package]] -name = "remove_dir_all" -version = "0.5.3" +name = "num-traits" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ - "winapi 0.3.9", + "autocfg 1.0.1", ] [[package]] -name = "reqwest" -version = "0.10.8" +name = "once_cell" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9eaa17ac5d7b838b7503d118fa16ad88f440498bf9ffe5424e621f93190d61e" +checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" + +[[package]] +name = "openapi" +version = "0.1.0" dependencies = [ - "async-compression", - "base64 0.12.3", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", + "async-trait", + "bytes 0.5.6", + "futures 0.3.14", "http", - "http-body", - "hyper", - "hyper-rustls", - "hyper-tls", - "ipnet", - "js-sys", "lazy_static", "log", - "mime 0.3.16", + "mime 0.4.0-a.0", "mime_guess", - "native-tls", - "percent-encoding", - "pin-project-lite", - "rustls 0.18.1", + "parking_lot", + "reqwest", "serde", "serde_json", - "serde_urlencoded", + "serde_yaml", + "thiserror", "tokio", - "tokio-rustls 0.14.1", - "tokio-tls", + "tokio-util", "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots 0.19.0", - "winreg 0.7.0", ] [[package]] -name = "resolv-conf" -version = "0.6.3" +name = "openssl" +version = "0.10.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11834e137f3b14e309437a8276714eed3a80d1ef894869e510f2c0c0b98b9f4a" +checksum = "6d7830286ad6a3973c0f1d9b73738f69c76b739301d0229c4b96501695cbe4c8" dependencies = [ - "hostname", - "quick-error", + "bitflags", + "cfg-if 1.0.0", + "foreign-types", + "libc", + "once_cell", + "openssl-sys", ] [[package]] -name = "ring" -version = "0.16.15" +name = "openssl-probe" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" + +[[package]] +name = "openssl-sys" +version = "0.9.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "952cd6b98c85bbc30efa1ba5783b8abf12fec8b3287ffa52605b9432313e34e4" +checksum = "fa52160d45fa2e7608d504b7c3a3355afed615e6d8b627a74458634ba21b69bd" dependencies = [ + "autocfg 1.0.1", "cc", "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi 0.3.9", + "pkg-config", + "vcpkg", ] [[package]] -name = "rle-decode-fast" -version = "1.0.1" +name = "os_str_bytes" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac" +checksum = "afb2e1c3ee07430c2cf76151675e583e0f19985fa6efae47d6848a3e2c824f85" [[package]] -name = "roxmltree" -version = "0.13.0" +name = "parking_lot" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17dfc6c39f846bfc7d2ec442ad12055d79608d501380789b965d22f9354451f2" -dependencies = [ - "xmlparser", -] - -[[package]] -name = "rpc" -version = "0.1.0" -source = "git+https://github.com/jjs-dev/commons#f25926f9adecfb364ceb2e791867d4a7afa11fab" +checksum = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7" dependencies = [ - "futures-util", - "hyper", - "reqwest", - "serde", - "serde_json", - "thiserror", - "tokio", - "tower-util", - "tracing", + "lock_api", + "parking_lot_core", + "rustc_version", ] [[package]] -name = "rust-argon2" -version = "0.8.2" +name = "parking_lot_core" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dab61250775933275e84053ac235621dfb739556d5c54a2f2e9313b7cf43a19" +checksum = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c" dependencies = [ - "base64 0.12.3", - "blake2b_simd", - "constant_time_eq", - "crossbeam-utils 0.7.2", + "cfg-if 0.1.10", + "cloudabi", + "libc", + "rand 0.6.5", + "redox_syscall 0.1.57", + "rustc_version", + "smallvec 0.6.14", + "winapi 0.3.9", ] [[package]] -name = "rustc-demangle" -version = "0.1.18" +name = "percent-encoding" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] -name = "rustc_version" -version = "0.2.3" +name = "pin-project" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4" dependencies = [ - "semver", + "pin-project-internal", ] [[package]] -name = "rustls" -version = "0.17.0" +name = "pin-project-internal" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0d4a31f5d68413404705d6982529b0e11a9aacd4839d1d6222ee3b8cb4015e1" +checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f" dependencies = [ - "base64 0.11.0", - "log", - "ring", - "sct", - "webpki", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "rustls" -version = "0.18.1" +name = "pin-project-lite" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d1126dcf58e93cee7d098dbda643b5f92ed724f1f6a63007c1116eed6700c81" -dependencies = [ - "base64 0.12.3", - "log", - "ring", - "sct", - "webpki", -] +checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" [[package]] -name = "rustversion" -version = "1.0.4" +name = "pin-project-lite" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd" +checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" [[package]] -name = "ryu" -version = "1.0.5" +name = "pin-utils" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "same-file" -version = "1.0.6" +name = "pkg-config" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + +[[package]] +name = "pom" +version = "0.1.0" +source = "git+https://github.com/jjs-dev/pps?branch=master#c62718257352fee31f80c3860694d2ad68c78515" dependencies = [ - "winapi-util", + "serde", ] [[package]] -name = "schannel" -version = "0.1.19" +name = "ppv-lite86" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ - "lazy_static", - "winapi 0.3.9", + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", ] [[package]] -name = "scoped-tls" -version = "1.0.0" +name = "proc-macro-error-attr" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] [[package]] -name = "scopeguard" -version = "1.1.0" +name = "proc-macro-hack" +version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] -name = "sct" -version = "0.6.0" +name = "proc-macro-nested" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c" -dependencies = [ - "ring", - "untrusted", -] +checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" [[package]] -name = "security-framework" -version = "0.4.4" +name = "proc-macro2" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535" +checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", + "unicode-xid", ] [[package]] -name = "security-framework-sys" -version = "0.4.3" +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17bf11d99252f512695eb468de5516e5cf75455521e69dfe343f3b74e4748405" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ - "core-foundation-sys", - "libc", + "proc-macro2", ] [[package]] -name = "semver" -version = "0.9.0" +name = "quoted-string" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +checksum = "9586f8867f39941d8e796c18340a9cb5221a018df021169dc3e61c87d9f5f567" dependencies = [ - "semver-parser", + "quick-error", ] [[package]] -name = "semver-parser" -version = "0.7.0" +name = "rand" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +dependencies = [ + "autocfg 0.1.7", + "libc", + "rand_chacha 0.1.1", + "rand_core 0.4.2", + "rand_hc 0.1.0", + "rand_isaac", + "rand_jitter", + "rand_os", + "rand_pcg", + "rand_xorshift", + "winapi 0.3.9", +] [[package]] -name = "serde" -version = "1.0.117" +name = "rand" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" dependencies = [ - "serde_derive", + "libc", + "rand_chacha 0.3.0", + "rand_core 0.6.2", + "rand_hc 0.3.0", ] [[package]] -name = "serde-value" -version = "0.7.0" +name = "rand_chacha" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" dependencies = [ - "ordered-float", - "serde", + "autocfg 0.1.7", + "rand_core 0.3.1", ] [[package]] -name = "serde_bytes" -version = "0.11.5" +name = "rand_chacha" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" dependencies = [ - "serde", + "ppv-lite86", + "rand_core 0.6.2", ] [[package]] -name = "serde_derive" -version = "1.0.117" +name = "rand_core" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", + "rand_core 0.4.2", ] [[package]] -name = "serde_ignored" -version = "0.1.2" +name = "rand_core" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c2c7d39d14f2f2ea82239de71594782f186fd03501ac81f0ce08e674819ff2f" -dependencies = [ - "serde", -] +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" [[package]] -name = "serde_json" -version = "1.0.59" +name = "rand_core" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" dependencies = [ - "indexmap", - "itoa", - "ryu", - "serde", + "getrandom", ] [[package]] -name = "serde_urlencoded" -version = "0.6.1" +name = "rand_hc" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" dependencies = [ - "dtoa", - "itoa", - "serde", - "url", + "rand_core 0.3.1", ] [[package]] -name = "serde_with" -version = "1.5.1" +name = "rand_hc" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bac272128fb3b1e98872dca27a05c18d8b78b9bd089d3edb7b5871501b50bce" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" dependencies = [ - "serde", - "serde_with_macros", + "rand_core 0.6.2", ] [[package]] -name = "serde_with_macros" -version = "1.2.2" +name = "rand_isaac" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c747a9ab2e833b807f74f6b6141530655010bfa9c9c06d5508bce75c8f8072f" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" dependencies = [ - "darling", - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", + "rand_core 0.3.1", ] [[package]] -name = "serde_yaml" -version = "0.8.14" +name = "rand_jitter" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7baae0a99f1a324984bcdc5f0718384c1f69775f1c7eec8b859b71b443e3fd7" +checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" dependencies = [ - "dtoa", - "linked-hash-map", - "serde", - "yaml-rust", + "libc", + "rand_core 0.4.2", + "winapi 0.3.9", ] [[package]] -name = "sha-1" -version = "0.8.2" +name = "rand_os" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" dependencies = [ - "block-buffer 0.7.3", - "digest 0.8.1", - "fake-simd", - "opaque-debug 0.2.3", + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "winapi 0.3.9", ] [[package]] -name = "sha-1" -version = "0.9.1" +name = "rand_pcg" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "170a36ea86c864a3f16dd2687712dd6646f7019f301e57537c7f4dc9f5916770" +checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" dependencies = [ - "block-buffer 0.9.0", - "cfg-if 0.1.10", - "cpuid-bool", - "digest 0.9.0", - "opaque-debug 0.3.0", + "autocfg 0.1.7", + "rand_core 0.4.2", ] [[package]] -name = "sha1" -version = "0.6.0" +name = "rand_xorshift" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +dependencies = [ + "rand_core 0.3.1", +] [[package]] -name = "sha2" -version = "0.8.2" +name = "rdrand" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" dependencies = [ - "block-buffer 0.7.3", - "digest 0.8.1", - "fake-simd", - "opaque-debug 0.2.3", + "rand_core 0.3.1", ] [[package]] -name = "sha2" -version = "0.9.1" +name = "redox_syscall" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 0.1.10", - "cpuid-bool", - "digest 0.9.0", - "opaque-debug 0.3.0", -] +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] -name = "sharded-slab" -version = "0.1.0" +name = "redox_syscall" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4921be914e16899a80adefb821f8ddb7974e3f1250223575a44ed994882127" +checksum = "85dd92e586f7355c633911e11f77f3d12f04b1b1bd76a198bd34ae3af8341ef2" dependencies = [ - "lazy_static", - "loom", + "bitflags", ] [[package]] -name = "signal-hook-registry" -version = "1.2.1" +name = "regex" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e12110bc539e657a646068aaf5eb5b63af9d0c1f7b29c97113fad80e15f035" +checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759" dependencies = [ - "arc-swap", - "libc", + "aho-corasick", + "memchr", + "regex-syntax", ] [[package]] -name = "simple_logger" -version = "1.11.0" +name = "regex-automata" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd57f17c093ead1d4a1499dc9acaafdd71240908d64775465543b8d9a9f1d198" +checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" dependencies = [ - "atty", - "chrono", - "colored", - "log", - "winapi 0.3.9", + "byteorder", + "regex-syntax", ] [[package]] -name = "slab" -version = "0.4.2" +name = "regex-syntax" +version = "0.6.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" [[package]] -name = "smallvec" -version = "0.6.13" +name = "remove_dir_all" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ - "maybe-uninit", + "winapi 0.3.9", ] [[package]] -name = "smallvec" -version = "1.4.2" +name = "reqwest" +version = "0.10.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252" +checksum = "0718f81a8e14c4dbb3b34cf23dc6aaf9ab8a0dfec160c534b3dbca1aaa21f47c" +dependencies = [ + "base64", + "bytes 0.5.6", + "encoding_rs", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "lazy_static", + "log", + "mime 0.3.16", + "mime_guess", + "native-tls", + "percent-encoding", + "pin-project-lite 0.2.6", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-tls", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] [[package]] -name = "socket2" -version = "0.3.15" +name = "rustc_version" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1fa70dc5c8104ec096f4fe7ede7a221d35ae13dcd19ba1ad9a81d2cab9a1c44" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" dependencies = [ - "cfg-if 0.1.10", - "libc", - "redox_syscall", - "winapi 0.3.9", + "semver", ] [[package]] -name = "spin" -version = "0.5.2" +name = "ryu" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] -name = "stable_deref_trait" -version = "1.2.0" +name = "same-file" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] [[package]] -name = "standback" -version = "0.2.11" +name = "schannel" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4e0831040d2cf2bdfd51b844be71885783d489898a192f254ae25d57cce725c" +checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" dependencies = [ - "version_check", + "lazy_static", + "winapi 0.3.9", ] [[package]] -name = "static_assertions" +name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] -name = "stdweb" -version = "0.4.20" +name = "security-framework" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" +checksum = "3670b1d2fdf6084d192bc71ead7aabe6c06aa2ea3fbd9cc3ac111fa5c2b1bd84" dependencies = [ - "discard", - "rustc_version", - "stdweb-derive", - "stdweb-internal-macros", - "stdweb-internal-runtime", - "wasm-bindgen", + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", ] [[package]] -name = "stdweb-derive" -version = "0.5.3" +name = "security-framework-sys" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" +checksum = "3676258fd3cfe2c9a0ec99ce3038798d847ce3e4bb17746373eb9f0f1ac16339" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.7", - "serde", - "serde_derive", - "syn 1.0.48", + "core-foundation-sys", + "libc", ] [[package]] -name = "stdweb-internal-macros" -version = "0.2.9" +name = "semver" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ - "base-x", - "proc-macro2 1.0.24", - "quote 1.0.7", - "serde", - "serde_derive", - "serde_json", - "sha1", - "syn 1.0.48", + "semver-parser", ] [[package]] -name = "stdweb-internal-runtime" -version = "0.1.5" +name = "semver-parser" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] -name = "stringprep" -version = "0.1.2" +name = "serde" +version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "serde_derive", ] [[package]] -name = "strsim" -version = "0.9.3" +name = "serde_derive" +version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" +checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "strsim" -version = "0.10.0" +name = "serde_json" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +dependencies = [ + "itoa", + "ryu", + "serde", +] [[package]] -name = "strum" -version = "0.19.5" +name = "serde_urlencoded" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b89a286a7e3b5720b9a477b23253bc50debac207c8d21505f8e70b36792f11b5" +checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] [[package]] -name = "strum_macros" -version = "0.19.4" +name = "serde_yaml" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e61bb0be289045cb80bfce000512e32d09f8337e54c186725da381377ad1f8d5" +checksum = "15654ed4ab61726bf918a39cb8d98a2e2995b002387807fa6ba58fdf7f59bb23" dependencies = [ - "heck", - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", + "dtoa", + "linked-hash-map", + "serde", + "yaml-rust", ] [[package]] -name = "subtle" -version = "1.0.0" +name = "sharded-slab" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" - -[[package]] -name = "svaluer" -version = "0.1.0" -dependencies = [ - "anyhow", - "crossbeam-channel", - "either", - "invoker-api", - "log", - "pom", - "serde", - "serde_json", - "serde_yaml", - "simple_logger", - "util", +checksum = "79c719719ee05df97490f80a45acfc99e5a30ce98a1e4fb67aee422745ae14e3" +dependencies = [ + "lazy_static", ] [[package]] -name = "syn" -version = "0.15.44" +name = "signal-hook-registry" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "unicode-xid 0.1.0", + "libc", ] [[package]] -name = "syn" -version = "1.0.48" +name = "slab" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac" -dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.7", - "unicode-xid 0.2.1", -] +checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" [[package]] -name = "synstructure" -version = "0.10.2" +name = "smallvec" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" +checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.15.44", - "unicode-xid 0.1.0", + "maybe-uninit", ] [[package]] -name = "synstructure" -version = "0.12.4" +name = "smallvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" + +[[package]] +name = "socket2" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" +checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", - "unicode-xid 0.2.1", + "cfg-if 1.0.0", + "libc", + "winapi 0.3.9", ] [[package]] -name = "take_mut" -version = "0.2.2" +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" +checksum = "ad184cc9470f9117b2ac6817bfe297307418819ba40552f9b3846f05c33d5373" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] [[package]] name = "tar" -version = "0.4.30" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "489997b7557e9a43e192c527face4feacc78bfbe6eed67fd55c4c9e381cba290" +checksum = "c0bcfbd6a598361fda270d82469fff3d65089dc33e175c9a131f7b4cd395f228" dependencies = [ "filetime", "libc", - "redox_syscall", "xattr", ] [[package]] name = "tempfile" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" +checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "libc", - "rand 0.7.3", - "redox_syscall", + "rand 0.8.3", + "redox_syscall 0.2.7", "remove_dir_all", "winapi 0.3.9", ] [[package]] name = "termcolor" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" dependencies = [ "winapi-util", ] [[package]] name = "terminal_size" -version = "0.1.13" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a14cd9f8c72704232f0bfc8455c0e861f0ad4eb60cc9ec8a170e231414c1e13" +checksum = "86ca8ced750734db02076f44132d802af0b33b09942331f4459dde8636fd2406" dependencies = [ "libc", "winapi 0.3.9", @@ -3704,114 +1729,38 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.21" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "318234ffa22e0920fe9a40d7b8369b5f649d490980cf7aadcf1eb91594869b42" +checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.21" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cae2447b6282786c3493999f40a9be2a6ad20cb8bd268b0a0dbf5a065535c0ab" +checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "thread_local" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "threadpool" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" -dependencies = [ - "num_cpus", -] - -[[package]] -name = "time" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi 0.3.9", -] - -[[package]] -name = "time" -version = "0.2.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55b7151c9065e80917fbf285d9a5d1432f60db41d170ccafc749a136b41a93af" -dependencies = [ - "const_fn", - "libc", - "standback", - "stdweb", - "time-macros", - "version_check", - "winapi 0.3.9", -] - -[[package]] -name = "time-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" -dependencies = [ - "proc-macro-hack", - "time-macros-impl", -] - -[[package]] -name = "time-macros-impl" -version = "0.1.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5c3be1edfad6027c69f5491cf4cb310d1a71ecd6af742788c6ff8bced86b8fa" -dependencies = [ - "proc-macro-hack", - "proc-macro2 1.0.24", - "quote 1.0.7", - "standback", - "syn 1.0.48", -] - -[[package]] -name = "tiny-nix-ipc" -version = "0.1.1" -source = "git+https://github.com/myfreeweb/tiny-nix-ipc#373ee4e6756e4c0ef624fdb64dea3a710bb9e4b7" +checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" dependencies = [ - "error-chain", - "nix 0.15.0", - "serde", - "serde_json", - "zerocopy", + "once_cell", ] [[package]] name = "tinyvec" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117" - -[[package]] -name = "tinyvec" -version = "1.0.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b78a366903f506d2ad52ca8dc552102ffdd3e937ba8a227f024dc1d1eae28575" +checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342" dependencies = [ "tinyvec_macros", ] @@ -3824,11 +1773,11 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "0.2.22" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd" +checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092" dependencies = [ - "bytes", + "bytes 0.5.6", "fnv", "futures-core", "iovec", @@ -3838,58 +1787,22 @@ dependencies = [ "mio", "mio-named-pipes", "mio-uds", - "num_cpus", - "pin-project-lite", + "pin-project-lite 0.1.12", "signal-hook-registry", "slab", "tokio-macros", - "tracing", "winapi 0.3.9", ] [[package]] name = "tokio-macros" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" -dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", -] - -[[package]] -name = "tokio-openssl" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c4b08c5f4208e699ede3df2520aca2e82401b2de33f45e96696a074480be594" -dependencies = [ - "openssl", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15cb62a0d2770787abc96e99c1cd98fcf17f94959f3af63ca85bdfb203f051b4" -dependencies = [ - "futures-core", - "rustls 0.17.0", - "tokio", - "webpki", -] - -[[package]] -name = "tokio-rustls" -version = "0.14.1" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12831b255bcfa39dc0436b01e19fea231a37db570686c06ee72c423479f889a" +checksum = "e44da00bfc73a25f814cd8d7e57a68a5c31b74b3152a0a1d1f590c97ed06265a" dependencies = [ - "futures-core", - "rustls 0.18.1", - "tokio", - "webpki", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -3908,63 +1821,51 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" dependencies = [ - "bytes", + "bytes 0.5.6", "futures-core", "futures-sink", "log", - "pin-project-lite", + "pin-project-lite 0.1.12", "tokio", ] [[package]] name = "toml" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" dependencies = [ "serde", ] [[package]] name = "tower-service" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" - -[[package]] -name = "tower-util" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1093c19826d33807c72511e68f73b4a0469a3f22c2bd5f7d5212178b4b89674" -dependencies = [ - "futures-core", - "futures-util", - "pin-project 0.4.27", - "tower-service", -] +checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.21" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0987850db3733619253fe60e17cb59b82d37c7e6c0236bb81e4d6b87c879f27" +checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "log", - "pin-project-lite", + "pin-project-lite 0.2.6", "tracing-attributes", "tracing-core", ] [[package]] name = "tracing-attributes" -version = "0.1.11" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e0ccfc3378da0cce270c946b676a376943f5cd16aeba64568e7939806f4ada" +checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -3978,21 +1879,19 @@ dependencies = [ [[package]] name = "tracing-futures" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" dependencies = [ - "futures 0.3.7", - "futures-task", - "pin-project 0.4.27", + "pin-project", "tracing", ] [[package]] name = "tracing-log" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e0f8c7178e13481ff6765bd169b33e8d554c5d2bbede5e32c356194be02b9b9" +checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" dependencies = [ "lazy_static", "log", @@ -4011,9 +1910,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.2.14" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2810660b9d5b18895d140caba6401765749a6a162e5d0736cfc44ea50db9d79d" +checksum = "705096c6f83bf68ea5d357a6aa01829ddbdac531b357b45abeca842938085baa" dependencies = [ "ansi_term", "chrono", @@ -4023,7 +1922,7 @@ dependencies = [ "serde", "serde_json", "sharded-slab", - "smallvec 1.4.2", + "smallvec 1.6.1", "thread_local", "tracing", "tracing-core", @@ -4031,86 +1930,12 @@ dependencies = [ "tracing-serde", ] -[[package]] -name = "triomphe" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda3a502873984dadbac264124e561c7bda47319733644c2c53c6e67155a53ba" -dependencies = [ - "nodrop", - "serde", - "stable_deref_trait", -] - -[[package]] -name = "trust-dns-proto" -version = "0.19.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdd7061ba6f4d4d9721afedffbfd403f20f39a4301fee1b70d6fcd09cca69f28" -dependencies = [ - "async-trait", - "backtrace", - "enum-as-inner", - "futures 0.3.7", - "idna", - "lazy_static", - "log", - "rand 0.7.3", - "smallvec 1.4.2", - "thiserror", - "tokio", - "url", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.19.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f23cdfdc3d8300b3c50c9e84302d3bd6d860fb9529af84ace6cf9665f181b77" -dependencies = [ - "backtrace", - "cfg-if 0.1.10", - "futures 0.3.7", - "ipconfig", - "lazy_static", - "log", - "lru-cache", - "resolv-conf", - "smallvec 1.4.2", - "thiserror", - "tokio", - "trust-dns-proto", -] - [[package]] name = "try-lock" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" -[[package]] -name = "typed-builder" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e38507a437aef3b8ead39616219615ff9320d0eb0907f0dce51ea0474889cc6" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.15.44", -] - -[[package]] -name = "typenum" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" - -[[package]] -name = "ucd-trie" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" - [[package]] name = "unicase" version = "2.6.0" @@ -4122,27 +1947,27 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" +checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0" dependencies = [ "matches", ] [[package]] name = "unicode-normalization" -version = "0.1.13" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" +checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef" dependencies = [ - "tinyvec 0.3.4", + "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.6.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" +checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" [[package]] name = "unicode-width" @@ -4152,28 +1977,17 @@ checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" [[package]] name = "unicode-xid" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" - -[[package]] -name = "unicode-xid" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" - -[[package]] -name = "untrusted" -version = "0.7.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "url" -version = "2.1.1" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" +checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b" dependencies = [ + "form_urlencoded", "idna", "matches", "percent-encoding", @@ -4189,22 +2003,11 @@ dependencies = [ "tracing-subscriber", ] -[[package]] -name = "uuid" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11" -dependencies = [ - "rand 0.7.3", - "serde", - "sha1", -] - [[package]] name = "vcpkg" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c" +checksum = "cbdbff6266a24120518560b5dc983096efb98462e51d0d68169895b237be3e5d" [[package]] name = "vec_map" @@ -4214,21 +2017,15 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" - -[[package]] -name = "void" -version = "1.0.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" [[package]] name = "walkdir" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" dependencies = [ "same-file", "winapi 0.3.9", @@ -4247,23 +2044,17 @@ dependencies = [ [[package]] name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" +version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.68" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42" +checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "serde", "serde_json", "wasm-bindgen-macro", @@ -4271,26 +2062,26 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.68" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68" +checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae" dependencies = [ "bumpalo", "lazy_static", "log", - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", + "proc-macro2", + "quote", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.18" +version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7866cab0aa01de1edf8b5d7936938a7e397ee50ce24119aef3e1eaa3b6171da" +checksum = "81b8b767af23de6ac18bf2168b690bed2902743ddf0fb39252e36f9e2bfc63ea" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "js-sys", "wasm-bindgen", "web-sys", @@ -4298,77 +2089,43 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.68" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038" +checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f" dependencies = [ - "quote 1.0.7", + "quote", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.68" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe" +checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c" dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.7", - "syn 1.0.48", + "proc-macro2", + "quote", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.68" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307" +checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489" [[package]] name = "web-sys" -version = "0.3.45" +version = "0.3.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bf6ef87ad7ae8008e15a355ce696bed26012b7caa21605188cfd8214ab51e2d" +checksum = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be" dependencies = [ "js-sys", "wasm-bindgen", ] -[[package]] -name = "webpki" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab146130f5f790d45f82aeeb09e55a256573373ec64409fc19a6fb82fb1032ae" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "webpki-roots" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cd5736df7f12a964a5067a12c62fa38e1bd8080aff1f80bc29be7c80d19ab4" -dependencies = [ - "webpki", -] - -[[package]] -name = "webpki-roots" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8eff4b7516a57307f9349c64bf34caa34b940b66fed4b2fb3136cb7386e5739" -dependencies = [ - "webpki", -] - -[[package]] -name = "widestring" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" - [[package]] name = "winapi" version = "0.2.8" @@ -4412,15 +2169,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "winreg" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" -dependencies = [ - "winapi 0.3.9", -] - [[package]] name = "winreg" version = "0.7.0" @@ -4455,44 +2203,17 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" -[[package]] -name = "xmlparser" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "114ba2b24d2167ef6d67d7d04c8cc86522b87f490025f39f0303b7db5bf5e3d8" - [[package]] name = "yaml-rust" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39f0c922f1a334134dc2f7a8b67dc5d25f0735263feec974345ff706bcf20b0d" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" dependencies = [ "linked-hash-map", ] -[[package]] -name = "zerocopy" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "992b9b31f80fd4a167f903f879b8ca43d6716cc368ea01df90538baa2dd34056" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b090467ecd0624026e8a6405d343ac7382592530d54881330b3fc8e400280fa5" -dependencies = [ - "proc-macro2 0.4.30", - "syn 0.15.44", - "synstructure 0.10.2", -] - [[package]] name = "zeroize" -version = "0.9.3" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86" +checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" diff --git a/Cargo.toml b/Cargo.toml index d433987c..98721059 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,29 +5,6 @@ debug = 1 [profile.dev] debug = 1 -# even in debug builds we want toolchain pulling to work fast - -[profile.dev.package.libflate] -opt-level=3 - -[profile.dev.package.libflate_lz77] -opt-level=3 - -[profile.dev.package.adler32] -opt-level=3 - -[profile.dev.package.crc32fast] -opt-level=3 - -[profile.dev.package.rle-decode-fast] -opt-level=3 - -[profile.dev.package.tar] -opt-level=3 - -[profile.dev.package.dkregistry] -opt-level=3 - # Never waste time optimizing `syn` & Co [profile.dev.build-override] @@ -36,6 +13,4 @@ opt-level = 0 [workspace] # TODO: add other as they are fixed members=[ "src/devtool", "src/gen-api-client", "src/cli", "src/client", - "src/problem-loader", "src/invoker", "src/dist-files-generator", - "src/dist-builder", "src/svaluer", "src/invoker-api", "src/pps/api", - "src/pps/cli", "src/pps/server" ] + "src/dist-files-generator", "src/dist-builder"] diff --git a/src/cli/Cargo.toml b/src/cli/Cargo.toml index f452ed98..a8428b5e 100644 --- a/src/cli/Cargo.toml +++ b/src/cli/Cargo.toml @@ -8,7 +8,7 @@ description = "JJS CLI client" [dependencies] util = {path = "../util"} client = {path = "../client"} -pom = { path = "../pom" } +pom = { git = "https://github.com/jjs-dev/pps", branch = "master" } base64 = "0.13.0" serde_json = "1.0.59" serde = "1.0.117" @@ -19,7 +19,7 @@ anyhow = "1.0.33" clap = "3.0.0-beta.2" either = "1.6.1" clap_generate = "3.0.0-beta.2" -dialoguer = "0.7.1" +dialoguer = "0.8.0" xdg = "2.2.0" serde_yaml = "0.8.14" tar = "0.4.30" diff --git a/src/invoker-api/Cargo.toml b/src/invoker-api/Cargo.toml deleted file mode 100644 index 6e9e4f8b..00000000 --- a/src/invoker-api/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "invoker-api" -version = "0.1.0" -authors = ["Mikail Bagishov "] -edition = "2018" - -[dependencies] -serde = { version = "1.0.117", features = ["derive"] } -strum = "0.19.5" -strum_macros = "0.19.4" -bitflags = "1.2.1" -pom = {path = "../pom"} -uuid = { version = "0.8.1", features = ["serde"] } diff --git a/src/invoker-api/src/judge_log.rs b/src/invoker-api/src/judge_log.rs deleted file mode 100644 index a3bff7b6..00000000 --- a/src/invoker-api/src/judge_log.rs +++ /dev/null @@ -1,51 +0,0 @@ -//! Judge log stored in FS -pub use crate::valuer_proto::JudgeLogKind; -use crate::{valuer_proto::SubtaskId, Status, StatusKind}; -use serde::{Deserialize, Serialize}; -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct JudgeLogTestRow { - pub test_id: pom::TestId, - pub status: Option, - pub test_stdin: Option, - pub test_stdout: Option, - pub test_stderr: Option, - pub test_answer: Option, - pub time_usage: Option, - pub memory_usage: Option, -} - -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct JudgeLogSubtaskRow { - pub subtask_id: SubtaskId, - pub score: Option, -} - -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct JudgeLog { - pub kind: JudgeLogKind, - pub tests: Vec, - pub subtasks: Vec, - pub compile_stdout: String, - pub compile_stderr: String, - pub score: u32, - pub is_full: bool, - pub status: Status, -} - -impl Default for JudgeLog { - fn default() -> Self { - Self { - kind: JudgeLogKind::Contestant, - tests: vec![], - subtasks: vec![], - compile_stdout: String::new(), - compile_stderr: String::new(), - score: 0, - is_full: false, - status: Status { - code: "".to_string(), - kind: StatusKind::NotSet, - }, - } - } -} diff --git a/src/invoker-api/src/lib.rs b/src/invoker-api/src/lib.rs deleted file mode 100644 index fb28fdf6..00000000 --- a/src/invoker-api/src/lib.rs +++ /dev/null @@ -1,139 +0,0 @@ -pub mod judge_log; -pub mod valuer_proto; - -use serde::{Deserialize, Serialize}; -use std::path::PathBuf; -use strum_macros::{Display, EnumString}; - -#[derive( - Clone, - Copy, - Debug, - Display, - EnumString, - Ord, - PartialOrd, - PartialEq, - Eq, - Serialize, - Deserialize, - Hash, -)] -pub enum StatusKind { - Queue, - /// WA, TLE, rejected by teacher, etc - Rejected, - /// e.g. Coding Style Violation - CompilationError, - // Evaluated, - Accepted, - NotSet, - InternalError, - Skipped, -} - -impl StatusKind { - pub fn is_success(self) -> bool { - matches!(self, Self::Accepted) - } -} - -pub mod status_codes { - macro_rules! declare_code { - ($code: ident) => { - pub const $code: &str = stringify!($code); - }; - - ($code: ident, $($codes: ident),+) => { - declare_code!($code); - declare_code!($($codes),+); - }; - } - - // build-related status codes - declare_code!( - TOOLCHAIN_SEARCH_ERROR, - BUILT, - COMPILATION_TIMED_OUT, - COMPILER_FAILED - ); - - // per-test status codes - declare_code!( - TIME_LIMIT_EXCEEDED, - RUNTIME_ERROR, - TEST_PASSED, - JUDGE_FAULT, - WRONG_ANSWER, - PRESENTATION_ERROR, - LAUNCH_ERROR - ); - - // aggregated status codes - declare_code!(ACCEPTED, PARTIAL_SOLUTION, BUILD_ERROR); -} - -#[derive(Clone, Debug, Serialize, Deserialize, Ord, PartialOrd, PartialEq, Eq, Hash)] -pub struct Status { - pub kind: StatusKind, - pub code: String, -} - -#[derive(Clone, Serialize, Deserialize)] -pub struct JudgeRequest { - /// Invoker will only update run, if `revision` is bigger than in DB. - pub revision: u32, - /// Toolchain id, for lookup in config - pub toolchain_id: String, - /// Problem id, for lookup in config - pub problem_id: String, - /// Request id (will be preserved by invoker) - pub request_id: uuid::Uuid, - /// Run source - pub run_source: Vec, -} - -impl std::fmt::Debug for JudgeRequest { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("JudgeRequest") - .field("revision", &self.revision) - .field("toolchain_id", &self.toolchain_id) - .field("problem_id", &self.problem_id) - .field("request_id", &self.request_id) - .field( - "run_source", - &format_args!("{} bytes", self.run_source.len()), - ) - .finish() - } -} - -/// Pass this to invoker running in CLI mode -/// -/// See fields' description in [JudgeRequest](JudgeRequest) -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct CliJudgeRequest { - pub revision: u32, - pub toolchain_id: String, - pub problem_id: String, - pub request_id: uuid::Uuid, - pub run_source: PathBuf, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct JudgeOutcomeHeader { - pub score: Option, - pub status: Status, - pub kind: valuer_proto::JudgeLogKind, -} - -/// Represents Live Status Update. Some fields can be None always, or only in some updates. -#[derive(Debug, Serialize, Deserialize)] -pub struct LiveStatusUpdate { - /// Current score. Probably, final score will be greater than or equal to `score`, - /// but it is not guaranteed. - pub score: Option, - /// Id of current test (indexing starts from 1). If solution is executed on several tests, this field will contain - /// last. - pub current_test: Option, -} diff --git a/src/invoker-api/src/valuer_proto.rs b/src/invoker-api/src/valuer_proto.rs deleted file mode 100644 index 71f1b6db..00000000 --- a/src/invoker-api/src/valuer_proto.rs +++ /dev/null @@ -1,124 +0,0 @@ -//! Defines types used to interact between invoker and valuer -use crate::Status; -use bitflags::bitflags; -use pom::TestId; -use serde::{Deserialize, Serialize}; - -bitflags! { - #[derive(Serialize, Deserialize)] - pub struct TestVisibleComponents: u32 { - /// Test input data - const TEST_DATA = 1; - /// Solution stdout & stderr - const OUTPUT = 2; - /// Test answer - const ANSWER = 4; - /// Test status - const STATUS = 8; - /// Resource usage - const RESOURCE_USAGE = 16; - } -} - -bitflags! { - #[derive(Serialize, Deserialize)] - pub struct SubtaskVisibleComponents: u32 { - /// Score gained for this subtask - const SCORE = 1; - } -} - -#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)] -pub struct JudgeLogTestRow { - pub test_id: pom::TestId, - pub status: Status, - pub components: TestVisibleComponents, -} - -#[derive(Debug, Serialize, Deserialize, Copy, Clone, Eq, PartialEq)] -pub struct SubtaskId(pub std::num::NonZeroU32); - -impl SubtaskId { - pub fn make(n: u32) -> SubtaskId { - SubtaskId(std::num::NonZeroU32::new(n).expect("SubtaskId cannot be made from 0")) - } -} - -#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)] -pub struct JudgeLogSubtaskRow { - pub subtask_id: SubtaskId, - pub score: u32, - pub components: SubtaskVisibleComponents, -} - -#[derive(Debug, Serialize, Deserialize, Clone, Copy, Eq, PartialEq)] -pub enum JudgeLogKind { - /// Contains all tests. - /// Test can be omitted, if staring it was speculation. - Full, - /// Contains judge log for contestant - /// Valuer should respect various restrictions specified in config. - Contestant, -} - -impl JudgeLogKind { - pub fn as_str(self) -> &'static str { - match self { - JudgeLogKind::Full => "full", - JudgeLogKind::Contestant => "contestant", - } - } - - pub fn list() -> impl Iterator { - const ALL_KINDS: [JudgeLogKind; 2] = [JudgeLogKind::Contestant, JudgeLogKind::Full]; - ALL_KINDS.iter().copied() - } -} - -/// Judge log from valuer POV -#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)] -pub struct JudgeLog { - pub kind: JudgeLogKind, - pub tests: Vec, - pub subtasks: Vec, - pub score: u32, - pub is_full: bool, -} - -impl Default for JudgeLog { - fn default() -> JudgeLog { - JudgeLog { - kind: JudgeLogKind::Contestant, - tests: Vec::new(), - subtasks: Vec::new(), - score: 0, - is_full: false, - } - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ProblemInfo { - pub tests: Vec, -} - -#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)] -pub struct TestDoneNotification { - pub test_id: TestId, - pub test_status: Status, -} - -#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)] -pub enum ValuerResponse { - Test { - test_id: TestId, - live: bool, - }, - /// Sent when judge log ready - /// Judge log of each kind must be sent at most once - JudgeLog(JudgeLog), - Finish, - LiveScore { - score: u32, - }, -} diff --git a/src/invoker/Cargo.toml b/src/invoker/Cargo.toml deleted file mode 100644 index 4b48a856..00000000 --- a/src/invoker/Cargo.toml +++ /dev/null @@ -1,49 +0,0 @@ - -[package] -name = "invoker" -version = "0.1.0" -authors = ["Mikail Bagishov "] -edition = "2018" - -[dependencies] -minion = {git = "https://github.com/jjs-dev/minion"} -serde = { version = "1.0.117", features = ["derive"] } -serde_json = "1.0.59" -dotenv = "0.15.0" -aho-corasick = "0.7.14" -invoker-api = {path = "../invoker-api"} -pom = {path = "../pom"} -libc = "0.2.80" -nix = "0.19.0" -strum = "0.19.5" -strum_macros = "0.19.4" -chrono = "0.4.19" -tempfile = "3.1.0" -fs_extra = "1.2.0" -base64 = "0.13.0" -bitflags = "1.2.1" -util = {path = "../util"} -anyhow = "1.0.33" -thiserror = "1.0.21" -uuid = { version = "0.8.1", features = ["v5"] } -problem-loader = {path = "../problem-loader"} -tokio = { version = "0.2.22", features = ["rt-core", "process", "io-std", "macros", "fs", "sync"] } -async-trait = "0.1.41" -num_cpus = "1.13.0" -serde_yaml = "0.8.14" -openssl = "0.10.30" -actix-web = { version = "3.2.0", features = ["openssl"], default-features = false } -actix-rt = { version = "1.1.1", default-features = false } -once_cell = "1.4.1" -client = {path = "../client"} -kube = { version = "0.43.0", optional = true } -k8s-openapi = { version = "0.9.0", optional = true, features = ["v1_17"], default-features = false } -puller = { git = "https://github.com/jjs-dev/commons" } -tracing = "0.1.21" -tracing-futures = "0.2.4" -async-mpmc = { git = "https://github.com/jjs-dev/commons" } -multiwake = { git = "https://github.com/jjs-dev/commons" } -dkregistry = { git = "https://github.com/mikailbag/dkregistry-rs", branch = "all" } - -[features] -k8s = ["kube", "k8s-openapi"] diff --git a/src/invoker/Dockerfile b/src/invoker/Dockerfile deleted file mode 100644 index 402e9c5f..00000000 --- a/src/invoker/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM debian:stable-slim -RUN apt-get update -y && apt-get install -y libssl-dev ca-certificates -ENV JJS_DATA=/data -ENV JJS_AUTH_DATA=/auth/authdata.yaml -ENV RUST_BACKTRACE=1 -COPY jjs-invoker /bin/jjs-invoker -ENTRYPOINT ["jjs-invoker"] diff --git a/src/invoker/src/api.rs b/src/invoker/src/api.rs deleted file mode 100644 index cb933d32..00000000 --- a/src/invoker/src/api.rs +++ /dev/null @@ -1,76 +0,0 @@ -//! Defines Invoker API -//! -//! If you just want to use JJS, you should look at apiserver. -//! This API is desired for advanced use cases, such as integrating invoker -//! in custom system. - -use crate::controller::JudgeRequestAndCallbacks; -use actix_web::{web, App, HttpResponse, HttpServer, Responder}; -use anyhow::Context as _; -use tracing::instrument; - -#[derive(Clone)] -struct State { - task_tx: async_mpmc::Sender, - cancel_token: tokio::sync::CancellationToken, -} - -async fn route_ping() -> impl Responder { - HttpResponse::Ok() - .content_type("text/plain") - .body("hello, world!") -} - -async fn route_ready() -> impl Responder { - "" -} - -async fn route_shutdown(state: web::Data) -> impl Responder { - tracing::info!("invoker api: got shutdown request"); - state.cancel_token.cancel(); - "cancellation triggered" -} - -#[actix_rt::main] -#[instrument(skip(task_tx))] -async fn exec( - cancel_token: tokio::sync::CancellationToken, - bind_addr: std::net::SocketAddr, - task_tx: async_mpmc::Sender, -) -> anyhow::Result<()> { - let state = State { - task_tx, - cancel_token: cancel_token.clone(), - }; - - let srv = HttpServer::new(move || { - App::new() - .app_data(web::Data::new(state.clone())) - .wrap(actix_web::middleware::Logger::default()) - .route("/", web::get().to(route_ping)) - .route("/ready", web::get().to(route_ready)) - .route("/state/shutdown", web::post().to(route_shutdown)) - }) - .workers(1) - .disable_signals() - .bind(bind_addr) - .context("unable to bind")? - .run(); - cancel_token.cancelled().await; - srv.stop(false).await; - - Ok(()) -} - -pub async fn start( - cancel_token: tokio::sync::CancellationToken, - bind_addr: std::net::SocketAddr, - task_tx: async_mpmc::Sender, -) -> Result<(), anyhow::Error> { - tokio::task::spawn_blocking(move || { - if let Err(err) = exec(cancel_token, bind_addr, task_tx) { - eprintln!("Invoker api service: serve error: {:#}", err); - } - }); - Ok(()) -} diff --git a/src/invoker/src/config.rs b/src/invoker/src/config.rs deleted file mode 100644 index ec26b428..00000000 --- a/src/invoker/src/config.rs +++ /dev/null @@ -1,58 +0,0 @@ -use serde::{Deserialize, Serialize}; - -#[derive(Deserialize, Serialize, Debug)] -#[serde(deny_unknown_fields)] -#[serde(rename_all = "kebab-case")] -pub struct InvokerConfig { - /// How many workers should be spawned - /// By default equal to processor count - #[serde(default)] - pub workers: Option, - /// API service config - #[serde(default)] - pub api: ApiSvcConfig, - /// If enabled, invoker will directly mount host filesystem instead of - /// toolchain image. - #[serde(default)] - pub host_toolchains: bool, - /// Override directories that will be mounted into sandbox. - /// E.g. if `expose-host-dirs = ["lib64", "usr/lib"]`, - /// then invoker will mount: - /// - `$SANDBOX_ROOT/lib64` -> `/lib64` - /// - `$SANDBOX_ROOT/usr/lib` -> `/usr/lib` - /// As usual, all mounts will be no-suid and read-only. - #[serde(default)] - pub expose_host_dirs: Option>, - /// Configures how invoker should resolve problems - pub problems: problem_loader::LoaderConfig, -} - -#[derive(Deserialize, Serialize, Debug)] -#[serde(deny_unknown_fields)] -pub struct ApiSvcConfig { - /// Override bind IP - #[serde(default = "ApiSvcConfig::default_address")] - pub address: String, - /// Override bind port - #[serde(default = "ApiSvcConfig::default_port")] - pub port: u16, -} - -impl ApiSvcConfig { - fn default_address() -> String { - "0.0.0.0".to_string() - } - - fn default_port() -> u16 { - 1789 - } -} - -impl Default for ApiSvcConfig { - fn default() -> Self { - ApiSvcConfig { - address: ApiSvcConfig::default_address(), - port: ApiSvcConfig::default_port(), - } - } -} diff --git a/src/invoker/src/controller.rs b/src/invoker/src/controller.rs deleted file mode 100644 index 19d1243d..00000000 --- a/src/invoker/src/controller.rs +++ /dev/null @@ -1,208 +0,0 @@ -//! Invoker controller -//! -//! Controller is the heart of invoker - it receives InvokeTasks from -//! TaskSources, wraps them into Jobs, schedules this Jobs into workers -//! and publishes Job outcomes. -mod notify; -mod task_loading; -mod toolchains; - -use crate::{ - scheduler::Scheduler, - worker::{JudgeOutcome, Request, Response}, -}; -use anyhow::Context; -use notify::Notifier; -use std::{ - path::{Path, PathBuf}, - sync::Arc, -}; -use tracing::{debug, info, instrument}; -use uuid::Uuid; - -/// Contains additional stuff for controller itself -#[derive(Debug)] -struct LoweredJudgeRequestExtensions { - notifier: Notifier, - invocation_dir: PathBuf, -} - -pub enum InvocationFinishReason { - Fault, - CompileError, - TestingDone, -} - -/// Contains both judging task and back address. -/// Each task source is represented as mpsc channel of `TaskInfo`s -pub struct JudgeRequestAndCallbacks { - pub request: invoker_api::JudgeRequest, - pub callbacks: Arc, -} - -impl std::fmt::Debug for JudgeRequestAndCallbacks { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("JudgeRequestAndCallbacks") - .field("request", &self.request) - .field("handler", &"..") - .finish() - } -} - -#[async_trait::async_trait] -pub trait JudgeResponseCallbacks: Send + Sync { - async fn set_finished( - &self, - invocation_id: Uuid, - reason: InvocationFinishReason, - ) -> anyhow::Result<()>; - - /// Called when a judge log is available. - /// kinds can be duplicated after a judge fault. - async fn add_outcome_header( - &self, - invocation_id: Uuid, - header: invoker_api::JudgeOutcomeHeader, - ) -> anyhow::Result<()>; - - async fn deliver_live_status_update( - &self, - invocation_id: Uuid, - lsu: invoker_api::LiveStatusUpdate, - ) -> anyhow::Result<()>; -} - -#[derive(Clone)] -pub struct Controller { - scheduler: Arc, - problem_loader: Arc, - toolchains_dir: Arc, - _config: Arc, - // used as RAII resource owner - _temp_dir: Arc, - toolchain_loader: Arc, -} - -fn get_num_cpus() -> usize { - static CACHE: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0); - let old = CACHE.load(std::sync::atomic::Ordering::Relaxed); - if old != 0 { - return old; - } - let corr = num_cpus::get(); - assert_ne!(corr, 0); - CACHE.store(corr, std::sync::atomic::Ordering::Relaxed); - corr -} - -impl Controller { - pub async fn new( - cfg_data: util::cfg::CfgData, - config: Arc, - ) -> anyhow::Result { - let worker_count = match config.workers { - Some(cnt) => cnt, - None => get_num_cpus(), - }; - info!("Using {} workers", worker_count); - let mut scheduler = Scheduler::new(&config).context("failed to initialize Scheduler")?; - for _ in 0..worker_count { - scheduler - .add_worker() - .await - .context("failed to start a worker")?; - } - let scheduler = Arc::new(scheduler); - - let temp_dir = tempfile::TempDir::new().context("can not find temporary dir")?; - - let problem_loader = - problem_loader::Loader::from_config(&config.problems, temp_dir.path().join("problems")) - .await - .context("can not create ProblemLoader")?; - let toolchain_loader = Arc::new( - toolchains::ToolchainLoader::new() - .await - .context("toolchain loader initialization error")?, - ); - Ok(Controller { - scheduler, - problem_loader: Arc::new(problem_loader), - toolchains_dir: cfg_data.data_dir.join("opt").into(), - _config: config, - _temp_dir: Arc::new(temp_dir), - toolchain_loader, - }) - } - - #[instrument(skip(self, chan))] - pub fn exec_on(self, chan: async_mpmc::Receiver) { - chan.process_all(move |req| { - let this = self.clone(); - - async move { - let request_id = req.request.request_id; - if let Err(err) = this.process_request(req).await { - tracing::warn!(request_id = %request_id, - err = %format_args!("{:#}", err), - "Failed to process a judge request"); - } - } - }); - } - - /// This function drives lifecycle of single judge request. - #[instrument(skip(self, req), fields(request_id=%req.request.request_id))] - async fn process_request(&self, req: JudgeRequestAndCallbacks) -> anyhow::Result<()> { - let (low_req, mut exts) = self - .lower_judge_request(&req) - .await - .context("request preprocessing failed")?; - - debug!(lowered_judge_request = ?low_req, "created a lowered judge request"); - - // TODO currently the process of finding a worker is unfair - // we should fix it e.g. using a semaphore which permits finding - // worker. - let worker = self.scheduler.find_free_worker().await; - // TODO: can we split into LoweredJudgeRequest and Extensions? - let mut responses = worker - .send(Request::Judge(low_req)) - .await - .context("failed to submit lowered judge request")?; - loop { - let message = responses - .next() - .await - .context("failed to receive next worker message")?; - match message { - Response::JudgeDone(judge_outcome) => { - debug!("Publising: JudgeOutcome {:?}", &judge_outcome); - let reason = match judge_outcome { - JudgeOutcome::Fault => InvocationFinishReason::Fault, - JudgeOutcome::TestingDone => InvocationFinishReason::TestingDone, - JudgeOutcome::CompileError(_) => InvocationFinishReason::CompileError, - }; - req.callbacks - .set_finished(req.request.request_id, reason) - .await - .context("failed to set run outcome in DB")?; - break; - } - Response::LiveScore(score) => { - exts.notifier.set_score(score).await; - } - Response::LiveTest(test) => { - exts.notifier.set_test(test).await; - } - Response::OutcomeHeader(header) => { - req.callbacks - .add_outcome_header(req.request.request_id, header) - .await?; - } - } - } - - Ok(()) - } -} diff --git a/src/invoker/src/controller/notify.rs b/src/invoker/src/controller/notify.rs deleted file mode 100644 index 14b06743..00000000 --- a/src/invoker/src/controller/notify.rs +++ /dev/null @@ -1,93 +0,0 @@ -//! Implements Notifications - messages about run testing updates -use crate::controller::JudgeResponseCallbacks; -use std::{ - sync::Arc, - time::{Duration, Instant}, -}; -use tracing::{debug, instrument, warn}; -pub(crate) struct Notifier { - score: Option, - test: Option, - throttled_until: Instant, - errored: bool, - handler: Arc, - judge_request_id: uuid::Uuid, -} - -impl std::fmt::Debug for Notifier { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - f.debug_struct("Notifier") - .field("score", &self.score) - .field("test", &self.test) - .field("throttled_until", &self.throttled_until) - .field("errored", &self.errored) - .field("judge_request_id", &self.judge_request_id) - .finish() - } -} - -impl Notifier { - pub(crate) fn new( - judge_request_id: uuid::Uuid, - handler: Arc, - ) -> Notifier { - Notifier { - score: None, - test: None, - throttled_until: Instant::now(), - errored: false, - handler, - judge_request_id, - } - } - - pub(crate) async fn set_score(&mut self, score: u32) { - self.score = Some(score); - self.maybe_drain().await - } - - pub(crate) async fn set_test(&mut self, test: u32) { - self.test = Some(test); - self.maybe_drain().await - } - - async fn maybe_drain(&mut self) { - let mut has_something = false; - has_something = has_something || self.score.is_some(); - has_something = has_something || self.test.is_some(); - if !has_something { - return; - } - if self.errored { - return; - } - if self.throttled_until > Instant::now() { - return; - } - self.drain().await - } - - #[instrument(skip(self), fields(judge_request_id=%self.judge_request_id))] - async fn drain(&mut self) { - let event = invoker_api::LiveStatusUpdate { - score: self.score.take().map(|x| x as i32), - current_test: self.test.take(), - }; - debug!( - update=?event, - "Sending live status update", - ); - if let Err(err) = self - .handler - .deliver_live_status_update(self.judge_request_id, event) - .await - { - warn!(error=%format_args!("{:#}", err), "Failed to send live status update"); - warn!("Disabling live status updates for this run"); - self.errored = true; - } - self.throttled_until = Instant::now() + LIVE_STATUS_UPDATE_THROTTLE; - } -} - -const LIVE_STATUS_UPDATE_THROTTLE: Duration = Duration::from_millis(250); diff --git a/src/invoker/src/controller/task_loading.rs b/src/invoker/src/controller/task_loading.rs deleted file mode 100644 index d7fe5b50..00000000 --- a/src/invoker/src/controller/task_loading.rs +++ /dev/null @@ -1,210 +0,0 @@ -//! Implements Controller functionality related to getting tasks and publishing results -use super::{ - notify::Notifier, Controller, JudgeRequestAndCallbacks, LoweredJudgeRequestExtensions, -}; -use crate::worker::{self, LoweredJudgeRequest}; -use anyhow::Context; -use std::{ - collections::{HashMap, HashSet}, - path::PathBuf, -}; -use tracing::instrument; -use uuid::Uuid; - -#[derive(Debug, Clone, thiserror::Error)] -pub(crate) enum InterpolateError { - #[error("template syntax violation: {message}")] - BadSyntax { message: &'static str }, - #[error("unknown key {key} in command template")] - MissingKey { key: String }, -} - -/// Interpolates string by dictionary -/// -/// Few examples of correct template strings: -/// - foo -/// - fo$(KeyName) -/// - fo$$$$(SomeKey) -/// -/// Few examples of incorrect strings: -/// - $( -/// - $(SomeKey)) -pub(crate) fn interpolate_string( - string: &str, - dict: &HashMap, -) -> Result { - let ak = aho_corasick::AhoCorasick::new_auto_configured(&["$(", ")"]); - let matches = ak.find_iter(string); - let mut out = String::new(); - let mut cur_pos = 0; - let mut next_pat_id = 0; - for m in matches { - if m.pattern() != next_pat_id { - return Err(InterpolateError::BadSyntax { - message: "get pattern start while parsing pattern or pattern end outside of pattern", - }); - } - - let chunk = &string[cur_pos..m.start()]; - cur_pos = m.end(); - if next_pat_id == 0 { - out.push_str(chunk); - } else { - match dict.get(chunk) { - Some(ref val) => { - out.push_str(val); - } - None => { - return Err(InterpolateError::MissingKey { - key: chunk.to_string(), - }); - } - } - } - next_pat_id = 1 - next_pat_id; - } - let tail = &string[cur_pos..]; - out.push_str(tail); - Ok(out) -} - -fn interpolate_command( - command: &super::toolchains::Command, - dict: &HashMap, - toolchain_spec: &super::toolchains::ToolchainSpec, -) -> Result { - let mut res: worker::Command = Default::default(); - for arg in &command.argv { - let interp = interpolate_string(arg, dict)?; - res.argv.push(interp); - } - let mut used_env_vars = HashSet::new(); - for (name, val) in &command.env { - let name = interpolate_string(name, dict)?; - let val = interpolate_string(val, dict)?; - res.env.push(format!("{}={}", name, val)); - used_env_vars.insert(name); - } - res.cwd = interpolate_string(&command.cwd, dict)?; - for (default_key, default_val) in &toolchain_spec.env { - if !used_env_vars.contains(default_key) { - res.env.push(format!("{}={}", default_key, default_val)); - } - } - Ok(res) -} - -pub(crate) fn get_common_interpolation_dict( - toolchain: &super::toolchains::ToolchainSpec, -) -> HashMap { - let mut dict = HashMap::new(); - dict.insert("Invoker.Id".to_string(), String::from("inv")); - dict.insert( - "Run.SourceFilePath".to_string(), - PathBuf::from("/jjs") - .join(&toolchain.filename) - .display() - .to_string(), - ); - dict.insert("Run.BinaryFilePath".to_string(), "/jjs/build".into()); - dict -} - -impl Controller { - /// This functions queries all related data about run and returns InvokeRequest - /// - /// `JudgeRequestAndCallbacks` is not single source of trust, and some - /// information needs to be taken from config. - /// But LoweredJudgeRequestWithExtensions **is** SSoT, and worker is - /// completely isolated from other components. - #[instrument(skip(self, judge_request_and_cbs))] - pub(super) async fn lower_judge_request( - &self, - judge_request_and_cbs: &JudgeRequestAndCallbacks, - ) -> anyhow::Result<(LoweredJudgeRequest, LoweredJudgeRequestExtensions)> { - let mut run_metadata = HashMap::new(); - let judge_time = { - let time = chrono::prelude::Utc::now(); - time.format("%Y-%m-%d %H:%M:%S").to_string() - }; - run_metadata.insert("JudgeTimeUtc".to_string(), judge_time); - { - let mut buf = Uuid::encode_buffer(); - let s = judge_request_and_cbs - .request - .request_id - .to_hyphenated_ref() - .encode_lower(&mut buf); - run_metadata.insert("InvokeRequestId".to_string(), s.to_owned()); - } - let problem_name = &judge_request_and_cbs.request.problem_id; - let (problem, problem_dir) = self - .problem_loader - .find(problem_name) - .await - .and_then(|opt| opt.ok_or_else(|| anyhow::anyhow!("unknown problem"))) - .with_context(|| format!("can not find problem `{}`", problem_name))?; - - let toolchain_info = self - .toolchain_loader - .resolve(&judge_request_and_cbs.request.toolchain_id) - .await - .context("toolchain loading error")?; - - let toolchain_spec = toolchain_info.get_spec(); - - let temp_invocation_dir = tokio::task::spawn_blocking(tempfile::tempdir) - .await - .unwrap() - .context("failed to create temporary dir")?; - tracing::debug!(invocation_temporary_directory=%temp_invocation_dir.path().display()); - let run_source_temp_file = temp_invocation_dir.path().join("source"); - tokio::fs::write( - &run_source_temp_file, - &judge_request_and_cbs.request.run_source, - ) - .await - .context("unable to save run source in FS")?; - - let temp_invocation_dir = temp_invocation_dir.into_path(); - let interp_dict = { - let mut dict = get_common_interpolation_dict(&toolchain_spec); - for (k, v) in run_metadata { - dict.insert(format!("Run.Meta.{}", k), v); - } - dict - }; - tracing::debug!(interpolation_values=?interp_dict, "interpolation context"); - let compile_commands = toolchain_spec - .build_commands - .iter() - .map(|c| interpolate_command(c, &interp_dict, &toolchain_spec)) - .collect::>() - .context("invalid build commands template")?; - let execute_command = - interpolate_command(&toolchain_spec.run_command, &interp_dict, &toolchain_spec) - .context("invalid run command template")?; - let low_judge_request = LoweredJudgeRequest { - compile_commands, - execute_command, - - compile_limits: toolchain_spec.limits, - problem_dir: problem_dir.to_path_buf(), - source_file_name: toolchain_spec.filename.clone(), - problem: problem.clone(), - run_source: run_source_temp_file, - out_dir: temp_invocation_dir.clone(), - judge_request_id: judge_request_and_cbs.request.request_id, - toolchain_dir: toolchain_info.path, - }; - let exts = LoweredJudgeRequestExtensions { - notifier: Notifier::new( - judge_request_and_cbs.request.request_id, - judge_request_and_cbs.callbacks.clone(), - ), - invocation_dir: temp_invocation_dir, - }; - - Ok((low_judge_request, exts)) - } -} diff --git a/src/invoker/src/controller/toolchains.rs b/src/invoker/src/controller/toolchains.rs deleted file mode 100644 index 9ce9a80b..00000000 --- a/src/invoker/src/controller/toolchains.rs +++ /dev/null @@ -1,184 +0,0 @@ -//! This module is responsible for toolchain loading -use anyhow::Context as _; -use dkregistry::v2::manifest::{Manifest, RuntimeConfig}; -use std::{ - collections::HashMap, - path::{Path, PathBuf}, -}; -use tracing::{debug, instrument}; - -#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)] -pub struct ToolchainSpec { - /// Human-readable - pub title: String, - - /// Machine-readable - pub name: String, - - pub filename: String, - - #[serde(rename = "build")] - pub build_commands: Vec, - - #[serde(rename = "run")] - pub run_command: Command, - - #[serde(rename = "build-limits", default)] - pub limits: pom::Limits, - - #[serde(rename = "env", default)] - pub env: HashMap, - - #[serde(rename = "env-passing", default)] - pub env_passing: bool, - - #[serde(rename = "env-blacklist", default)] - pub env_blacklist: Vec, -} - -#[derive(serde::Serialize, serde::Deserialize, Default, Debug, Clone)] -pub struct Command { - #[serde(default = "Command::default_env")] - pub env: HashMap, - pub argv: Vec, - #[serde(default = "Command::default_cwd")] - pub cwd: String, -} - -impl Command { - fn default_env() -> HashMap { - HashMap::new() - } - - fn default_cwd() -> String { - String::from("/jjs") - } -} - -#[derive(Clone)] -pub struct ResolvedToolchainInfo { - spec: ToolchainSpec, - pub path: PathBuf, - image_config: ImageConfig, -} -impl ResolvedToolchainInfo { - /// Returns toolchain spec, with applied information from docker image - pub fn get_spec(&self) -> ToolchainSpec { - let mut tc = self.spec.clone(); - for (k, v) in self.image_config.environment.clone() { - tc.env.insert(k, v); - } - tc - } -} - -/// Contains some data, extracted from image manifest -#[derive(serde::Serialize, serde::Deserialize, Clone)] -pub struct ImageConfig { - pub environment: Vec<(String, String)>, -} - -impl ImageConfig { - fn parse_env_item(item: &str) -> Option<(String, String)> { - let mut parts = item.splitn(2, '='); - let key = parts.next()?; - let value = parts.next()?; - Some((key.to_string(), value.to_string())) - } - - fn from_run_config(rc: RuntimeConfig) -> anyhow::Result { - let environment = rc - .env - .unwrap_or_default() - .into_iter() - .map(|item| ImageConfig::parse_env_item(&item)) - .map(|item| item.context("environment string does not look like key=value")) - .collect::>>()?; - Ok(Self { environment }) - } -} - -/// Responsible for fetching toolchains -pub struct ToolchainLoader { - puller: puller::Puller, - toolchains_dir: tempfile::TempDir, - /// Cache for already pulled toolchains. - cache: HashMap, -} - -impl ToolchainLoader { - pub async fn new() -> anyhow::Result { - let puller = puller::Puller::new().await; - let toolchains_dir = tempfile::TempDir::new()?; - Ok(ToolchainLoader { - toolchains_dir, - puller, - cache: HashMap::new(), - }) - } - - /// Actually downloads and unpacks toolchain to specified dir. - #[instrument(skip(self, toolchain_url, target_dir))] - async fn extract_toolchain( - &self, - toolchain_url: &str, - target_dir: &Path, - ) -> anyhow::Result { - debug!(target_dir=%target_dir.display(), "downloading image"); - tokio::fs::create_dir(target_dir) - .await - .context("failed to create target dir")?; - - let image_manifest = self - .puller - .pull( - toolchain_url, - target_dir, - tokio::sync::CancellationToken::new(), - ) - .await - .context("failed to pull toolchain")?; - let image_manifest = match image_manifest { - Manifest::S2(im_v2) => im_v2, - _ => anyhow::bail!("Unsupported manifest: only schema2 is supported"), - }; - let config_blob = image_manifest.config_blob; - - let runtime_config = config_blob - .runtime_config - .context("image manifest does not have RunConfig")?; - - let image_config = ImageConfig::from_run_config(runtime_config) - .context("failed to process config blob")?; - debug!("toolchain has been pulled successfully"); - Ok(image_config) - } - - #[instrument(skip(self))] - pub async fn resolve(&self, toolchain_url: &str) -> anyhow::Result { - if let Some(info) = self.cache.get(toolchain_url) { - return Ok(info.clone()); - } - let toolchain_dir = self - .toolchains_dir - .path() - .join(base64::encode(toolchain_url)); - - let image_config = self - .extract_toolchain(toolchain_url, &toolchain_dir) - .await - .context("toolchain download error")?; - - let toolchain_spec_path = toolchain_dir.join("manifest.yaml"); - let toolchain_spec = tokio::fs::read(toolchain_spec_path) - .await - .context("toolchain config file (manifest.yaml in image root) missing")?; - let toolchain_spec: ToolchainSpec = - serde_yaml::from_slice(&toolchain_spec).context("invalid toolchain spec")?; - Ok(ResolvedToolchainInfo { - path: toolchain_dir, - spec: toolchain_spec, - image_config, - }) - } -} diff --git a/src/invoker/src/init.rs b/src/invoker/src/init.rs deleted file mode 100644 index 3c083be9..00000000 --- a/src/invoker/src/init.rs +++ /dev/null @@ -1,42 +0,0 @@ -//! platform-specific initialization -use anyhow::{bail, Context}; -use nix::sched::CloneFlags; -fn check_system() -> anyhow::Result<()> { - if let Some(err) = minion::check() { - bail!("invoker is not able to test runs: {}", err); - } - Ok(()) -} - -fn unshare_mount_namespace() -> anyhow::Result<()> { - nix::sched::unshare(CloneFlags::CLONE_NEWNS).context("unshare() fail") -} - -fn unshare_user_namespace() -> anyhow::Result<()> { - if nix::unistd::getuid().is_root() { - return Ok(()); - } - let uid = nix::unistd::getuid().as_raw(); - let gid = nix::unistd::getgid().as_raw(); - let uid_mapping = format!("0 {} 1", uid); - let gid_mapping = format!("0 {} 1", gid); - nix::sched::unshare(CloneFlags::CLONE_NEWUSER).context("unshare() fail")?; - std::fs::write("/proc/self/setgroups", "deny").context("failed to deny setgroups()")?; - std::fs::write("/proc/self/uid_map", uid_mapping).context("failed to setup uid mapping")?; - std::fs::write("/proc/self/gid_map", gid_mapping).context("failed to setup gid mapping")?; - nix::unistd::setuid(nix::unistd::Uid::from_raw(0)).expect("failed to become root user"); - nix::unistd::setgid(nix::unistd::Gid::from_raw(0)).expect("failed to join root group"); - Ok(()) -} - -fn unshare() -> anyhow::Result<()> { - unshare_user_namespace().context("failed to unshare user ns")?; - unshare_mount_namespace().context("failed to unshare mount ns")?; - Ok(()) -} - -pub fn init() -> anyhow::Result<()> { - check_system().context("system configuration problem detected")?; - unshare().context("failed to create namespaces")?; - Ok(()) -} diff --git a/src/invoker/src/lib.rs b/src/invoker/src/lib.rs deleted file mode 100644 index 6b17d7f1..00000000 --- a/src/invoker/src/lib.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![type_length_limit = "4323264"] -pub mod api; -pub mod config; -pub mod controller; -pub mod init; -mod scheduler; -pub mod sources; -pub mod worker; diff --git a/src/invoker/src/main.rs b/src/invoker/src/main.rs deleted file mode 100644 index de0f7aaa..00000000 --- a/src/invoker/src/main.rs +++ /dev/null @@ -1,214 +0,0 @@ -#![type_length_limit = "4323264"] -use anyhow::Context; -use invoker::controller::JudgeRequestAndCallbacks; -use std::sync::Arc; -use tracing::{info, instrument, warn}; -fn is_cli_mode() -> bool { - std::env::args().count() > 1 -} - -async fn start_request_providers( - cancel: tokio::sync::CancellationToken, - chan: async_mpmc::Sender, -) -> anyhow::Result<()> { - if is_cli_mode() { - info!("spawning CliSource"); - tokio::task::spawn(invoker::sources::cli_source::run(chan, cancel)); - } else { - info!("Establishing apiserver connection"); - let api = client::infer().await.context("API connection failed")?; - info!("Spawning ApiSource"); - let api_source = invoker::sources::ApiSource::new(api, chan); - tokio::task::spawn(async move { - api_source.run(cancel).await; - }); - } - Ok(()) -} - -fn worker_self_isolate() -> anyhow::Result<()> { - #[cfg(target_os = "linux")] - { - // TODO: unshare NEWNET too. To achieve it, we have to switch to multiprocessing instead of multithreading - nix::sched::unshare(nix::sched::CloneFlags::CLONE_FILES).context("failed to unshare")?; - } - Ok(()) -} - -fn is_worker() -> bool { - std::env::var("__JJS_WORKER").is_ok() -} - -fn main() -> anyhow::Result<()> { - dotenv::dotenv().ok(); - util::log::setup(); - if is_worker() { - invoker::init::init().context("failed to initialize")?; - worker_self_isolate()?; - } - let mut rt = tokio::runtime::Builder::new(); - rt.basic_scheduler(); - if is_worker() { - rt.max_threads(4); - } - let mut rt = rt.enable_all().core_threads(1).build()?; - rt.block_on(async { - let cancel_token = tokio::sync::CancellationToken::new(); - let res = real_main(cancel_token.clone()).await; - if res.is_err() { - cancel_token.cancel(); - } - res - }) -} -#[instrument(skip(judge_requests))] -async fn start_controller( - config: Arc, - system_config_data: util::cfg::CfgData, - judge_requests: async_mpmc::Receiver, -) -> anyhow::Result<()> { - info!("Starting controller"); - let controller = invoker::controller::Controller::new(system_config_data, config) - .await - .context("failed to start controller")?; - controller.exec_on(judge_requests); - Ok(()) -} - -async fn real_main(cancel_token: tokio::sync::CancellationToken) -> anyhow::Result<()> { - if is_worker() { - return invoker::worker::main().await; - } - - let system_config_data = util::cfg::load_cfg_data()?; - - // now we should fetch InvokerConfig - // we have generic `get_config_from_fs` and specific `get_config_from_k8s` - let invoker_config = { - if let Some(cfg) = get_config_from_k8s().await? { - info!("Got config from Kubernetes"); - cfg - } else { - info!("Loading config from FS"); - get_config_from_fs(&system_config_data).await? - } - }; - // TODO probably broken for IPv6 - let bind_address = format!("{}:{}", invoker_config.api.address, invoker_config.api.port); - let bind_address = bind_address - .parse() - .with_context(|| format!("invalid bind address {}", bind_address))?; - - let (judge_request_tx, judge_request_rx) = async_mpmc::channel(); - - invoker::api::start(cancel_token.clone(), bind_address, judge_request_tx.clone()) - .await - .context("failed to start api")?; - - info!("API service started"); - start_request_providers(cancel_token.clone(), judge_request_tx) - .await - .context("failed to initialize request providers")?; - start_controller( - Arc::new(invoker_config), - system_config_data, - judge_request_rx, - ) - .await - .context("can not start controller")?; - { - let cancel_token = cancel_token.clone(); - tokio::task::spawn(async move { - info!("Installing signal hook"); - tokio::select! { - res = tokio::signal::ctrl_c() => { - match res { - Ok(_) => { - info!("Received ctrl-c"); - cancel_token.cancel(); - } - Err(err) => warn!(error=%err, "Failed to wait for signal"), - } - } - _ = cancel_token.cancelled() => () - } - }); - } - cancel_token.cancelled().await; - info!("Received shutdown request; exiting gracefully"); - Ok(()) -} - -pub async fn get_config_from_fs( - cfg_data: &util::cfg::CfgData, -) -> anyhow::Result { - let invoker_config_file_path = cfg_data.data_dir.join("etc/invoker.yaml"); - let invoker_config_data = tokio::fs::read(&invoker_config_file_path) - .await - .with_context(|| { - format!( - "unable to read config from {}", - invoker_config_file_path.display() - ) - })?; - - info!(path=%invoker_config_file_path.display(), "Found config"); - - serde_yaml::from_slice(&invoker_config_data).context("config parse error") -} - -/// Fetches config from Kubernetes ConfigMap. -/// Returns Ok(Some(config)) on success, Err(err) on error -/// and Ok(None) if not running inside kubernetes -pub async fn get_config_from_k8s() -> anyhow::Result> { - #[cfg(feature = "k8s")] - return get_config_from_k8s_inner().await; - #[cfg(not(feature = "k8s"))] - return Ok(None); -} - -#[cfg(feature = "k8s")] -async fn get_config_from_k8s_inner() -> anyhow::Result> { - let incluster_config = match kube::Config::from_cluster_env() { - Ok(conf) => conf, - Err(err) => { - let is_caused_by_non_k8s_environment = matches!( - &err, - kube::error::Error::Kubeconfig( - kube::error::ConfigError::MissingInClusterVariables { .. }, - ) - ); - if is_caused_by_non_k8s_environment { - return Ok(None); - } else { - anyhow::bail!("failed to infer k8s config: {}", err); - } - } - }; - let namespace = incluster_config.default_ns.clone(); - info!(cluster_api_url=%incluster_config.cluster_url, - namespace=%incluster_config.default_ns, - "Discovered Kuberentes API-server", - ); - let client = kube::Client::new(incluster_config); - - let configmaps_api = - kube::Api::::namespaced(client, &namespace); - let config_map_name = std::env::var("CONFIGMAP").unwrap_or_else(|_| "jjs-config".to_string()); - - let configmap = configmaps_api - .get(&config_map_name) - .await - .context("can not read ConfigMap with configuration")?; - - tracing::debug!("Resolved ConfigMap"); - - let config_map_key_name = - std::env::var("CONFIGMAP_KEY").unwrap_or_else(|_| "judge".to_string()); - let config_data = match &configmap.data { - Some(data) => data.get(&config_map_key_name), - None => None, - } - .context("ConfigMap does not have key with configuration")?; - serde_yaml::from_str(&config_data).context("config parse error") -} diff --git a/src/invoker/src/scheduler.rs b/src/invoker/src/scheduler.rs deleted file mode 100644 index 75f57333..00000000 --- a/src/invoker/src/scheduler.rs +++ /dev/null @@ -1,242 +0,0 @@ -// maybe it's overengineered but it's fun - -use crate::{ - config::InvokerConfig, - worker::{Request, Response}, -}; -use anyhow::Context as _; -use std::sync::atomic::{AtomicU8, Ordering::SeqCst}; -use tokio::{ - io::{AsyncBufReadExt, AsyncWriteExt}, - sync::Mutex, -}; -use tracing::{debug, instrument}; -/// Scheduler is responsible for finding a suitable worker for a task -pub struct Scheduler { - workers: Vec, - /// We need it because we must pass it to a worker. - // TODO: ideally we do not want to pass any configs to a worker - config: String, - /// these field is used to signal that a worker is reclaimed - worker_reclamation: (multiwake::Sender, multiwake::Receiver), -} - -impl Scheduler { - /// Creates new Scheduler with empty `workers` set - pub fn new(config: &InvokerConfig) -> anyhow::Result { - let config = serde_json::to_string(&config).context("failed to serialize InvokerConfig")?; - Ok(Scheduler { - workers: vec![], - config, - worker_reclamation: multiwake::multiwake(), - }) - } - - /// Starts new worker process and adds it to this scheduler - #[instrument(skip(self))] - pub async fn add_worker(&mut self) -> anyhow::Result<()> { - let mut child = tokio::process::Command::new(std::env::current_exe()?) - .env("__JJS_WORKER", "1") - .env("__JJS_WORKER_INVOKER_CONFIG", &self.config) - .stdin(std::process::Stdio::piped()) - .stdout(std::process::Stdio::piped()) - .spawn() - .context("failed to spawn worker")?; - let info = WorkerInfo { - state: WorkerState::new(WorkerStateKind::Idle), - child_stdin: Mutex::new(child.stdin.take().expect("child stdin was captured")), - child_stdout: Mutex::new(tokio::io::BufReader::new( - child.stdout.take().expect("child stdout was captured"), - )), - }; - self.workers.push(info); - Ok(()) - } - - /// Tries to find a free worker. On success, returns `FreeWorkerHandle`, - /// which can be used to send requests to that worker. - #[instrument(skip(self))] - pub async fn find_free_worker(&self) -> FreeWorkerHandle<'_> { - let mut receiver = self.worker_reclamation.1.clone(); - let mut attempt_id = 0u32; - loop { - debug!(attempt_id, "scanning all workers"); - attempt_id += 1; - for worker in &self.workers { - if let Some(handle) = worker.try_lock(self.worker_reclamation.0.clone()) { - return handle; - } - } - receiver.wait().await; - } - } -} - -/// This handle logically owns free worker and can be used to send it requests. -pub struct FreeWorkerHandle<'a> { - /// reference to the worker - worker: &'a WorkerInfo, - /// Used to notify that worker is reclaimed - notify: multiwake::Sender, -} - -impl Drop for FreeWorkerHandle<'_> { - fn drop(&mut self) { - // true if worker can be reused later. - // Theoretically, it should always be the case when handle is dropped. - // However, due to bugs in JJS or problems in environment task, using - // this worker can fail in unexpected manner, leaving worker in - // inconsistent state. This flag implements conservative strategy - // which allows us to avoid such situations. - let reclaimable = matches!( - self.worker.state.load(), - WorkerStateKind::Idle | WorkerStateKind::Locked - ); - if reclaimable { - tracing::debug!("Reclaiming worker"); - self.worker.state.store(WorkerStateKind::Idle); - self.notify.wake(); - } else { - tracing::warn!("Leaking worker because it is not in reclaimable state"); - self.worker.state.store(WorkerStateKind::Crash); - } - } -} - -impl<'a> FreeWorkerHandle<'a> { - /// Sends request to worker, returning "stream" of responses - pub(crate) async fn send(self, req: Request) -> anyhow::Result> { - self.worker.state.store(WorkerStateKind::Judge); - self.worker - .send(req) - .await - .map_err(|err| { - tracing::warn!("request not delivered, marking worker as crashed"); - self.worker.state.store(WorkerStateKind::Crash); - err - }) - .context("failed to send request")?; - Ok(WorkerResponses { handle: Some(self) }) - } -} - -/// Provides access to worker responses -pub struct WorkerResponses<'a> { - handle: Option>, -} - -impl WorkerResponses<'_> { - /// Returns next response. - /// If returned response is JudgeDone or error, must not be polled again. - pub(crate) async fn next(&mut self) -> anyhow::Result { - let handle = self - .handle - .as_ref() - .expect("WorkerResponses is polled after finish"); - let res = handle.worker.recv().await; - let is_eos = match &res { - Ok(ok) => matches!(ok, Response::JudgeDone(_)), - Err(_) => true, - }; - if is_eos { - if res.is_ok() { - handle.worker.state.store(WorkerStateKind::Locked); - } else { - handle.worker.state.store(WorkerStateKind::Crash); - } - self.handle.take(); - } - res - } -} - -/// Contains WorkerStateKind -struct WorkerState(AtomicU8); -const WORKER_STATE_IDLE: u8 = 0; -const WORKER_STATE_LOCKED: u8 = 1; -const WORKER_STATE_CRASH: u8 = 2; -const WORKER_STATE_JUDGE: u8 = 3; -impl WorkerState { - fn new(kind: WorkerStateKind) -> Self { - let this = WorkerState(AtomicU8::new(0)); - this.store(kind); - this - } - - fn store(&self, kind: WorkerStateKind) { - let value = match kind { - WorkerStateKind::Idle => WORKER_STATE_IDLE, - WorkerStateKind::Locked => WORKER_STATE_LOCKED, - WorkerStateKind::Crash => WORKER_STATE_CRASH, - WorkerStateKind::Judge => WORKER_STATE_JUDGE, - }; - self.0.store(value, SeqCst); - } - - fn load(&self) -> WorkerStateKind { - let value = self.0.load(SeqCst); - match value { - WORKER_STATE_IDLE => WorkerStateKind::Idle, - WORKER_STATE_LOCKED => WorkerStateKind::Locked, - WORKER_STATE_CRASH => WorkerStateKind::Crash, - WORKER_STATE_JUDGE => WorkerStateKind::Judge, - other => unreachable!("unexpected worker state {}", other), - } - } - - /// Tries to atomically lock this worker state. - /// I.e., this functions succeeds if state was `Idle` and it was - /// successfully CASed to `Locked`. - fn lock(&self) -> bool { - self.0 - .compare_and_swap(WORKER_STATE_IDLE, WORKER_STATE_LOCKED, SeqCst) - == WORKER_STATE_IDLE - } -} - -enum WorkerStateKind { - /// Worker is ready for new tasks - Idle, - /// Worker is ready, but it is locked by a WorkerHandle - Locked, - /// Worker is juding run - Judge, - /// Worker has crashed - Crash, -} - -struct WorkerInfo { - state: WorkerState, - child_stdout: Mutex>, - child_stdin: Mutex, -} - -impl WorkerInfo { - pub async fn recv(&self) -> anyhow::Result { - let mut line = String::new(); - let mut child_stdout = self.child_stdout.lock().await; - - child_stdout.read_line(&mut line).await?; - Ok(serde_json::from_str(&line).context("parse error")?) - } - - pub async fn send(&self, req: Request) -> anyhow::Result<()> { - let mut data = serde_json::to_vec(&req)?; - data.push(b'\n'); - self.child_stdin.lock().await.write_all(&data).await?; - Ok(()) - } - - /// If this worker is idle, returns a handle to it. - /// Otherwise, returns None - pub fn try_lock(&self, notify: multiwake::Sender) -> Option { - if self.state.lock() { - Some(FreeWorkerHandle { - worker: self, - notify, - }) - } else { - None - } - } -} diff --git a/src/invoker/src/sources.rs b/src/invoker/src/sources.rs deleted file mode 100644 index 783e6e7f..00000000 --- a/src/invoker/src/sources.rs +++ /dev/null @@ -1,4 +0,0 @@ -mod api_source; -pub mod cli_source; - -pub use api_source::ApiSource; diff --git a/src/invoker/src/sources/api_source.rs b/src/invoker/src/sources/api_source.rs deleted file mode 100644 index 78ba1755..00000000 --- a/src/invoker/src/sources/api_source.rs +++ /dev/null @@ -1,201 +0,0 @@ -use crate::controller::{InvocationFinishReason, JudgeRequestAndCallbacks, JudgeResponseCallbacks}; -use anyhow::Context; -use client::prelude::Sendable; -use std::sync::Arc; -use tracing::{info, instrument, warn}; -use uuid::Uuid; - -struct Inner { - api: client::ApiClient, - run_mapping: tokio::sync::Mutex>, -} - -/// Fetches tasks from JJS API -pub struct ApiSource { - inner: Arc, - chan: async_mpmc::Sender, -} - -// double Arc, but who cares? -struct Callbacks { - inner: Arc, -} - -#[async_trait::async_trait] -impl JudgeResponseCallbacks for Callbacks { - async fn set_finished( - &self, - invocation_id: uuid::Uuid, - _reason: InvocationFinishReason, - ) -> anyhow::Result<()> { - let run_id = self - .inner - .run_mapping - .lock() - .await - .remove(&invocation_id) - .context("corrupted run_id_mapping")?; - let patch = client::models::RunPatch::patch_run().run_id(run_id); - /* TODO - let state = match reason { - InvocationFinishReason::CompileError => db::schema::InvocationState::CompileError, - InvocationFinishReason::Fault => db::schema::InvocationState::InvokeFailed, - InvocationFinishReason::JudgeDone => db::schema::InvocationState::JudgeDone, - }; - patch.state(state); - */ - patch - .send(&self.inner.api) - .await - .context("failed to store outcome")?; - Ok(()) - } - - async fn add_outcome_header( - &self, - invocation_id: uuid::Uuid, - header: invoker_api::JudgeOutcomeHeader, - ) -> anyhow::Result<()> { - let run_id = self - .inner - .run_mapping - .lock() - .await - .get(&invocation_id) - .context("corrupted run_id_mapping")? - .clone(); - client::models::RunPatch::patch_run() - .run_id(run_id) - .status( - vec![ - vec![ - header.kind.as_str(), - &format!("{}:{}", header.status.kind, header.status.code), - ] - .into_iter(), - ] - .into_iter(), - ) - .send(&self.inner.api) - .await - .context("failed to send outcome to API")?; - Ok(()) - } - - async fn deliver_live_status_update( - &self, - invocation_id: Uuid, - _lsu: invoker_api::LiveStatusUpdate, - ) -> anyhow::Result<()> { - let mapping = self.inner.run_mapping.lock().await; - let run_id = match mapping.get(&invocation_id) { - Some(id) => id, - None => { - anyhow::bail!("warning: invocation_id {} not found", invocation_id); - } - }; - let _key = format!("lsu-{}", run_id); - eprintln!("TODO"); - Ok(()) - } -} - -impl ApiSource { - pub fn new( - api: client::ApiClient, - chan: async_mpmc::Sender, - ) -> ApiSource { - let inner = Inner { - api, - - run_mapping: tokio::sync::Mutex::new(std::collections::HashMap::new()), - }; - let inner = Arc::new(inner); - ApiSource { chan, inner } - } - - fn make_callbacks(&self) -> Arc { - Arc::new(Callbacks { - inner: self.inner.clone(), - }) - } - - async fn get_tasks_from_api(&self) -> anyhow::Result> { - let runs = client::models::Run::pop_run_from_queue() - .limit(1_i64) - .send(&self.inner.api) - .await - .context("failed to get task list")?; - - let mut mapping = self.inner.run_mapping.lock().await; - let mut tasks = Vec::new(); - - for run in runs.object { - let request_id = uuid::Uuid::new_v4(); - mapping.insert(request_id, run.id.clone()); - - let run_source = client::models::Misc::get_run_source() - .run_id(run.id.clone()) - .send(&self.inner.api) - .await - .context("run source not available")? - .object; - let run_source = base64::decode(&run_source).context("api returned invalid base64")?; - let toolchain = client::models::Toolchain::get_toolchain() - .toolchain_id(&run.toolchain_name) - .send(&self.inner.api) - .await - .context("toolchain resolution failed")?; - - let task = invoker_api::JudgeRequest { - problem_id: run.problem_name, - request_id, - revision: 0, - toolchain_id: toolchain.image.clone(), - run_source, - }; - - tasks.push(task); - } - std::mem::drop(mapping); - if tasks.is_empty() { - // hack, but will be rewritten anyway - tokio::time::delay_for(std::time::Duration::from_secs(3)).await; - } - Ok(tasks) - } - - async fn tick(&mut self) -> anyhow::Result<()> { - let reqs = self - .get_tasks_from_api() - .await - .context("failed to fetch tasks")?; - - for request in reqs { - let req_cbs = JudgeRequestAndCallbacks { - request, - callbacks: self.make_callbacks(), - }; - self.chan.send(req_cbs); - } - Ok(()) - } - - /// Fetches tasks and posts results back in loop, until cancelled. - #[instrument(skip(self))] - pub async fn run(mut self, cancel: tokio::sync::CancellationToken) { - info!("Starting loop"); - loop { - let tick_res = tokio::select! { - res = self.tick() => res, - _ = cancel.cancelled() => { - info!("Cancelled"); - return; - } - }; - if let Err(err) = tick_res { - warn!("tick failed: {:#}", err); - } - } - } -} diff --git a/src/invoker/src/sources/cli_source.rs b/src/invoker/src/sources/cli_source.rs deleted file mode 100644 index 5f7da209..00000000 --- a/src/invoker/src/sources/cli_source.rs +++ /dev/null @@ -1,138 +0,0 @@ -use crate::controller::{InvocationFinishReason, JudgeRequestAndCallbacks, JudgeResponseCallbacks}; -use anyhow::Context as _; -use invoker_api::{CliJudgeRequest, JudgeRequest}; -use std::sync::Arc; -use tokio::io::AsyncBufReadExt; -use tracing::debug; -use uuid::Uuid; - -async fn convert_request(cli_judge_request: CliJudgeRequest) -> anyhow::Result { - let run_source = tokio::fs::read(&cli_judge_request.run_source) - .await - .context("run_source not readable")?; - Ok(JudgeRequest { - revision: cli_judge_request.revision, - toolchain_id: cli_judge_request.toolchain_id, - problem_id: cli_judge_request.problem_id, - request_id: cli_judge_request.request_id, - run_source, - }) -} - -#[derive(serde::Serialize)] -pub enum Message { - Finish(FinishedMessage), - Progress(ProgressMessage), - LiveStatusUpdate(LsuMessage), -} -#[derive(serde::Serialize)] -pub struct FinishedMessage { - invocation_id: Uuid, - reason: &'static str, -} - -#[derive(serde::Serialize)] -pub struct ProgressMessage { - invocation_id: Uuid, - header: invoker_api::JudgeOutcomeHeader, -} - -#[derive(serde::Serialize)] -pub struct LsuMessage { - invocation_id: Uuid, - update: invoker_api::LiveStatusUpdate, -} - -struct Callbacks; - -#[async_trait::async_trait] -impl JudgeResponseCallbacks for Callbacks { - async fn set_finished( - &self, - invocation_id: Uuid, - reason: InvocationFinishReason, - ) -> anyhow::Result<()> { - let reason = match reason { - InvocationFinishReason::CompileError => "CompileError", - InvocationFinishReason::TestingDone => "TestingDone", - InvocationFinishReason::Fault => "Fault", - }; - print_message(Message::Finish(FinishedMessage { - invocation_id, - reason, - })) - .await - } - - async fn add_outcome_header( - &self, - invocation_id: Uuid, - header: invoker_api::JudgeOutcomeHeader, - ) -> anyhow::Result<()> { - print_message(Message::Progress(ProgressMessage { - invocation_id, - header, - })) - .await - } - - async fn deliver_live_status_update( - &self, - invocation_id: Uuid, - update: invoker_api::LiveStatusUpdate, - ) -> anyhow::Result<()> { - print_message(Message::LiveStatusUpdate(LsuMessage { - invocation_id, - update, - })) - .await - } -} - -async fn read_worker_iteration( - req_tx: &mut async_mpmc::Sender, - stdin_reader: &mut tokio::io::BufReader, -) -> anyhow::Result<()> { - let mut line = String::new(); - let ret = stdin_reader - .read_line(&mut line) - .await - .context("failed to read line")?; - if ret == 0 { - tokio::time::delay_for(std::time::Duration::from_secs(30)).await; - } - let task = serde_json::from_str(&line).context("unparseable CliInvokeTask")?; - debug!("got {:?}", &task); - let request = convert_request(task).await?; - let judge_request_and_cbs = JudgeRequestAndCallbacks { - request, - callbacks: Arc::new(Callbacks), - }; - req_tx.send(judge_request_and_cbs); - Ok(()) -} - -async fn print_message(msg: Message) -> anyhow::Result<()> { - let msg = serde_json::to_string(&msg).context("serialization error")?; - println!("{}", msg); - Ok(()) -} - -pub async fn run( - mut req_tx: async_mpmc::Sender, - cancel: tokio::sync::CancellationToken, -) { - let mut reader = tokio::io::BufReader::new(tokio::io::stdin()); - - let run_fut = async move { - loop { - if let Err(err) = read_worker_iteration(&mut req_tx, &mut reader).await { - eprintln!("read iteration failed: {:#}", err); - } - } - }; - tokio::select! { - _ = run_fut => (), - _ = cancel.cancelled() => (), - } -} diff --git a/src/invoker/src/worker.rs b/src/invoker/src/worker.rs deleted file mode 100644 index 9dabcee5..00000000 --- a/src/invoker/src/worker.rs +++ /dev/null @@ -1,331 +0,0 @@ -//! Implements Invoker Worker. -//! -//! Worker is responsible for processing `InvokeRequest`s - -mod compiler; -mod exec_test; -mod invoke_util; -mod os_util; -mod transform_judge_log; -mod valuer; - -use anyhow::Context; -use compiler::{BuildOutcome, Compiler}; -use exec_test::{ExecRequest, TestExecutor}; -use invoker_api::{ - valuer_proto::{TestDoneNotification, ValuerResponse}, - Status, -}; -use serde::{Deserialize, Serialize}; -use std::{ - borrow::Cow, - path::{Path, PathBuf}, - sync::Arc, -}; -use tokio::io::{AsyncBufReadExt, AsyncWriteExt}; -use tracing::{debug, error}; -use valuer::Valuer; -#[derive(Default, Debug, Clone, Deserialize, Serialize)] -pub(crate) struct Command { - pub(crate) argv: Vec, - pub(crate) env: Vec, - pub(crate) cwd: String, -} - -/// Submission information, sufficient for judging -#[derive(Debug, Deserialize, Serialize)] -pub(crate) struct LoweredJudgeRequest { - pub(crate) compile_commands: Vec, - pub(crate) execute_command: Command, - pub(crate) compile_limits: pom::Limits, - pub(crate) problem: pom::Problem, - /// Path to problem dir - pub(crate) problem_dir: PathBuf, - /// Path to file containing run source - pub(crate) run_source: PathBuf, - /// Name of source file in sandbox. E.g., `source.cpp` for C++. - pub(crate) source_file_name: String, - /// Directory for emitting files (source, build, judge log) - pub(crate) out_dir: PathBuf, - /// Toolchain directory (i.e. sysroot for command execution) - pub(crate) toolchain_dir: PathBuf, - /// UUID of request - pub(crate) judge_request_id: uuid::Uuid, -} - -impl LoweredJudgeRequest { - pub(crate) fn resolve_asset(&self, short_path: &pom::FileRef) -> PathBuf { - let root: Cow = match short_path.root { - pom::FileRefRoot::Problem => self.problem_dir.join("assets").into(), - pom::FileRefRoot::Root => Path::new("/").into(), - }; - - debug!( - "full checker path: {}", - root.join(&short_path.path).to_str().unwrap() - ); - - root.join(&short_path.path) - } - - pub(crate) fn step_dir(&self, test_id: Option) -> PathBuf { - match test_id { - Some(t) => self.out_dir.join(format!("t-{}", t)), - None => self.out_dir.join("compile"), - } - } -} - -#[derive(Deserialize, Serialize)] -pub(crate) enum Request { - Judge(LoweredJudgeRequest), -} - -#[derive(Debug, Deserialize, Serialize)] -pub(crate) enum Response { - JudgeDone(JudgeOutcome), - OutcomeHeader(invoker_api::JudgeOutcomeHeader), - LiveTest(u32), - LiveScore(u32), -} - -pub(crate) struct Worker { - /// Minion backend to use for invocations - minion: Arc, - /// Invoker configuration - config: crate::config::InvokerConfig, -} - -impl Worker { - pub(crate) fn new(config: crate::config::InvokerConfig) -> anyhow::Result { - Ok(Worker { - minion: minion::erased::setup() - .context("minion initialization failed")? - .into(), - config, - }) - } - - async fn recv(&self, stdin: &mut (impl AsyncBufReadExt + Unpin)) -> Option { - let mut buf = String::new(); - match stdin.read_line(&mut buf).await { - Ok(_) => { - if buf.trim().is_empty() { - return None; - } - - Some(serde_json::from_str(&buf).expect("parse error")) - } - Err(_) => None, - } - } - - async fn send(&self, resp: Response) { - let mut stdout = tokio::io::stdout(); - let mut msg = serde_json::to_vec(&resp).expect("failed to serialize Response"); - msg.push(b'\n'); - stdout - .write_all(&msg) - .await - .expect("Failed to print Response"); - } - - pub(crate) async fn main_loop(mut self) { - let mut stdin = tokio::io::BufReader::new(tokio::io::stdin()); - while let Some(req) = self.recv(&mut stdin).await { - match req { - Request::Judge(judge_req) => { - debug!("Got LoweredJudgeRequest: {:?}", &judge_req); - let outcome = match self.judge(&judge_req).await { - Ok(o) => o, - Err(err) => { - error!("Invoke failed: {:#}", err); - self.create_fake_protocols( - &judge_req, - &invoker_api::Status { - kind: invoker_api::StatusKind::InternalError, - code: invoker_api::status_codes::JUDGE_FAULT.to_string(), - }, - ) - .await - .ok(); - JudgeOutcome::Fault - } - }; - debug!("JudgeOutcome: {:?}", &outcome); - self.send(Response::JudgeDone(outcome)).await; - } - } - } - } - - async fn judge(&mut self, req: &LoweredJudgeRequest) -> anyhow::Result { - let compiler = Compiler { - req, - minion: &*self.minion, - config: &self.config, - }; - - if !req.run_source.exists() { - anyhow::bail!("Run source file not exists"); - } - - if !req.out_dir.exists() { - anyhow::bail!("Run output dir not exists"); - } - - let compiler_response = compiler.compile(); - - let outcome; - - match compiler_response { - Err(err) => return Err(err).context("compilation error"), - Ok(BuildOutcome::Error(st)) => { - self.create_fake_protocols(req, &st).await?; - outcome = JudgeOutcome::CompileError(st); - } - Ok(BuildOutcome::Success) => { - self.run_tests(req).await.context("failed to run tests")?; - - outcome = JudgeOutcome::TestingDone; - } - }; - Ok(outcome) - } - - /// Used when we are unable to produce protocols, i.e. on compilation errors - /// and judge faults. - async fn create_fake_protocols( - &mut self, - req: &LoweredJudgeRequest, - status: &invoker_api::Status, - ) -> anyhow::Result<()> { - for kind in invoker_api::judge_log::JudgeLogKind::list() { - let pseudo_valuer_proto = invoker_api::valuer_proto::JudgeLog { - kind, - tests: vec![], - subtasks: vec![], - score: 0, - is_full: false, - }; - let mut protocol = self.process_judge_log(&pseudo_valuer_proto, req, &[])?; - protocol.status = status.clone(); - self.put_protocol(req, protocol).await?; - } - Ok(()) - } - - async fn put_outcome( - &mut self, - score: u32, - status: invoker_api::Status, - kind: invoker_api::judge_log::JudgeLogKind, - ) { - let header = invoker_api::JudgeOutcomeHeader { - score: Some(score), - status, - kind, - }; - self.send(Response::OutcomeHeader(header)).await; - } - - async fn put_protocol( - &mut self, - req: &LoweredJudgeRequest, - protocol: invoker_api::judge_log::JudgeLog, - ) -> anyhow::Result<()> { - let protocol_file_name = format!("protocol-{}.json", protocol.kind.as_str()); - let protocol_path = req.out_dir.join(protocol_file_name); - debug!("Writing protocol to {}", protocol_path.display()); - let protocol_file = std::fs::File::create(&protocol_path)?; - let protocol_file = std::io::BufWriter::new(protocol_file); - serde_json::to_writer(protocol_file, &protocol) - .context("failed to write judge log to file")?; - self.put_outcome(protocol.score, protocol.status, protocol.kind) - .await; - Ok(()) - } - - async fn run_tests(&mut self, req: &LoweredJudgeRequest) -> anyhow::Result<()> { - let mut test_results = vec![]; - - let mut valuer = Valuer::new(req).context("failed to init valuer")?; - valuer - .write_problem_data(req) - .await - .context("failed to send problem data")?; - loop { - match valuer.poll().await? { - ValuerResponse::Test { test_id: tid, live } => { - if live { - self.send(Response::LiveTest(tid.get())).await; - } - let tid_u32: u32 = tid.into(); - let test = &req.problem.tests[(tid_u32 - 1u32) as usize]; - let judge_request = ExecRequest { - test, - test_id: tid.into(), - }; - - let test_exec = TestExecutor { - exec: judge_request, - req, - minion: &*self.minion, - config: &self.config, - }; - - let judge_response = test_exec - .exec() - .with_context(|| format!("failed to judge solution on test {}", tid))?; - test_results.push((tid, judge_response.clone())); - valuer - .notify_test_done(TestDoneNotification { - test_id: tid, - test_status: judge_response.status, - }) - .await - .with_context(|| { - format!("failed to notify valuer that test {} is done", tid) - })?; - } - ValuerResponse::Finish => { - break; - } - ValuerResponse::LiveScore { score } => { - self.send(Response::LiveScore(score)).await; - } - ValuerResponse::JudgeLog(judge_log) => { - let converted_judge_log = self - .process_judge_log(&judge_log, req, &test_results) - .context("failed to convert valuer judge log to invoker judge log")?; - self.put_protocol(req, converted_judge_log) - .await - .context("failed to save protocol")?; - } - } - } - - Ok(()) - } -} - -#[derive(Serialize, Debug, Clone, Deserialize)] -pub(crate) enum JudgeOutcome { - /// Compilation failed - CompileError(Status), - /// Run was executed on some tests successfully (i.e. without judge faults) - /// All protocols were sent already - TestingDone, - /// Run was not judged, because of invocation fault - /// Maybe, several protocols were emitted, but results are neither precise nor complete - Fault, -} - -pub async fn main() -> anyhow::Result<()> { - let config_data = std::env::var("__JJS_WORKER_INVOKER_CONFIG") - .context("__JJS_WORKER_INVOKER_CONFIG missing")?; - let config = serde_json::from_str(&config_data)?; - let w = Worker::new(config).context("worker initialization failed")?; - w.main_loop().await; - Ok(()) -} diff --git a/src/invoker/src/worker/compiler.rs b/src/invoker/src/worker/compiler.rs deleted file mode 100644 index e874c6af..00000000 --- a/src/invoker/src/worker/compiler.rs +++ /dev/null @@ -1,89 +0,0 @@ -use crate::worker::{invoke_util, LoweredJudgeRequest}; -use anyhow::Context; -use invoker_api::{status_codes, Status, StatusKind}; -use std::fs; - -pub(crate) enum BuildOutcome { - Success, - Error(Status), -} - -/// Compiler turns SubmissionInfo into Artifact -pub(crate) struct Compiler<'a> { - pub(crate) req: &'a LoweredJudgeRequest, - pub(crate) minion: &'a dyn minion::erased::Backend, - pub(crate) config: &'a crate::config::InvokerConfig, -} - -impl<'a> Compiler<'a> { - pub(crate) fn compile(&self) -> anyhow::Result { - let sandbox = invoke_util::create_sandbox(self.req, None, self.minion, self.config) - .context("failed to create sandbox")?; - let step_dir = self.req.step_dir(None); - fs::copy( - &self.req.run_source, - step_dir.join("data").join(&self.req.source_file_name), - ) - .context("failed to copy source")?; - - for (i, command) in self.req.compile_commands.iter().enumerate() { - let stdout_path = step_dir.join(&format!("stdout-{}.txt", i)); - let stderr_path = step_dir.join(&format!("stderr-{}.txt", i)); - - invoke_util::log_execute_command(&command); - - let mut native_command = minion::Command::new(); - invoke_util::command_set_from_judge_req(&mut native_command, &command); - invoke_util::command_set_stdio(&mut native_command, &stdout_path, &stderr_path); - - native_command.sandbox(sandbox.sandbox.clone()); - - let child = match native_command.spawn(self.minion) { - Ok(child) => child, - Err(err) => { - let is_internal_error = match err.downcast_ref::() { - Some(e) => e.is_system(), - None => true, - }; - if is_internal_error { - return Err(err.context("failed to launch child")); - } else { - return Ok(BuildOutcome::Error(Status { - kind: StatusKind::Rejected, - code: status_codes::LAUNCH_ERROR.to_string(), - })); - } - } - }; - - let wait_result = child - .wait_for_exit(None) - .context("failed to wait for compiler")?; - match wait_result { - minion::WaitOutcome::Timeout => { - return Ok(BuildOutcome::Error(Status { - kind: StatusKind::Rejected, - code: status_codes::COMPILATION_TIMED_OUT.to_string(), - })); - } - minion::WaitOutcome::AlreadyFinished => unreachable!("not expected other to wait"), - minion::WaitOutcome::Exited => { - if child - .get_exit_code() - .context("failed to get compiler exit code")? - .unwrap() - != 0 - { - return Ok(BuildOutcome::Error(Status { - kind: StatusKind::Rejected, - code: status_codes::COMPILER_FAILED.to_string(), - })); - } - } - }; - } - fs::copy(step_dir.join("data/build"), self.req.out_dir.join("build")) - .context("failed to copy artifact to run dir")?; - Ok(BuildOutcome::Success) - } -} diff --git a/src/invoker/src/worker/exec_test.rs b/src/invoker/src/worker/exec_test.rs deleted file mode 100644 index 9110ceca..00000000 --- a/src/invoker/src/worker/exec_test.rs +++ /dev/null @@ -1,255 +0,0 @@ -mod checker_proto; - -use crate::worker::{invoke_util, os_util, LoweredJudgeRequest}; -use anyhow::Context; -use invoker_api::{status_codes, Status, StatusKind}; -use std::{fs, io::Write, path::PathBuf}; -use tracing::{debug, error}; -pub(crate) struct ExecRequest<'a> { - pub(crate) test_id: u32, - pub(crate) test: &'a pom::Test, -} - -#[derive(Debug, Clone)] -pub(crate) struct ExecOutcome { - pub(crate) status: Status, - pub(crate) resource_usage: minion::ResourceUsageData, -} - -/// Runs Artifact on one test and produces output -pub(crate) struct TestExecutor<'a> { - pub(crate) exec: ExecRequest<'a>, - pub(crate) req: &'a LoweredJudgeRequest, - pub(crate) minion: &'a dyn minion::erased::Backend, - pub(crate) config: &'a crate::config::InvokerConfig, -} - -enum RunOutcomeVar { - Success { out_data_path: PathBuf }, - Fail(Status), -} - -struct RunOutcome { - var: RunOutcomeVar, - resource_usage: minion::ResourceUsageData, -} - -fn map_checker_outcome_to_status(out: checker_proto::Output) -> Status { - match out.outcome { - checker_proto::Outcome::Ok => Status { - kind: StatusKind::Accepted, - code: status_codes::TEST_PASSED.to_string(), - }, - checker_proto::Outcome::BadChecker => Status { - kind: StatusKind::InternalError, - code: status_codes::JUDGE_FAULT.to_string(), - }, - checker_proto::Outcome::PresentationError => Status { - kind: StatusKind::Rejected, - code: status_codes::PRESENTATION_ERROR.to_string(), - }, - checker_proto::Outcome::WrongAnswer => Status { - kind: StatusKind::Rejected, - code: status_codes::WRONG_ANSWER.to_string(), - }, - } -} - -impl<'a> TestExecutor<'a> { - fn run_solution(&self, test_data: &[u8], test_id: u32) -> anyhow::Result { - let step_dir = self.req.step_dir(Some(test_id)); - - let sandbox = - invoke_util::create_sandbox(self.req, Some(test_id), self.minion, self.config)?; - - fs::copy(self.req.out_dir.join("build"), step_dir.join("data/build")) - .context("failed to copy build artifact to share dir")?; - - let stdout_path = step_dir.join("stdout.txt"); - let stderr_path = step_dir.join("stderr.txt"); - let command = &self.req.execute_command; - invoke_util::log_execute_command(command); - - let mut native_command = minion::Command::new(); - - invoke_util::command_set_from_judge_req(&mut native_command, &command); - invoke_util::command_set_stdio(&mut native_command, &stdout_path, &stderr_path); - - native_command.sandbox(sandbox.sandbox.clone()); - - // capture child input - native_command.stdin(minion::InputSpecification::pipe()); - - let mut child = match native_command.spawn(&*self.minion) { - Ok(child) => child, - Err(err) => { - let is_internal_error = match err.downcast_ref::() { - Some(e) => e.is_system(), - None => true, - }; - if is_internal_error { - return Err(err).context("failed to spawn solution"); - } else { - let run_outcome_var = RunOutcomeVar::Fail(Status { - kind: StatusKind::Rejected, - code: status_codes::LAUNCH_ERROR.to_string(), - }); - return Ok(RunOutcome { - var: run_outcome_var, - resource_usage: Default::default(), - }); - } - } - }; - let mut stdin = child.stdin().unwrap(); - stdin.write_all(test_data).ok(); - std::mem::drop(stdin); // close pipe - - let wait_result = child - .wait_for_exit(None) - .context("failed to wait for child")?; - - let resource_usage = sandbox - .sandbox - .resource_usage() - .context("cannot get resource usage")?; - - match wait_result { - minion::WaitOutcome::Timeout => { - return Ok(RunOutcome { - var: RunOutcomeVar::Fail(Status { - kind: StatusKind::Rejected, - code: status_codes::TIME_LIMIT_EXCEEDED.to_string(), - }), - resource_usage, - }); - } - minion::WaitOutcome::AlreadyFinished => unreachable!("not expected other to wait"), - minion::WaitOutcome::Exited => { - if child - .get_exit_code() - .context("failed to get exit code")? - .unwrap() - != 0 - { - return Ok(RunOutcome { - var: RunOutcomeVar::Fail(Status { - kind: StatusKind::Rejected, - code: status_codes::RUNTIME_ERROR.to_string(), - }), - resource_usage, - }); - } - } - } - - Ok(RunOutcome { - var: RunOutcomeVar::Success { - out_data_path: stdout_path, - }, - resource_usage, - }) - } - - pub fn exec(self) -> anyhow::Result { - use std::os::unix::io::IntoRawFd; - let input_file = self.req.resolve_asset(&self.exec.test.path); - let test_data = std::fs::read(input_file).context("failed to read test")?; - let run_outcome = self.run_solution(&test_data, self.exec.test_id)?; - let sol_file_path = match run_outcome.var { - RunOutcomeVar::Success { out_data_path } => out_data_path, - RunOutcomeVar::Fail(status) => { - return Ok(ExecOutcome { - status, - resource_usage: run_outcome.resource_usage, - }); - } - }; - // run checker - let step_dir = self.req.step_dir(Some(self.exec.test_id)); - let sol_file = fs::File::open(sol_file_path).context("failed to open run's answer")?; - let sol_handle = os_util::handle_inherit(sol_file.into_raw_fd().into(), true); - let full_checker_path = self.req.resolve_asset(&self.req.problem.checker_exe); - let mut cmd = std::process::Command::new(full_checker_path.clone()); - debug!( - "full checker path: {}, short path: {}", - full_checker_path.to_str().unwrap(), - &self.req.problem.checker_exe.path - ); - cmd.current_dir(&self.req.problem_dir); - - for arg in &self.req.problem.checker_cmd { - cmd.arg(arg); - } - - let test_cfg = self.exec.test; - - let corr_handle = if let Some(corr_path) = &test_cfg.correct { - let full_path = self.req.resolve_asset(corr_path); - let data = fs::read(full_path).context("failed to read correct answer")?; - os_util::buffer_to_file(&data, "invoker-correct-data") - } else { - os_util::buffer_to_file(&[], "invoker-correct-data") - }; - let test_handle = os_util::buffer_to_file(&test_data, "invoker-test-data"); - - cmd.env("JJS_CORR", corr_handle.to_string()); - cmd.env("JJS_SOL", sol_handle.to_string()); - cmd.env("JJS_TEST", test_handle.to_string()); - - let (out_judge_side, out_checker_side) = os_util::make_pipe(); - cmd.env("JJS_CHECKER_OUT", out_checker_side.to_string()); - let (comments_judge_side, comments_checker_side) = os_util::make_pipe(); - cmd.env("JJS_CHECKER_COMMENT", comments_checker_side.to_string()); - let st = cmd.output().context("failed to execute checker")?; - os_util::close(out_checker_side); - os_util::close(comments_checker_side); - os_util::close(corr_handle); - os_util::close(test_handle); - os_util::close(sol_handle); - // TODO: capture comments - os_util::close(comments_judge_side); - - let checker_out = std::fs::File::create(step_dir.join("check-log.txt"))?; - let mut checker_out = std::io::BufWriter::new(checker_out); - checker_out.write_all(b" --- stdout ---\n")?; - checker_out.write_all(&st.stdout)?; - checker_out.write_all(b"--- stderr ---\n")?; - checker_out.write_all(&st.stderr)?; - let return_value_for_judge_fault = Ok(ExecOutcome { - status: Status { - kind: StatusKind::InternalError, - code: status_codes::JUDGE_FAULT.to_string(), - }, - resource_usage: Default::default(), - }); - - let succ = st.status.success(); - if !succ { - error!("Judge fault: checker returned non-zero: {}", st.status); - os_util::close(out_judge_side); - return return_value_for_judge_fault; - } - let checker_out = match String::from_utf8(os_util::handle_read_all(out_judge_side)) { - Ok(c) => c, - Err(_) => { - error!("checker produced non-utf8 output"); - return return_value_for_judge_fault; - } - }; - let parsed_out = match checker_proto::parse(&checker_out) { - Ok(o) => o, - Err(err) => { - error!("checker output couldn't be parsed: {}", err); - return return_value_for_judge_fault; - } - }; - - let status = map_checker_outcome_to_status(parsed_out); - - Ok(ExecOutcome { - status, - resource_usage: run_outcome.resource_usage, - }) - } -} diff --git a/src/invoker/src/worker/exec_test/checker_proto.rs b/src/invoker/src/worker/exec_test/checker_proto.rs deleted file mode 100644 index f691f607..00000000 --- a/src/invoker/src/worker/exec_test/checker_proto.rs +++ /dev/null @@ -1,58 +0,0 @@ -//! Checker out file parser -use anyhow::bail; -use strum_macros::EnumString; - -#[derive(EnumString)] -pub enum Outcome { - Ok, - WrongAnswer, - PresentationError, - #[strum(to_string = "CheckerLogicError")] - BadChecker, -} - -pub struct Output { - pub outcome: Outcome, -} - -pub fn parse(data: &str) -> anyhow::Result { - let mut res_outcome = None; - for (line_id, line) in data.lines().enumerate() { - let line_id = (line_id + 1) as u32; - let p = match line.find('=') { - Some(i) => i, - None => { - bail!( - "Line {} doesn't contain '='-separated key and value", - line_id - ); - } - }; - let tag = &data[..p]; - let value = &data[p + 1..]; - match tag { - "outcome" => { - let data = value.trim(); - let outcome: Outcome = match data.parse() { - Ok(o) => o, - Err(e) => { - bail!("Tag outcome: {}", e); - } - }; - if res_outcome.replace(outcome).is_some() { - bail!("Tag outcome redefined"); - } - } - _ => { - bail!("Line {}: unknown tag {}", line_id, tag); - } - } - } - let outcome = match res_outcome { - Some(o) => o, - None => { - bail!("Tag outcome missong"); - } - }; - Ok(Output { outcome }) -} diff --git a/src/invoker/src/worker/invoke_util.rs b/src/invoker/src/worker/invoke_util.rs deleted file mode 100644 index 0423184b..00000000 --- a/src/invoker/src/worker/invoke_util.rs +++ /dev/null @@ -1,141 +0,0 @@ -use crate::worker::{Command, LoweredJudgeRequest}; -use anyhow::Context; -use std::{ - fs, - path::{Path, PathBuf}, - time::Duration, -}; -use tracing::{debug, error}; - -pub(crate) struct Sandbox { - pub(crate) sandbox: Box, - umount: Option, -} - -impl Drop for Sandbox { - fn drop(&mut self) { - if let Some(p) = self.umount.take() { - if let Err(err) = nix::mount::umount2(&p, nix::mount::MntFlags::MNT_DETACH) { - error!("Leaking tmpfs at {}: umount2 failed: {}", p.display(), err) - } else { - debug!("Successfully destroyed tmpfs at {}", p.display()) - } - } else { - panic!("TODO, REMOVE: winda??") - } - } -} - -static DEFAULT_HOST_MOUNTS: once_cell::sync::Lazy> = once_cell::sync::Lazy::new(|| { - vec![ - "usr".to_string(), - "bin".to_string(), - "lib".to_string(), - "lib64".to_string(), - ] -}); - -pub(crate) fn create_sandbox( - req: &LoweredJudgeRequest, - test_id: Option, - backend: &dyn minion::erased::Backend, - config: &crate::config::InvokerConfig, -) -> anyhow::Result { - let mut shared_dirs = vec![]; - if config.host_toolchains { - let dirs = config - .expose_host_dirs - .as_ref() - .unwrap_or_else(|| &*DEFAULT_HOST_MOUNTS); - for item in dirs { - let item = format!("/{}", item); - let shared_dir = minion::SharedDir { - src: item.clone().into(), - dest: item.into(), - kind: minion::SharedDirKind::Readonly, - }; - shared_dirs.push(shared_dir) - } - } else { - let toolchain_dir = &req.toolchain_dir; - let opt_items = - fs::read_dir(&toolchain_dir).context("failed to list toolchains sysroot")?; - for item in opt_items { - let item = item.context("failed to stat toolchains sysroot item")?; - let name = item.file_name(); - let shared_dir = minion::SharedDir { - src: toolchain_dir.join(&name), - dest: PathBuf::from(&name), - kind: minion::SharedDirKind::Readonly, - }; - shared_dirs.push(shared_dir) - } - } - - let limits = if let Some(test_id) = test_id { - req.problem.tests[(test_id - 1) as usize].limits - } else { - req.compile_limits - }; - let out_dir = req.step_dir(test_id); - std::fs::create_dir_all(&out_dir).context("failed to create step directory")?; - let umount_path; - #[cfg(target_os = "linux")] - { - let quota = limits.work_dir_size(); - let quota = minion::linux::ext::Quota::bytes(quota); - minion::linux::ext::make_tmpfs(&out_dir.join("data"), quota) - .context("failed to set size limit on shared directory")?; - umount_path = Some(out_dir.join("data")); - } - #[cfg(not(target_os = "linux"))] - { - umount_path = None; - } - shared_dirs.push(minion::SharedDir { - src: out_dir.join("data"), - dest: PathBuf::from("/jjs"), - kind: minion::SharedDirKind::Full, - }); - let cpu_time_limit = Duration::from_millis(limits.time() as u64); - let real_time_limit = Duration::from_millis(limits.time() * 3 as u64); - std::fs::create_dir(out_dir.join("root")).context("failed to create chroot dir")?; - // TODO adjust integer types - let sandbox_options = minion::SandboxOptions { - max_alive_process_count: limits.process_count() as _, - memory_limit: limits.memory() as _, - exposed_paths: shared_dirs, - isolation_root: out_dir.join("root"), - cpu_time_limit, - real_time_limit, - }; - let sandbox = backend - .new_sandbox(sandbox_options) - .context("failed to create minion dominion")?; - Ok(Sandbox { - sandbox, - umount: umount_path, - }) -} - -pub(crate) fn log_execute_command(command_interp: &Command) { - debug!("executing command {:?}", command_interp); -} - -pub(crate) fn command_set_from_judge_req(cmd: &mut minion::Command, command: &Command) { - cmd.path(&command.argv[0]); - cmd.args(&command.argv[1..]); - cmd.envs(&command.env); -} - -pub(crate) fn command_set_stdio(cmd: &mut minion::Command, stdout_path: &Path, stderr_path: &Path) { - let stdout_file = fs::File::create(stdout_path).expect("io error"); - - let stderr_file = fs::File::create(stderr_path).expect("io error"); - // Safety: std::fs::File owns it's handle - unsafe { - cmd.stdout(minion::OutputSpecification::handle_of(stdout_file)); - - cmd.stderr(minion::OutputSpecification::handle_of(stderr_file)); - } -} diff --git a/src/invoker/src/worker/os_util.rs b/src/invoker/src/worker/os_util.rs deleted file mode 100644 index 6880eff0..00000000 --- a/src/invoker/src/worker/os_util.rs +++ /dev/null @@ -1,64 +0,0 @@ -use std::ffi::CString; - -pub fn buffer_to_file(buf: &[u8], comment: &str) -> i64 { - use nix::{ - fcntl::{self, FcntlArg}, - sys::memfd::{self, MemFdCreateFlag}, - }; - let fd = memfd::memfd_create( - &CString::new(comment).unwrap(), - MemFdCreateFlag::MFD_ALLOW_SEALING, - ) - .unwrap(); - let mut buf_rem = buf; - loop { - let cnt = nix::unistd::write(fd, buf_rem).unwrap(); - buf_rem = &buf_rem[cnt..]; - if cnt == 0 { - break; - } - } - // now seal memfd - // currently this is not important, but when... - // TODO: cache all this stuff - // ... it is important that file can't be altered by solution - let seals = libc::F_SEAL_GROW | libc::F_SEAL_SEAL | libc::F_SEAL_WRITE | libc::F_SEAL_SHRINK; - fcntl::fcntl( - fd, - FcntlArg::F_ADD_SEALS(fcntl::SealFlag::from_bits(seals).unwrap()), - ) - .unwrap(); - // and seek fd to begin - nix::unistd::lseek64(fd, 0, nix::unistd::Whence::SeekSet).unwrap(); - i64::from(fd) -} - -// this is bug in clippy: https://github.com/rust-lang/rust-clippy/issues/5368 -#[allow(clippy::verbose_file_reads)] -pub fn handle_read_all(h: i64) -> Vec { - use std::{io::Read, os::unix::io::FromRawFd}; - let h = h as i32; - let mut file = unsafe { std::fs::File::from_raw_fd(h) }; - let mut out = Vec::new(); - let res = file.read_to_end(&mut out); - res.unwrap(); - out -} - -pub fn make_pipe() -> (i64, i64) { - let (a, b) = nix::unistd::pipe().unwrap(); - (i64::from(a), i64::from(b)) -} - -pub fn handle_inherit(h: i64, close: bool) -> i64 { - let out = i64::from(nix::unistd::dup(h as i32).unwrap()); - if close { - nix::unistd::close(h as i32).unwrap() - } - - out -} - -pub fn close(h: i64) { - nix::unistd::close(h as i32).unwrap() -} diff --git a/src/invoker/src/worker/transform_judge_log.rs b/src/invoker/src/worker/transform_judge_log.rs deleted file mode 100644 index b19bc0bf..00000000 --- a/src/invoker/src/worker/transform_judge_log.rs +++ /dev/null @@ -1,145 +0,0 @@ -use crate::worker::{LoweredJudgeRequest, Worker}; -use anyhow::Context; -use invoker_api::{ - judge_log, status_codes, valuer_proto::TestVisibleComponents, Status, StatusKind, -}; -use std::io::Read; - -impl Worker { - /// Go from valuer judge log to invoker judge log - // Bug in clippy: https://github.com/rust-lang/rust-clippy/issues/5368 - #[allow(clippy::verbose_file_reads)] - pub(super) fn process_judge_log( - &self, - valuer_log: &invoker_api::valuer_proto::JudgeLog, - req: &LoweredJudgeRequest, - test_results: &[(pom::TestId, crate::worker::exec_test::ExecOutcome)], - ) -> anyhow::Result { - let resource_usage_by_test = { - let mut map = std::collections::HashMap::new(); - for (k, v) in test_results { - map.insert(*k, v.resource_usage); - } - map - }; - let mut persistent_judge_log = judge_log::JudgeLog::default(); - let status = if valuer_log.is_full { - Status { - kind: StatusKind::Accepted, - code: status_codes::ACCEPTED.to_string(), - } - } else { - Status { - kind: StatusKind::Rejected, - code: status_codes::PARTIAL_SOLUTION.to_string(), - } - }; - persistent_judge_log.status = status; - persistent_judge_log.kind = valuer_log.kind; - persistent_judge_log.score = valuer_log.score; - // now fill compile_stdout and compile_stderr in judge_log - { - let mut compile_stdout = Vec::new(); - let mut compile_stderr = Vec::new(); - let compile_dir = req.out_dir.join("compile"); - for i in 0.. { - let stdout_file = compile_dir.join(format!("stdout-{}.txt", i)); - let stderr_file = compile_dir.join(format!("stderr-{}.txt", i)); - if !stdout_file.exists() || !stderr_file.exists() { - break; - } - let mut stdout_file = - std::fs::File::open(stdout_file).context("failed to open output log")?; - let mut stderr_file = - std::fs::File::open(stderr_file).context("failed to open errors log")?; - stdout_file - .read_to_end(&mut compile_stdout) - .context("failed to read output log")?; - stderr_file - .read_to_end(&mut compile_stderr) - .context("failed to read errors log")?; - } - persistent_judge_log.compile_stdout = base64::encode(&compile_stdout); - persistent_judge_log.compile_stderr = base64::encode(&compile_stderr); - } - // for each test, if valuer allowed, add stdin/stdout/stderr etc to judge_log - { - for item in &valuer_log.tests { - let mut new_item = judge_log::JudgeLogTestRow { - test_id: item.test_id, - test_answer: None, - test_stdout: None, - test_stderr: None, - test_stdin: None, - status: None, - time_usage: None, - memory_usage: None, - }; - let test_local_dir = req.step_dir(Some(item.test_id.get())); - if item.components.contains(TestVisibleComponents::TEST_DATA) { - let test_file = &req.problem.tests[item.test_id].path; - let test_file = req.resolve_asset(&test_file); - let test_data = std::fs::read(test_file).context("failed to read test data")?; - let test_data = base64::encode(&test_data); - new_item.test_stdin = Some(test_data); - } - if item.components.contains(TestVisibleComponents::OUTPUT) { - let stdout_file = test_local_dir.join("stdout.txt"); - let stderr_file = test_local_dir.join("stderr.txt"); - //println!("DEBUG: stdout_file={}", stdout_file.display()); - let sol_stdout = - std::fs::read(stdout_file).context("failed to read solution stdout")?; - let sol_stderr = - std::fs::read(stderr_file).context("failed to read solution stderr")?; - let sol_stdout = base64::encode(&sol_stdout); - let sol_stderr = base64::encode(&sol_stderr); - new_item.test_stdout = Some(sol_stdout); - new_item.test_stderr = Some(sol_stderr); - } - if item.components.contains(TestVisibleComponents::ANSWER) { - let answer_ref = &req.problem.tests[item.test_id].correct; - if let Some(answer_ref) = answer_ref { - let answer_file = req.resolve_asset(answer_ref); - let answer = - std::fs::read(answer_file).context("failed to read correct answer")?; - let answer = base64::encode(&answer); - new_item.test_answer = Some(answer); - } - } - if item.components.contains(TestVisibleComponents::STATUS) { - new_item.status = Some(item.status.clone()); - } - if let Some(resource_usage) = resource_usage_by_test.get(&item.test_id) { - if item - .components - .contains(TestVisibleComponents::RESOURCE_USAGE) - { - new_item.memory_usage = resource_usage.memory; - new_item.time_usage = resource_usage.time; - } - } - persistent_judge_log.tests.push(new_item); - } - persistent_judge_log - .tests - .sort_by(|a, b| a.test_id.cmp(&b.test_id)); - } - { - for item in &valuer_log.subtasks { - persistent_judge_log - .subtasks - .push(judge_log::JudgeLogSubtaskRow { - subtask_id: item.subtask_id, - score: Some(item.score), - }); - } - persistent_judge_log - .subtasks - .sort_by(|a, b| a.subtask_id.0.cmp(&b.subtask_id.0)); - } - // note that we do not filter subtasks connected staff, - // because such filtering is done by Valuer. - - Ok(persistent_judge_log) - } -} diff --git a/src/invoker/src/worker/valuer.rs b/src/invoker/src/worker/valuer.rs deleted file mode 100644 index c2f753be..00000000 --- a/src/invoker/src/worker/valuer.rs +++ /dev/null @@ -1,115 +0,0 @@ -use crate::worker::LoweredJudgeRequest; -use anyhow::{bail, Context}; -use invoker_api::valuer_proto::{ProblemInfo, TestDoneNotification, ValuerResponse}; -use std::os::unix::io::IntoRawFd; -use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader, BufWriter}; -use tracing::warn; -pub(crate) struct Valuer { - stdin: BufWriter, - stdout: BufReader, - // ties lifetime of valuer instance to `Valuer` lifetime - _child: tokio::process::Child, -} - -impl Valuer { - pub(crate) fn new(req: &LoweredJudgeRequest) -> anyhow::Result { - let valuer_exe = req.resolve_asset(&req.problem.valuer_exe); - let mut cmd = tokio::process::Command::new(&valuer_exe); - cmd.kill_on_drop(true); - cmd.stdin(std::process::Stdio::piped()); - cmd.stdout(std::process::Stdio::piped()); - cmd.stderr(std::process::Stdio::inherit()); - cmd.env("JJS_VALUER", "1"); - cmd.env("RUST_LOG", "info,svaluer=debug"); - let work_dir = req.resolve_asset(&req.problem.valuer_cfg); - if work_dir.exists() { - cmd.current_dir(&work_dir); - } else { - warn!( - "Not setting current dir for valuer because path specified ({}) does not exists", - work_dir.display() - ); - } - let log = std::fs::File::create(req.out_dir.join("valuer-log.txt")) - .context("failed to create valuer log file")? - .into_raw_fd(); - unsafe { - cmd.pre_exec(move || { - nix::unistd::dup3(log, libc::STDERR_FILENO, nix::fcntl::OFlag::empty()) - .map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))?; - Ok(()) - }); - } - let mut child = cmd.spawn().with_context(|| { - format!( - "failed to spawn valuer {} (requested current dir {})", - valuer_exe.display(), - work_dir.display() - ) - })?; - let stdin = child.stdin.take().unwrap(); - let stdout = child.stdout.take().unwrap(); - let val = Valuer { - stdin: BufWriter::new(stdin), - stdout: BufReader::new(stdout), - _child: child, - }; - - Ok(val) - } - - async fn write_val(&mut self, msg: impl serde::Serialize) -> anyhow::Result<()> { - let mut msg = serde_json::to_string(&msg).context("failed to serialize")?; - if msg.contains('\n') { - bail!("bug: serialized message is not oneline"); - } - msg.push('\n'); - self.stdin - .write_all(msg.as_bytes()) - .await - .context("failed to write message")?; - self.stdin - .flush() - .await - .context("failed to flush valuer stdin")?; - Ok(()) - } - - pub(crate) async fn write_problem_data( - &mut self, - req: &LoweredJudgeRequest, - ) -> anyhow::Result<()> { - let proto_problem_info = ProblemInfo { - tests: req - .problem - .tests - .iter() - .map(|test_spec| test_spec.group.clone()) - .collect(), - }; - self.write_val(proto_problem_info).await - } - - pub(crate) async fn poll(&mut self) -> anyhow::Result { - let mut line = String::new(); - let read_line_fut = self.stdout.read_line(&mut line); - match tokio::time::timeout(std::time::Duration::from_secs(15), read_line_fut).await { - Ok(read) => { - read.context("early eof")?; - } - Err(_elapsed) => { - bail!("valuer response timed out"); - } - } - let response = serde_json::from_str(&line).context("failed to parse valuer message")?; - - Ok(response) - } - - pub(crate) async fn notify_test_done( - &mut self, - notification: TestDoneNotification, - ) -> anyhow::Result<()> { - self.write_val(notification).await - } -} diff --git a/src/invoker/tests/separated_feedback.rs b/src/invoker/tests/separated_feedback.rs deleted file mode 100644 index 4ca3f875..00000000 --- a/src/invoker/tests/separated_feedback.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[tokio::test] -async fn separated_feedback() { - // TODO write this test when cfg is rewritten -} diff --git a/src/jtl/CMakeLists.txt b/src/jtl/CMakeLists.txt deleted file mode 100644 index 39765f96..00000000 --- a/src/jtl/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -cmake_minimum_required(VERSION 3.13.4) -project(Jtl VERSION 0.1.0) -set(CMAKE_CXX_STANDARD 17) - -set(SRC_FILES src/jtl.cpp src/testgen.cpp src/proto.cpp src/checker.cpp src/util.cpp) -set(HEADER_FILES include/jtl.h include/testgen.h include/checker.h) - -set(TEMP_DIR ${CMAKE_CURRENT_BINARY_DIR}) - -# JTL itself -add_library(Jtl STATIC ${SRC_FILES}) -target_include_directories(Jtl PUBLIC include src ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/deps) -set_target_properties(Jtl PROPERTIES PUBLIC_HEADER "${HEADER_FILES}") -target_link_libraries(Jtl PUBLIC pthread rt dl m) - -install(TARGETS Jtl - ARCHIVE DESTINATION /tmp - PUBLIC_HEADER DESTINATION include/jjs) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libJtl.a DESTINATION lib RENAME libjtl.a) -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/JtlConfig.cmake DESTINATION share/cmake) - -# Checkers, valuers, testgens, etc -function(add_builtin builtin_name src_file) - set(target_name builtin-${builtin_name}) - add_executable(${target_name} ${src_file}) - target_include_directories(${target_name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include) - target_link_options(${target_name} PUBLIC -L${CMAKE_CURRENT_BINARY_DIR}) - target_link_libraries(${target_name} PUBLIC Jtl) - add_dependencies(${target_name} Jtl) - install(TARGETS ${target_name} - RUNTIME DESTINATION bin) -endfunction() -add_builtin(checker-cmp-tokens src/builtin/checker-cmp-tokens.cpp) -add_builtin(checker-polygon-compat src/builtin/checker-polygon-compat.cpp) \ No newline at end of file diff --git a/src/jtl/Dockerfile b/src/jtl/Dockerfile deleted file mode 100644 index c3f29292..00000000 --- a/src/jtl/Dockerfile +++ /dev/null @@ -1,2 +0,0 @@ -FROM debian:stable-slim -COPY / /jtl \ No newline at end of file diff --git a/src/jtl/JtlConfig.cmake b/src/jtl/JtlConfig.cmake deleted file mode 100644 index 96ff518e..00000000 --- a/src/jtl/JtlConfig.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# TODO: Required etc -# Output: -# Jtl_LIBS: libraries you should link to -# Jtl_INCLUDES: add to include path -set(Jtl_HW foo) -if (DEFINED ENV{JJS_PATH}) - set(Jtl_LIBS $ENV{JJS_PATH}/lib/libjtl.a pthread m dl rt) - set(Jtl_INCLUDES $ENV{JJS_PATH}/include/) -else () - message(FATAL_ERROR "$JJS_PATH env var is not set") -endif () \ No newline at end of file diff --git a/src/jtl/cbindgen.toml b/src/jtl/cbindgen.toml deleted file mode 100644 index c3741377..00000000 --- a/src/jtl/cbindgen.toml +++ /dev/null @@ -1,8 +0,0 @@ -autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify it manually. */" -language = "C++" - -[export] -exclude = [] - -[enum] -rename_variants = "QualifiedScreamingSnakeCase" \ No newline at end of file diff --git a/src/jtl/include/checker.h b/src/jtl/include/checker.h deleted file mode 100644 index ba16f1cf..00000000 --- a/src/jtl/include/checker.h +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include "jtl.h" -#include - -namespace checker { - -void comment(const char* format, ...) PRINT_FORMAT_FN(1); - -void sol_scanf(const char* format, ...) SCAN_FORMAT_FN(1); - -void corr_scanf(const char* format, ...) SCAN_FORMAT_FN(1); - -void test_scanf(const char* format, ...) SCAN_FORMAT_FN(1); - -void check_sol_eof(); - -void check_corr_eof(); - -void check_test_eof(); - -struct CheckerInput { - /// Contestant's solution answer - FILE* sol_answer = nullptr; - /// Correct answer (answer generated by primary solution), if requested by - /// problem config. Otherwise, refers to /dev/null - FILE* corr_answer = nullptr; - /// Test data - FILE* test = nullptr; - - int64_t fd_sol = -1; - int64_t fd_corr = -1; - int64_t fd_test = -1; -}; - -CheckerInput init(bool open_files = true); - -/// Reads next char sequence, followed by whitespace -/// next_token() returns owning pointer to token. This pointer should be freed -/// by free() -char* next_token(FILE* f); - -enum class Outcome { - - /// Checker couldn't recognize answer - PRESENTATION_ERROR, - - /// Answer was wrong - WRONG_ANSWER, - - /// Correct answer - OK, - - /// Checker is incorrect - /// for example, contestant provided more optimal answer than jury - CHECKER_LOGIC_ERROR, -}; - -/// Checker exits using this function -/// If checker simply exits with e.g. exit(0) protocol will be broken and -/// internal judging error will be diagnosed -void finish(Outcome outcome) ATTR_NORETURN; - -/// Some comparison functions - -bool compare_epsilon(long double expected, long double actual, - long double epsilon); - -bool compare_strings_ignore_case(const char* lhs, const char* rhs); -} // namespace checker \ No newline at end of file diff --git a/src/jtl/include/jtl.h b/src/jtl/include/jtl.h deleted file mode 100644 index 7a02328b..00000000 --- a/src/jtl/include/jtl.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include "testgen.h" -#include - -#ifdef __GNUC__ -#define SCAN_FORMAT_FN(x) __attribute__((format(scanf, x, x + 1))) -#define PRINT_FORMAT_FN(x) __attribute__((format(printf, x, x + 1))) -#else -#define SCAN_FORMAT_FN(x) -#define PRINT_FORMAT_FN(x) -#endif - -#ifdef __GNUC__ -#define ATTR_NORETURN __attribute__((noreturn)) -#else -#define ATTR_NORETURN -#endif - -#ifdef __GNUC__ -#define ATTR_RET_NONNULL __attribute__((returns_nonnull)) -#else -#define ATTR_RET_NONNULL -#endif - -/// utility functions checks than only whitespace chars are remaining in file -bool is_file_eof(FILE* f); - -void oom() ATTR_NORETURN; - -void* check_oom(void* ptr) ATTR_RET_NONNULL; - -void die(char const* message, ...) ATTR_NORETURN PRINT_FORMAT_FN(1); \ No newline at end of file diff --git a/src/jtl/include/testgen.h b/src/jtl/include/testgen.h deleted file mode 100644 index 1dafe021..00000000 --- a/src/jtl/include/testgen.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -namespace testgen { -class Generator { - std::mt19937_64 gen; - - public: - // disallow implicit copies - Generator(const Generator& gen) noexcept = default; - - explicit Generator(uint64_t seed); - - uint64_t next_u64(); - - size_t next_usize(); - - /// generates number in [lo; hi) - uint64_t next_range(uint64_t lo, uint64_t hi); - - template - T choose_uniform(RAIter begin, RAIter end) { - size_t const item_count = std::distance(begin, end); - auto const selected_pos = (size_t) next_range(0, (uint64_t) item_count); - *std::advance(begin, selected_pos); - } - - /// returns new generator, which state is initially same with this - Generator clone(); -}; - -struct TestgenSession { - int test_id = 0; - Generator gen; - - TestgenSession(uint64_t _seed); -}; - -/// Call this first in test generator -TestgenSession init(); -} // namespace testgen diff --git a/src/jtl/src/builtin/checker-cmp-tokens.cpp b/src/jtl/src/builtin/checker-cmp-tokens.cpp deleted file mode 100644 index 5df0a4da..00000000 --- a/src/jtl/src/builtin/checker-cmp-tokens.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#include -#include -#include -#include - -using namespace checker; -struct Random; - -struct Args { - bool enable_epsilon = false; - long double epsilon = 0.0; - bool ignore_case = false; -}; - -bool is_float(const char* s) { - const size_t n = strlen(s); - size_t cnt = 0; - for (size_t i = 0; i < n; ++i) { - if (s[i] != '.' && (s[i] < '0' || s[i] > '9')) { - return false; - } - if (s[i] == '.') { - ++cnt; - } - } - return cnt <= 1 && s[0] != '.' && s[n - 1] != '.'; -} - -bool compare_tokens(char* expected, char* actual, const Args& args) { - if (is_float(expected) && args.enable_epsilon) { - long double exp = strtold(expected, nullptr); - long double act = strtold(actual, nullptr); - return compare_epsilon(exp, act, args.epsilon); - } else if (args.ignore_case) { - return compare_strings_ignore_case(expected, actual); - } else { - return strcmp(expected, actual) == 0; - } -} - -int main(int argc, char** argv) { - checker::CheckerInput checker_input = init(); - Args args; - for (size_t i = 1; i < argc; ++i) { - if (strcmp(argv[i], "--epsilon") == 0) { - if (i + 1 == argc) { - fprintf(stderr, "Error: --epsilon was not given value"); - finish(Outcome::CHECKER_LOGIC_ERROR); - } - char* endptr; - long double eps = strtold(argv[i + 1], &endptr); - if (endptr == argv[i + 1]) { - fprintf(stderr, "Error: %s is not valid long double value", - argv[i + 1]); - finish(Outcome::CHECKER_LOGIC_ERROR); - } - args.enable_epsilon = true; - args.epsilon = eps; - } else if (strcmp(argv[i], "--ignore-case") == 0) { - args.ignore_case = true; - } - } - size_t i = 0; - while (true) { - char* actual = next_token(checker_input.sol_answer); - char* expected = next_token(checker_input.corr_answer); - if (!expected && actual) { - comment("error: early EOF in actual answer on position %zu", i); - comment("note: next expected token was %s", expected); - finish(Outcome::WRONG_ANSWER); - } - if (expected && !actual) { - comment("error: actual answer contains additional tokens, starting " - "from %zu", - i); - comment("note: next actual token was %s", actual); - finish(Outcome::WRONG_ANSWER); - } - if (!expected) { - break; - } - bool eq = compare_tokens(expected, actual, args); - if (!eq) { - comment("error: token mismatch on position %zu", i); - comment("note: expected %s, got %s", expected, actual); - - finish(Outcome::WRONG_ANSWER); - } - ++i; - } - - comment("success: %zu tokens", i); - finish(Outcome::OK); -} \ No newline at end of file diff --git a/src/jtl/src/builtin/checker-polygon-compat.cpp b/src/jtl/src/builtin/checker-polygon-compat.cpp deleted file mode 100644 index 5c4dc747..00000000 --- a/src/jtl/src/builtin/checker-polygon-compat.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include - -#include "checker.h" -#include "unistd.h" -#include "util.h" - -using namespace checker; - -static const size_t PATH_LEN = 128; - -int main(int argc, char** argv) { - if (argc != 2) { - fprintf(stderr, "Usage: %s path_to_polygon_compatible_checker", - argv[0]); - exit(1); - } - CheckerInput input = init(false); - char input_file[PATH_LEN]; - char output_file[PATH_LEN]; - char answer_file[PATH_LEN]; - - pid_t my_pid = getpid(); - assert(my_pid != -1); - - sprintf(input_file, "/proc/%d/fd/%d", my_pid, (int) input.fd_test); - sprintf(output_file, "/proc/%d/fd/%d", my_pid, (int) input.fd_sol); - sprintf(answer_file, "/proc/%d/fd/%d", my_pid, (int) input.fd_corr); - - char* inner_checker = argv[1]; - int fres = fork(); - if (fres == -1) { - fprintf(stderr, "fork() failed: %m\n"); - return 1; - } - if (fres == 0) { - execl(inner_checker, inner_checker, input_file, output_file, - answer_file, nullptr); - fprintf(stderr, "error: launch inner checker %s: %d (%m)\n", - inner_checker, errno); - exit(66); - } - int wstatus; - if (waitpid(fres, &wstatus, 0) == -1) { - fprintf(stderr, "error: waitpid() failed: %m\n"); - exit(1); - } - if (WIFEXITED(wstatus)) { - int exit_code = WEXITSTATUS(wstatus); - switch (exit_code) { - case 0: - finish(Outcome::OK); - break; - case 1: - finish(Outcome::WRONG_ANSWER); - break; - case 2: - case 4: - case 8: - finish(Outcome::PRESENTATION_ERROR); - break; - case 3: - finish(Outcome::CHECKER_LOGIC_ERROR); - break; - default: { - // fallthrough - } - } - fprintf(stderr, "unexpected return code from child checker: %d\n", - exit_code); - exit(1); - } else { - fprintf( - stderr, - "unexpected exit status (child checker didn't terminate normally): " - "%d\n", - wstatus); - exit(1); - } -} \ No newline at end of file diff --git a/src/jtl/src/checker.cpp b/src/jtl/src/checker.cpp deleted file mode 100644 index 3a926360..00000000 --- a/src/jtl/src/checker.cpp +++ /dev/null @@ -1,198 +0,0 @@ -#include "checker.h" -#include "jtl.h" -#include "proto.h" -#include -#include -#include - -struct CheckerData { - checker::CheckerInput inp; - FILE* out_file = nullptr; - FILE* comment_file = nullptr; -}; - -CheckerData CHECKER; - -checker::CheckerInput checker::init(bool open_files) { - checker::CheckerInput inp; - if (open_files) { - inp.corr_answer = get_env_file("JJS_CORR", "r"); - inp.sol_answer = get_env_file("JJS_SOL", "r"); - inp.test = get_env_file("JJS_TEST", "r"); - } else { - inp.fd_corr = get_env_int("JJS_CORR"); - inp.fd_sol = get_env_int("JJS_SOL"); - inp.fd_test = get_env_int("JJS_TEST"); - } - CHECKER.out_file = get_env_file("JJS_CHECKER_OUT", "w"); - CHECKER.comment_file = get_env_file("JJS_CHECKER_COMMENT", "w"); - CHECKER.inp = inp; - return inp; -} - -void checker::finish(Outcome outcome) { - FILE* proto_file = CHECKER.out_file; - fprintf(proto_file, "outcome="); - switch (outcome) { - case Outcome::WRONG_ANSWER: - fprintf(proto_file, "WrongAnswer"); - break; - case Outcome::CHECKER_LOGIC_ERROR: - fprintf(proto_file, "CheckerLogicError"); - break; - case Outcome::OK: - fprintf(proto_file, "Ok"); - break; - case Outcome::PRESENTATION_ERROR: - fprintf(proto_file, "PresentationError"); - break; - } - - exit(0); -} - -const int COMMENT_OUT_BUF_LEN = 4096; - -char COMMENT_OUT_BUF[COMMENT_OUT_BUF_LEN]; - -void checker::comment(const char* format, ...) { - va_list args; - va_start(args, format); - int num_written = - vsnprintf(COMMENT_OUT_BUF, COMMENT_OUT_BUF_LEN, format, args); - va_end(args); - FILE* f = CHECKER.comment_file; - fprintf(f, "%s", COMMENT_OUT_BUF); - if (num_written == COMMENT_OUT_BUF_LEN) { - fprintf(f, "... (comment was truncated)"); - } - fprintf(f, "\n"); -} - -void checker::corr_scanf(const char* format, ...) { - va_list args; - va_start(args, format); - int res = vfscanf(CHECKER.inp.corr_answer, format, args); - va_end(args); - if (res == EOF) { - comment("fatal: unexpected EOF when reading correct answer"); - finish(Outcome::CHECKER_LOGIC_ERROR); - } -} - -void checker::sol_scanf(const char* format, ...) { - va_list args; - va_start(args, format); - int res = vfscanf(CHECKER.inp.sol_answer, format, args); - va_end(args); - if (res == EOF) { - comment("error: unexpected EOF when reading provided answer"); - finish(Outcome::PRESENTATION_ERROR); - } -} - -void checker::test_scanf(const char* format, ...) { - va_list args; - va_start(args, format); - int res = vfscanf(CHECKER.inp.test, format, args); - va_end(args); - if (res == EOF) { - comment("fatal: unexpected EOF when reading test file"); - finish(Outcome::CHECKER_LOGIC_ERROR); - } -} - -void checker::check_corr_eof() { - if (!is_file_eof(CHECKER.inp.corr_answer)) { - comment("fatal: correct answer has data yet"); - finish(Outcome::CHECKER_LOGIC_ERROR); - } -} - -void checker::check_test_eof() { - if (!is_file_eof(CHECKER.inp.test)) { - comment("fatal: test file has data yet"); - finish(Outcome::CHECKER_LOGIC_ERROR); - } -} - -void checker::check_sol_eof() { - if (!is_file_eof(CHECKER.inp.sol_answer)) { - comment("error: solution has data yet"); - finish(Outcome::PRESENTATION_ERROR); - } -} - -char* checker::next_token(FILE* f) { - int cap = 16; - char* out = (char*) check_oom(malloc(16)); - int len = 0; - bool had_data = false; - while (true) { - char ch; - clearerr(f); - int ret = fread(&ch, 1, 1, f); - if (ret == 0 && ferror(f) != 0) { - comment("check_utils: read failed"); - exit(1); - } - if (ret == 0) { - break; - } - if (isspace(ch)) { - if (had_data) { - break; - } else { - continue; - } - } - if (len + 1 == cap) { - cap = 2 * cap; - void* const realloced = realloc(out, cap); - out = (char*) check_oom(realloced); - } - had_data = true; - out[len] = ch; - ++len; - } - if (!had_data) { - // no chars were read - free(out); - return nullptr; - } - out[len] = '\0'; - return out; -} - -bool checker::compare_epsilon(long double expected, long double actual, - long double epsilon) { - assert(std::isfinite(expected)); - if (!std::isfinite(actual)) { - return false; - } - - long double absolute_error = std::abs(expected - actual); - if (std::abs(expected) < 1.0) { - return absolute_error <= epsilon; - } else { - long double relative_error = absolute_error / std::abs(expected); - return relative_error <= epsilon; - } -} - -bool checker::compare_strings_ignore_case(const char* lhs, const char* rhs) { - while (true) { - char a = *lhs; - char b = *rhs; - if (a == '\0' || b == '\0') { - return a == b; - } - a = tolower(a); - b = tolower(b); - if (a != b) { - return false; - } - ++lhs; - ++rhs; - } -} diff --git a/src/jtl/src/jtl.cpp b/src/jtl/src/jtl.cpp deleted file mode 100644 index 0c82aa19..00000000 --- a/src/jtl/src/jtl.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "jtl.h" -#include "proto.h" -#include -#include -#include -#include -#include - -static bool is_char_whitespace(char c) { - return c == ' ' || c == '\n' || c == '\t'; -} - -bool is_file_eof(FILE* f) { - const int BUF_SIZE = 256; - char buf[BUF_SIZE]; - while (true) { - int nread = fread(buf, 1, BUF_SIZE, f); - for (int i = 0; i < nread; ++i) { - if (!is_char_whitespace(buf[i])) { - return false; - } - } - if (nread == 0) { - break; - } - } - return true; -} - -void oom() { - fprintf(stderr, "Out of memory"); - abort(); -} - -void* check_oom(void* ptr) { - if (ptr) { - return ptr; - } else { - oom(); - } -} - -void die(char const* message, ...) { - va_list v; - va_start(v, message); - vfprintf(stderr, message, v); - exit(1); -} diff --git a/src/jtl/src/proto.cpp b/src/jtl/src/proto.cpp deleted file mode 100644 index 22639da2..00000000 --- a/src/jtl/src/proto.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "proto.h" -#include "jtl.h" -#include -#include -#include -#include - -char* get_env(const char* var_name) { - char* res = getenv(var_name); - if (res == nullptr) { - die("ERROR: var %s not present\n", var_name); - } - return res; -} - -int get_env_int(const char* var_name) { - char* res = get_env(var_name); - int ans; - if (sscanf(res, "%d", &ans) == 0) { - die("ERROR: var `%s` has value `%s`, which is not integer\n", var_name, - res); - } - return ans; -} - -FILE* get_env_file(const char* var_name, const char* mode) { - int fd = get_env_int(var_name); - FILE* file = fdopen(fd, mode); - if (file == nullptr) { - die("ERROR: var `%s` contains fd `%d`, which is not file of mode %s", - var_name, fd, mode); - } - return file; -} - -const uint8_t CHAR_BAD = 255; - -uint8_t decode_hex_char(char x) { - if ('0' <= x && x <= '9') - return x - '0'; - if ('a' <= x && x <= 'f') - return x - 'a' + 10; - return CHAR_BAD; -} - -BinString decode_hex(char* data) { - size_t n = strlen(data); - if (n % 2 != 0) - return {}; - auto out = new uint8_t[n / 2]; - for (size_t i = 0; i < n / 2; ++i) { - auto a = decode_hex_char(data[2 * i]); - auto b = decode_hex_char(data[2 * i + 1]); - if (a == CHAR_BAD || b == CHAR_BAD) { - delete[] out; - return {}; - } - out[i] = a * 16 + b; - } - BinString bs; - bs.len = n / 2; - bs.head.reset(out); - return std::move(bs); -} - -BinString get_env_hex(const char* var_name) { - char* value = get_env(var_name); - - auto res = decode_hex(value); - if (!res.head) { - die("ERROR: var `%s` contains '%s', which is not hex\n", var_name, - value); - } - return res; -} diff --git a/src/jtl/src/proto.h b/src/jtl/src/proto.h deleted file mode 100644 index 4e0b97c9..00000000 --- a/src/jtl/src/proto.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include -#include -#include - -char* get_env(const char* var_name); - -int get_env_int(const char* var_name); - -FILE* get_env_file(const char* var_name, const char* mode); - -struct BinString { - std::unique_ptr head; - size_t len = 0; -}; - -BinString get_env_hex(const char* var_name); diff --git a/src/jtl/src/testgen.cpp b/src/jtl/src/testgen.cpp deleted file mode 100644 index 50a05146..00000000 --- a/src/jtl/src/testgen.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "testgen.h" -#include "jtl.h" -#include "proto.h" -#include -#include -#include -#include - -testgen::Generator::Generator(uint64_t seed) : gen(seed) {} - -uint64_t testgen::Generator::next_u64() { return gen(); } - -/// Returns random number in [0; n) -static uint64_t get_rand(uint64_t n, std::mt19937_64& gen) { - assert(n != 0); - uint64_t bits = n; - // step one: we want `bits` to contain highest bit of n, and all smaller - bits |= (bits >> 1u); - bits |= (bits >> 2u); - bits |= (bits >> 4u); - bits |= (bits >> 8u); - bits |= (bits >> 16u); - bits |= (bits >> 32u); - while (true) { - uint64_t s = gen(); - s &= bits; - // why is it fast: bits is smaller than 2*n, so probability that this - // iteration succeed is at least 0.5 - if (s < n) { - return s; - } - } -} - -uint64_t testgen::Generator::next_range(uint64_t lo, uint64_t hi) { - assert(lo < hi); - return lo + get_rand(hi - lo, gen); -} -testgen::TestgenSession::TestgenSession(uint64_t _seed) : gen(_seed) {} -testgen::TestgenSession testgen::init() { - auto rand_seed = get_env_hex("JJS_RANDOM_SEED"); - if (rand_seed.len != 8) { - die("rand_seed has incorrect length (%zu instead of 8)\n", - rand_seed.len); - } - uint64_t random_seed; - memcpy(&random_seed, rand_seed.head.get(), 8); - testgen::TestgenSession sess {random_seed}; - sess.test_id = get_env_int("JJS_TEST_ID"); - return sess; -} diff --git a/src/jtl/src/util.cpp b/src/jtl/src/util.cpp deleted file mode 100644 index 07884c5a..00000000 --- a/src/jtl/src/util.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "util.h" -#include - -static const uintptr_t SIGN_EXTENSION = 0xffff'0000'0000'0000; - -bool jtl::check_pointer(void* ptr) { - const auto p = (uintptr_t) ptr; - const auto sign_ext = p & SIGN_EXTENSION; - return (sign_ext == SIGN_EXTENSION) || (sign_ext == 0); -} \ No newline at end of file diff --git a/src/jtl/src/util.h b/src/jtl/src/util.h deleted file mode 100644 index ef32a607..00000000 --- a/src/jtl/src/util.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include -namespace jtl { -bool check_pointer(void* ptr); - -struct FileInfo { - char* path; - FILE* file; -}; -} // namespace jtl \ No newline at end of file diff --git a/src/pom/Cargo.toml b/src/pom/Cargo.toml deleted file mode 100644 index bd301df6..00000000 --- a/src/pom/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "pom" -version = "0.1.0" -authors = ["Mikail Bagishov "] -edition = "2018" -description = "problems&contests object model (shared between invoker and tt)" - -[dependencies] -serde = { version = "1.0.117", features = ["derive"] } diff --git a/src/pom/src/lib.rs b/src/pom/src/lib.rs deleted file mode 100644 index b3db7cf5..00000000 --- a/src/pom/src/lib.rs +++ /dev/null @@ -1,132 +0,0 @@ -use serde::{Deserialize, Serialize}; - -#[derive(Serialize, Deserialize, Debug, Clone, Copy)] -pub struct Limits { - /// Memory limit in bytes - pub memory: Option, - /// Time limit in milliseconds - pub time: Option, - /// Process count limit - pub process_count: Option, - /// Working dir size limit in bytes - pub work_dir_size: Option, -} - -impl Limits { - fn default_num_procs() -> u64 { - 16 - } - - fn default_memory() -> u64 { - 256 * 1024 * 1024 - } - - fn default_time() -> u64 { - 3000 - } - - fn default_work_dir_size() -> u64 { - 16 * 1024 * 1024 - } - - pub fn time(self) -> u64 { - self.time.unwrap_or_else(Self::default_time) - } - - pub fn memory(self) -> u64 { - self.memory.unwrap_or_else(Self::default_memory) - } - - pub fn process_count(self) -> u64 { - self.process_count.unwrap_or_else(Self::default_num_procs) - } - - pub fn work_dir_size(self) -> u64 { - self.work_dir_size - .unwrap_or_else(Self::default_work_dir_size) - } -} - -impl Default for Limits { - fn default() -> Limits { - Limits { - memory: Some(Limits::default_memory()), - time: Some(Limits::default_time()), - process_count: Some(Limits::default_num_procs()), - work_dir_size: Some(Limits::default_work_dir_size()), - } - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub enum FileRefRoot { - Problem, - Root, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct FileRef { - pub root: FileRefRoot, - pub path: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Test { - pub path: FileRef, - pub correct: Option, - pub limits: Limits, - pub group: String, -} - -#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize, Hash)] -pub struct TestId(pub std::num::NonZeroU32); - -impl TestId { - /// Creates `TestId` from `id` - /// # Panics - /// Will panic if `id` is 0. Only use this function when you can prove `id` is non-null. - pub fn make(id: u32) -> Self { - Self(std::num::NonZeroU32::new(id).expect("TestId must be non-null")) - } - - pub fn get(self) -> u32 { - self.0.get() - } -} - -impl From for u32 { - fn from(t: TestId) -> u32 { - t.get() - } -} - -impl std::fmt::Display for TestId { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - f.debug_tuple("TestId").field(&self.0.get()).finish() - } -} - -impl TestId { - pub fn to_idx(self) -> usize { - (self.0.get() - 1) as usize - } -} - -impl std::ops::Index for Vec { - type Output = Test; - - fn index(&self, index: TestId) -> &Self::Output { - &self[index.to_idx()] - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Problem { - pub title: String, - pub name: String, - pub tests: Vec, - pub checker_exe: FileRef, - pub checker_cmd: Vec, - pub valuer_exe: FileRef, - pub valuer_cfg: FileRef, -} diff --git a/src/pps/Readme.md b/src/pps/Readme.md deleted file mode 100644 index adbae55e..00000000 --- a/src/pps/Readme.md +++ /dev/null @@ -1,2 +0,0 @@ -# JJS Problem preparation system (PPS) -PPS goal is to provide next-generation problem preparation experience diff --git a/src/pps/api/Cargo.toml b/src/pps/api/Cargo.toml deleted file mode 100644 index 161ea612..00000000 --- a/src/pps/api/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "pps-api" -version = "0.1.0" -authors = ["Mikail Bagishov "] -edition = "2018" - -[dependencies] -serde = { version = "1.0.117", features = ["derive"] } -reqwest = "0.10.8" -anyhow = "1.0.33" -serde_json = "1.0.59" -tokio = { version = "0.2.22", features = ["sync"] } -tracing = "0.1.21" -rpc = { git = "https://github.com/jjs-dev/commons" } diff --git a/src/pps/api/src/compile_problem.rs b/src/pps/api/src/compile_problem.rs deleted file mode 100644 index ce4808fc..00000000 --- a/src/pps/api/src/compile_problem.rs +++ /dev/null @@ -1,35 +0,0 @@ -//! Specifies that problem contained in workspace -//! should be compiled -use serde::{Deserialize, Serialize}; -use std::path::PathBuf; - -#[derive(Serialize, Deserialize)] -pub struct Request { - /// Path to problem source directory - pub problem_path: PathBuf, - /// Where to put compiled package - pub out_path: PathBuf, - /// Ignore existing files in out_path - pub force: bool, -} - -#[derive(Serialize, Deserialize)] -pub enum Update { - /// Contains some warnings that should be displayed to used. - /// Appears at most once. - Warnings(Vec), - /// Solution with given name is being built - BuildSolution(String), - /// Test generator with given name is being built - BuildTestgen(String), - /// Checker building started - BuildChecker, - /// Test generation started. `count` tests will be processed. - /// Appears at most once before `GenerateTest` updates. - GenerateTests { count: usize }, - /// Test `test_id` is being generated. Total test count is `count`. - /// `test_id`s are in range 1..=`count`. It is gu - GenerateTest { test_id: usize }, - /// Valuer config is being copied - CopyValuerConfig, -} diff --git a/src/pps/api/src/import_problem.rs b/src/pps/api/src/import_problem.rs deleted file mode 100644 index 2204f061..00000000 --- a/src/pps/api/src/import_problem.rs +++ /dev/null @@ -1,52 +0,0 @@ -//! Import problem from some other format -use serde::{Deserialize, Serialize}; -use std::path::PathBuf; -#[derive(Serialize, Deserialize)] -pub struct Request { - /// this path specifies file or files that should be imported - pub src_path: PathBuf, - /// where to put generated problem source - pub out_path: PathBuf, - /// do not check that dest is empty - pub force: bool, -} - -#[derive(Serialize, Deserialize)] -pub enum Update { - /// Contains one property of discovered problem. - /// Each `property_name` will be reported at most once. - Property { - property_name: PropertyName, - property_value: String, - }, - /// Contains one warnings. May appear multiple times. - Warning(String), - /// Started importing checker - ImportChecker, - /// Started importing tests - ImportTests, - /// Finished importing tests. `count` tests imported. - ImportTestsDone { count: usize }, - /// Started importing solutions - ImportSolutions, - /// Started importing solution with specific name - ImportSolution(String), - /// Valuer config is detected and will be imported - ImportValuerConfig, - /// Valuer config was not found, default will be used - DefaultValuerConfig, -} - -#[derive(Serialize, Deserialize)] -pub enum PropertyName { - /// Value is time limit in milliseconds. - TimeLimit, - /// Value is memory limit in milliseconds. - MemoryLimit, - /// Value is printf-style pattern of input files. - InputPathPattern, - /// Value is printf-style pattern of output files. - OutputPathPattern, - /// Value is problem title. - ProblemTitle, -} diff --git a/src/pps/api/src/lib.rs b/src/pps/api/src/lib.rs deleted file mode 100644 index bf97deca..00000000 --- a/src/pps/api/src/lib.rs +++ /dev/null @@ -1,48 +0,0 @@ -//! All PPS apis. -//! -//! All paths are relative to workspace root. -pub mod compile_problem; -pub mod import_problem; - -use rpc::Route; -use std::convert::Infallible; -pub struct CompileProblem(Infallible); - -impl Route for CompileProblem { - type Request = rpc::Unary; - type Response = rpc::Streaming; - - const ENDPOINT: &'static str = "/problems/compile"; -} - -pub struct ImportProblem(Infallible); - -impl Route for ImportProblem { - type Request = rpc::Unary; - type Response = rpc::Streaming; - - const ENDPOINT: &'static str = "/problems/import"; -} - -/// Contains possible error os success -#[derive(serde::Serialize, serde::Deserialize, Debug)] -#[must_use = "this is Result in fact"] -pub struct SimpleFinish(pub Result<(), StringError>); - -impl From> for SimpleFinish { - fn from(r: anyhow::Result<()>) -> Self { - Self(r.map_err(|e| StringError(format!("{:#}", e)))) - } -} - -#[derive(Debug, serde::Serialize, serde::Deserialize)] -#[serde(transparent)] -pub struct StringError(pub String); - -impl std::fmt::Display for StringError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.fmt(f) - } -} - -impl std::error::Error for StringError {} diff --git a/src/pps/cli/Cargo.toml b/src/pps/cli/Cargo.toml deleted file mode 100644 index 54e7966e..00000000 --- a/src/pps/cli/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "pps-cli" -version = "0.1.0" -authors = ["Mikail Bagishov "] -edition = "2018" - -[dependencies] -serde = { version = "1.0.117", features = ["derive"] } -serde_json = "1.0.59" -anyhow = "1.0.33" -tokio = { version = "0.2.22", features = ["process", "macros", "rt-threaded", "fs"] } -clap = "3.0.0-beta.2" -pps-api = { path = "../api" } -pps-server = { path = "../server" } -rand = "0.7.3" -util = { path = "../../util" } -tracing = "0.1.21" -tracing-futures = "0.2.4" -rpc = { git = "https://github.com/jjs-dev/commons" } diff --git a/src/pps/cli/Dockerfile b/src/pps/cli/Dockerfile deleted file mode 100644 index 209cf825..00000000 --- a/src/pps/cli/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM debian:stable-slim -# TODO: use rustls -RUN apt-get update -y && apt-get install -y libssl-dev -ENV JJS_AUTH_DATA=/auth/authdata.yaml JJS_PATH=/jtl -COPY jjs-pps /jjs-pps -VOLUME ["/auth"] -ENTRYPOINT ["/jjs-pps"] diff --git a/src/pps/cli/src/client_util.rs b/src/pps/cli/src/client_util.rs deleted file mode 100644 index b562018d..00000000 --- a/src/pps/cli/src/client_util.rs +++ /dev/null @@ -1,30 +0,0 @@ -// To start server, we need to know some free port. -// Even if there is a way to get this information, it would -// suffer from race conditions. -// That's why, we simply select random port and try using it. -// 20 iterations give negligible probality of failure. -const BIND_ATTEMPTS: usize = 20; - -#[tracing::instrument] -pub(crate) async fn create_server( - cancel: tokio::sync::CancellationToken, -) -> anyhow::Result<(tokio::sync::oneshot::Receiver<()>, rpc::Client)> { - // TODO provide way to customize port or port range - tracing::info!("launching server"); - let mut last_error = None; - for _ in 0..BIND_ATTEMPTS { - let port: u16 = rand::random(); - match pps_server::serve(port, cancel.clone()).await { - Ok(rx) => { - let endpoint = format!("http://127.0.0.1:{}", port); - let client = rpc::Client::new(rpc::ReqwestEngine::new(), endpoint); - return Ok((rx, client)); - } - Err(err) => { - tracing::warn!(error=?err, "bind attempt unsuccessful"); - last_error = Some(err) - } - } - } - Err(last_error.expect("BIND_ATTEMPTS != 0")) -} diff --git a/src/pps/cli/src/compile.rs b/src/pps/cli/src/compile.rs deleted file mode 100644 index c7c3db8b..00000000 --- a/src/pps/cli/src/compile.rs +++ /dev/null @@ -1,73 +0,0 @@ -use anyhow::Context as _; -use pps_api::compile_problem::Update; -use std::path::PathBuf; - -#[derive(Debug, clap::Clap)] -pub struct CompileArgs { - /// Path to problem package root - #[clap(long = "pkg", short = 'P')] - pub pkg_path: Vec, - /// Output path - #[clap(long = "out", short = 'O')] - pub out_path: Vec, - /// Rewrite dir - #[clap(long, short = 'F')] - pub force: bool, -} - -#[tracing::instrument(skip(client, compile_args))] -pub async fn exec(client: &mut rpc::Client, compile_args: CompileArgs) -> anyhow::Result<()> { - if compile_args.out_path.len() != compile_args.pkg_path.len() { - anyhow::bail!("count(--pkg) != count(--out)"); - } - for (out_path, pkg_path) in compile_args.out_path.iter().zip(&compile_args.pkg_path) { - let req = pps_api::compile_problem::Request { - out_path: out_path.clone(), - problem_path: pkg_path.clone(), - force: compile_args.force, - }; - let (tx, mut resp) = client - .start::() - .await - .context("failed to start RPC call")?; - tx.send(req).await?; - let mut notifier = None; - while let Some(upd) = resp.next_event().await? { - match upd { - Update::Warnings(warnings) => { - if !warnings.is_empty() { - eprintln!("{} warnings", warnings.len()); - for warn in warnings { - eprintln!("- {}", warn); - } - } - } - Update::BuildSolution(solution_name) => { - println!("Building solution {}", &solution_name); - } - Update::BuildTestgen(testgen_name) => { - println!("Building generator {}", testgen_name); - } - Update::BuildChecker => { - println!("Building checker"); - } - Update::GenerateTests { count } => { - notifier = Some(crate::progress_notifier::Notifier::new(count)); - } - Update::GenerateTest { test_id } => { - notifier - .as_mut() - .expect("GenerateTest received before GenerateTests") - .maybe_notify(test_id); - } - Update::CopyValuerConfig => { - println!("Valuer config"); - } - } - } - if let Err(err) = resp.finish().await?.0 { - anyhow::bail!("Failed to build problem: {}", err) - } - } - Ok(()) -} diff --git a/src/pps/cli/src/import.rs b/src/pps/cli/src/import.rs deleted file mode 100644 index f3bd565c..00000000 --- a/src/pps/cli/src/import.rs +++ /dev/null @@ -1,88 +0,0 @@ -use anyhow::Context as _; -use pps_api::import_problem::{PropertyName, Update}; -use std::path::{Path, PathBuf}; - -#[derive(clap::Clap, Debug)] -pub struct ImportArgs { - /// Path to package being imported - #[clap(long = "in", short = 'I')] - pub in_path: PathBuf, - /// Out path (will contain ppc package) - #[clap(long = "out", short = 'O')] - pub out_path: PathBuf, - /// Rewrite dir - #[clap(long, short = 'F')] - pub force: bool, - /// Imported contest name - /// This option can only be used when importing contest - #[clap(long, short = 'N')] - pub contest_name: Option, -} - -async fn import_one_problem( - client: &mut rpc::Client, - src: &Path, - dest: &Path, - force: bool, -) -> anyhow::Result<()> { - let import_req = pps_api::import_problem::Request { - src_path: src.to_path_buf(), - out_path: dest.to_path_buf(), - force, - }; - let (tx, mut import) = client.start::().await?; - tx.send(import_req).await?; - while let Some(update) = import.next_event().await? { - match update { - Update::Property { - property_name, - property_value, - } => match property_name { - PropertyName::TimeLimit => println!("Time limit: {} ms", property_value), - PropertyName::MemoryLimit => { - let ml = property_value.parse::()?; - println!("Memory limit: {} bytes ({} MiBs)", ml, ml / (1 << 20)); - } - PropertyName::InputPathPattern => { - println!("Test input file path pattern: {}", property_value) - } - PropertyName::OutputPathPattern => { - println!("Test output file path pattern: {}", property_value) - } - PropertyName::ProblemTitle => println!("Problem title: {}", property_value), - }, - Update::Warning(warning) => eprintln!("warning: {}", warning), - Update::ImportChecker => println!("Importing checker"), - Update::ImportTests => println!("Importing tests"), - Update::ImportTestsDone { count } => println!("{} tests imported", count), - Update::ImportSolutions => println!("Importing solutions"), - Update::ImportSolution(solution) => println!("Importing solution '{}'", solution), - Update::ImportValuerConfig => println!("Importing valuer config"), - Update::DefaultValuerConfig => println!("Defaulting valuer config"), - } - } - import.finish().await?.0.context("build failure")?; - - println!("Import successful"); - - Ok(()) -} - -#[tracing::instrument(skip(client, args))] -pub(crate) async fn exec(client: &mut rpc::Client, args: ImportArgs) -> anyhow::Result<()> { - if args.force { - std::fs::remove_dir_all(&args.out_path).ok(); - std::fs::create_dir(&args.out_path).context("create out dir")?; - } else { - crate::check_dir(&PathBuf::from(&args.out_path), false /* TODO */)?; - } - - let src = &args.in_path; - let dest = &args.out_path; - - import_one_problem(client, src, dest, args.force).await?; - - // TODO support importing contests - - Ok(()) -} diff --git a/src/pps/cli/src/main.rs b/src/pps/cli/src/main.rs deleted file mode 100644 index 3d686a6c..00000000 --- a/src/pps/cli/src/main.rs +++ /dev/null @@ -1,56 +0,0 @@ -#![feature(is_sorted)] -#![allow(clippy::needless_lifetimes)] - -mod client_util; -mod compile; -mod import; -mod progress_notifier; - -#[derive(clap::Clap, Debug)] -#[clap(author, about)] -pub enum Args { - Compile(compile::CompileArgs), - Import(import::ImportArgs), -} - -use anyhow::Context as _; -use std::path::Path; - -fn check_dir(path: &Path, allow_nonempty: bool) -> anyhow::Result<()> { - if !path.exists() { - anyhow::bail!("error: path {} not exists", path.display()); - } - if !path.is_dir() { - anyhow::bail!("error: path {} is not directory", path.display()); - } - if !allow_nonempty && path.read_dir().unwrap().next().is_some() { - anyhow::bail!("error: dir {} is not empty", path.display()); - } - Ok(()) -} - -#[tokio::main] -async fn main() -> anyhow::Result<()> { - use clap::Clap; - util::log::setup(); - let args = Args::parse(); - tracing::info!("starting new server in background"); - let cancel = tokio::sync::CancellationToken::new(); - let (server_done_rx, mut client) = client_util::create_server(cancel.clone()).await?; - process_args(args, &mut client) - .await - .context("failed to process args")?; - cancel.cancel(); - tracing::info!("waiting for server shutdown"); - server_done_rx.await.ok(); - Ok(()) -} - -#[tracing::instrument(skip(args, client))] -async fn process_args(args: Args, client: &mut rpc::Client) -> anyhow::Result<()> { - tracing::info!(args=?args, "executing requested command"); - match args { - Args::Compile(compile_args) => compile::exec(client, compile_args).await, - Args::Import(import_args) => import::exec(client, import_args).await, - } -} diff --git a/src/pps/cli/src/progress_notifier.rs b/src/pps/cli/src/progress_notifier.rs deleted file mode 100644 index 6d8752cd..00000000 --- a/src/pps/cli/src/progress_notifier.rs +++ /dev/null @@ -1,46 +0,0 @@ -use std::time::{Duration, Instant}; - -const STEP_PERCENTAGE_THRESHOLD: usize = 20; -const STEP_DURATION_THRESHOLD: Duration = Duration::from_secs(10); - -pub(super) struct Notifier { - last_step: usize, - total_step_count: usize, - last_time: std::time::Instant, -} - -impl Notifier { - pub(super) fn new(cnt: usize) -> Notifier { - assert_ne!(cnt, 0); - Notifier { - last_step: 0, - total_step_count: cnt, - last_time: Instant::now(), - } - } - - fn do_notify(&mut self, new_step: usize) { - println!("Progress: {}/{}", new_step, self.total_step_count); - self.last_step = new_step; - self.last_time = Instant::now(); - } - - pub(super) fn maybe_notify(&mut self, new_step: usize) { - let mut should_notify = false; - { - let cnt_delta = new_step - self.last_step; - if 100 * cnt_delta >= STEP_PERCENTAGE_THRESHOLD * self.total_step_count { - should_notify = true; - } - } - { - let time_delta = Instant::now().duration_since(self.last_time); - if time_delta >= STEP_DURATION_THRESHOLD { - should_notify = true; - } - } - if should_notify { - self.do_notify(new_step); - } - } -} diff --git a/src/pps/server/Cargo.toml b/src/pps/server/Cargo.toml deleted file mode 100644 index 90a07d74..00000000 --- a/src/pps/server/Cargo.toml +++ /dev/null @@ -1,32 +0,0 @@ -[package] -name = "pps-server" -version = "0.1.0" -authors = ["Mikail Bagishov "] -edition = "2018" - -[dependencies] -tokio = { version = "0.2.22", features = ["macros", "tracing"] } -serde = "1.0.117" -serde_json = "1.0.59" -anyhow = "1.0.33" -toml = "0.5.7" -thiserror = "1.0.21" -async-trait = "0.1.41" -getrandom = { version = "0.2.0", features = ["std"] } -glob = "0.3.0" -pom = { path = "../../pom" } -libc = "0.2.80" -roxmltree = "0.13.0" -serde_yaml = "0.8.14" -pest = "2.1.3" -pest_derive = "2.1.0" -formatf = { git = "https://github.com/mikailbag/formatf" } -svaluer = { path = "../../svaluer" } -hex = "0.4.2" -pps-api = { path = "../api" } -hyper = "0.13.8" -tracing = "0.1.21" -tracing-futures = { version = "0.2.4", features = ["futures-03"] } -either = "1.6.1" -rpc = { git = "https://github.com/jjs-dev/commons" } -futures-util = "0.3.7" diff --git a/src/pps/server/src/command.rs b/src/pps/server/src/command.rs deleted file mode 100644 index 9572e331..00000000 --- a/src/pps/server/src/command.rs +++ /dev/null @@ -1,97 +0,0 @@ -// TODO: split all this stuff to separate library -use anyhow::Context; -use serde::{Deserialize, Serialize}; -use std::ffi::{OsStr, OsString}; - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Command { - argv: Vec, - exe: OsString, - cwd: Option, - env: Vec<(OsString, OsString)>, -} - -impl Command { - pub fn to_tokio_command(&self) -> tokio::process::Command { - let mut cmd = tokio::process::Command::new(&self.exe); - cmd.args(self.argv.iter()); - if let Some(cwd) = &self.cwd { - cmd.current_dir(cwd); - } - cmd.envs(self.env.iter().cloned()); - cmd - } - - pub fn to_string_pretty(&self) -> String { - use std::fmt::Write; - let mut out = String::new(); - if let Some(cwd) = &self.cwd { - write!(out, "cd {} && ", cwd.to_string_lossy()).unwrap(); - } - for (k, v) in &self.env { - write!(out, "{}={} ", k.to_string_lossy(), v.to_string_lossy()).unwrap(); - } - write!(out, "{}", self.exe.to_string_lossy()).unwrap(); - for arg in &self.argv { - write!(out, " {}", arg.to_string_lossy()).unwrap(); - } - out - } - - pub async fn run_quiet(&mut self) -> anyhow::Result { - use std::os::unix::process::ExitStatusExt; - let mut s = self.to_tokio_command(); - let out = s.output().await.context("couldn't spawn")?; - let status = out.status; - if status.success() { - return Ok(out); - } - - let exit_code = if status.code().is_some() { - format!("normal: {}", status.code().unwrap()) - } else { - format!("signaled: {}", status.signal().unwrap()) - }; - anyhow::bail!( - "child process did not finished successfully (exit code {})\ncommand: `{}`\nchild stdout:\n{}\nchild stderr:\n{}", - exit_code, - self, - String::from_utf8_lossy(&out.stdout), - String::from_utf8_lossy(&out.stderr) - ) - } -} - -impl std::fmt::Display for Command { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - f.write_str(&self.to_string_pretty()) - } -} - -impl Command { - pub fn new(s: impl AsRef) -> Command { - Command { - exe: s.as_ref().to_os_string(), - argv: Vec::new(), - cwd: None, - env: Vec::new(), - } - } - - pub fn arg(&mut self, a: impl AsRef) -> &mut Self { - self.argv.push(a.as_ref().to_os_string()); - self - } - - pub fn env(&mut self, key: impl AsRef, value: impl AsRef) -> &mut Self { - let key = key.as_ref().to_os_string(); - let value = value.as_ref().to_os_string(); - self.env.push((key, value)); - self - } - - pub fn current_dir(&mut self, cwd: impl AsRef) -> &mut Self { - self.cwd.replace(cwd.as_ref().to_os_string()); - self - } -} diff --git a/src/pps/server/src/compile.rs b/src/pps/server/src/compile.rs deleted file mode 100644 index fbb17852..00000000 --- a/src/pps/server/src/compile.rs +++ /dev/null @@ -1,70 +0,0 @@ -//! This module implements compiling source package into invoker package -pub(crate) mod build; -mod builder; - -use anyhow::Context as _; -use pps_api::{ - compile_problem::{Request, Update}, - SimpleFinish, -}; -use std::{path::Path, sync::Arc}; - -impl rpc::Handler for crate::Service { - type Error = anyhow::Error; - type Fut = futures_util::future::BoxFuture<'static, Result<(), Self::Error>>; - - fn handle( - self, - rx: rpc::UnaryRx, - mut tx: rpc::StreamingTx, - ) -> Self::Fut { - Box::pin(async move { - let args = rx.recv().await?; - let response = exec_compile_request(args, self.0, &mut tx).await; - tx.finish(response.into()).await?; - Ok(()) - }) - } -} - -/// This function actually implements request processing. -/// It's return value is used as response. -pub(crate) async fn exec_compile_request( - args: Request, - data: Arc, - tx: &mut rpc::StreamingTx, -) -> anyhow::Result<()> { - if args.force { - std::fs::remove_dir_all(&args.out_path).ok(); - tokio::fs::create_dir_all(&args.out_path).await?; - } else { - crate::check_dir(&args.out_path, false /* TODO */)?; - } - let toplevel_manifest = args.problem_path.join("problem.toml"); - let toplevel_manifest = std::fs::read_to_string(toplevel_manifest)?; - - let raw_problem_cfg: crate::manifest::RawProblem = - toml::from_str(&toplevel_manifest).context("problem.toml parse error")?; - let (problem_cfg, warnings) = raw_problem_cfg.postprocess()?; - - tx.send_event(Update::Warnings(warnings)).await?; - - let out_dir = args.out_path.canonicalize().context("resolve out dir")?; - let problem_dir = args - .problem_path - .canonicalize() - .context("resolve problem dir")?; - - let mut builder = builder::ProblemBuilder { - cfg: &problem_cfg, - problem_dir: &problem_dir, - out_dir: &out_dir, - jtl_dir: &data.jjs_dir, - build_backend: &build::Pibs { - jjs_dir: Path::new(&data.jjs_dir), - }, - tx, - }; - builder.build().await?; - Ok(()) -} diff --git a/src/pps/server/src/compile/build.rs b/src/pps/server/src/compile/build.rs deleted file mode 100644 index 7d0d8a55..00000000 --- a/src/pps/server/src/compile/build.rs +++ /dev/null @@ -1,130 +0,0 @@ -use std::path::{Path, PathBuf}; -use thiserror::Error; - -#[derive(Debug, Clone)] -pub(crate) struct Task { - /// Directory with source files, or path to single file - pub(crate) src: PathBuf, - /// Directory for build artifacts - pub(crate) dest: PathBuf, - /// Directort for temporary data - pub(crate) tmp: PathBuf, -} - -pub(crate) struct TaskSuccess { - pub(crate) command: crate::command::Command, -} - -#[derive(Debug, Error)] -pub(crate) enum TaskError { - #[error("child command errored: code {:?}", _0.status.code())] - ExitCodeNonZero(std::process::Output), - #[error("io error: {source}")] - Io { - #[from] - source: std::io::Error, - }, - #[error("feature not supported: {feature}")] - FeatureNotSupported { feature: &'static str }, -} - -impl Task { - fn multi_file(&self) -> bool { - self.src.is_dir() - } -} - -#[async_trait::async_trait] -trait CommandExt { - async fn run(&mut self) -> Result<(), TaskError>; -} - -#[async_trait::async_trait] -impl CommandExt for tokio::process::Command { - async fn run(&mut self) -> Result<(), TaskError> { - let out = self.output().await?; - if out.status.success() { - Ok(()) - } else { - Err(TaskError::ExitCodeNonZero(out)) - } - } -} - -#[async_trait::async_trait] -pub(crate) trait BuildBackend: Send + Sync { - async fn process_task(&self, task: Task) -> Result; -} - -/// Ppc-integrated build system -pub(crate) struct Pibs<'a> { - pub(crate) jjs_dir: &'a Path, -} - -impl<'a> Pibs<'a> { - async fn process_cmake_task(&self, task: Task) -> Result { - // let cmake_lists = task.src.join("CMakeLists.txt"); - tokio::process::Command::new("cmake") - .arg("-S") - .arg(&task.src) - .arg("-B") - .arg(&task.tmp) - .run() - .await?; - - tokio::process::Command::new("cmake") - .arg("--build") - .arg(&task.tmp) - .run() - .await?; - - let dst = task.dest.join("bin"); - tokio::fs::copy(task.tmp.join("Out"), &dst).await?; - let run_cmd = crate::command::Command::new(dst); - Ok(TaskSuccess { command: run_cmd }) - } -} - -#[async_trait::async_trait] -impl<'a> BuildBackend for Pibs<'a> { - async fn process_task(&self, task: Task) -> Result { - if task.multi_file() { - let cmake_lists_path = task.src.join("CMakeLists.txt"); - if cmake_lists_path.exists() { - return self.process_cmake_task(task).await; - } - let python_path = task.src.join("main.py"); - if python_path.exists() { - let out_path = task.dest.join("out.py"); - std::fs::copy(&python_path, &out_path)?; - let mut command = crate::command::Command::new("python3"); - command.arg(&out_path); - return Ok(TaskSuccess { command }); - } - return Err(TaskError::FeatureNotSupported { - feature: "multi-file sources", - }); - } - - let incl_arg = format!("-I{}/include", self.jjs_dir.display()); - let link_arg = format!("-L{}/lib", self.jjs_dir.display()); - - let dest_file = task.dest.join("bin"); - tokio::process::Command::new("g++") - .arg("-std=c++17") - .arg(incl_arg) - .arg(link_arg) - .arg("-DPPC=1") - .arg(task.src) - .arg("-o") - .arg(&dest_file) - .arg("-ljtl") - .arg("-lpthread") - .arg("-ldl") - .run() - .await?; - - let command = crate::command::Command::new(&dest_file); - Ok(TaskSuccess { command }) - } -} diff --git a/src/pps/server/src/compile/builder.rs b/src/pps/server/src/compile/builder.rs deleted file mode 100644 index d00fc6c2..00000000 --- a/src/pps/server/src/compile/builder.rs +++ /dev/null @@ -1,472 +0,0 @@ -use crate::{ - command::Command, - compile::build::{BuildBackend, Task, TaskError}, -}; -use anyhow::Context as _; -use pom::{FileRef, FileRefRoot, Limits}; -use pps_api::compile_problem::Update; -use std::{ - collections::HashMap, - fmt::Write, - os::unix::io::IntoRawFd, - path::{Path, PathBuf}, -}; - -/// ProblemBuilder is struct, responsible for building single problem. -/// Its instances are managed by CompilerService. -pub(crate) struct ProblemBuilder<'a> { - /// Problem manifest - pub(crate) cfg: &'a crate::manifest::Problem, - /// Directory, containing problem source files - pub(crate) problem_dir: &'a Path, - /// Directory for output files - pub(crate) out_dir: &'a Path, - /// Path to local JTL installation - pub(crate) jtl_dir: &'a Path, - /// Used to execute build tasks (e.g. builds checker or solution) - pub(crate) build_backend: &'a dyn BuildBackend, - /// Used to return live building progress - pub(crate) tx: &'a mut rpc::StreamingTx, -} - -/// Fills given buffer with random hex string -fn get_entropy_hex(buf: &mut [u8]) { - getrandom::getrandom(buf).expect("get entropy failed"); - for i in buf.iter_mut() { - *i %= 16; - if *i < 10 { - *i += b'0'; - } else { - *i = b'a' + (*i - 10); - } - } -} - -/// Applies merge patch `other` to a `place`: -/// If `other` is None, does nothing. -/// If `other` is Some, stores `other` inner value into `place`. -fn merge_option(place: &mut Option, other: Option) { - if let Some(x) = other { - place.replace(x); - } -} - -/// Merges several `Limits` object. Last element of slice will have maximal proirity. -fn merge_limits(limits_set: &[Limits]) -> Limits { - let mut res = Limits::default(); - for lim in limits_set { - merge_option(&mut res.memory, lim.memory); - merge_option(&mut res.process_count, lim.process_count); - merge_option(&mut res.time, lim.time); - } - res -} - -// TODO: remove duplicated code -impl<'a> ProblemBuilder<'a> { - /// Higher-level wrapper for `self.build_backend` - async fn do_build(&self, src: &Path, dest: &Path) -> anyhow::Result { - tokio::fs::create_dir_all(dest) - .await - .context("failed to create dir")?; - - let build_id = std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .unwrap() - .as_micros() - .to_string(); - let build_dir = format!("/tmp/tt-build-{}", &build_id); - tokio::fs::create_dir(&build_dir) - .await - .expect("couldn't create build dir"); - - let task = Task { - src: src.to_path_buf(), - dest: dest.to_path_buf(), - tmp: Path::new(&build_dir).to_path_buf(), - }; - match self.build_backend.process_task(task.clone()).await { - Ok(cmd) => Ok(cmd.command), - Err(err) => { - let mut description = String::new(); - writeln!( - &mut description, - "Build error: unable to run build task: {}", - err - ) - .unwrap(); - if let TaskError::ExitCodeNonZero(out) = err { - writeln!( - &mut description, - "--- stdout ---\n{}", - String::from_utf8_lossy(&out.stdout) - ) - .unwrap(); - writeln!( - &mut description, - "--- stderr ---\n{}", - String::from_utf8_lossy(&out.stderr) - ) - .unwrap(); - } - writeln!(&mut description, "Build task: {:#?}", task).unwrap(); - anyhow::bail!("task execution error: {}", description) - } - } - } - - /// async wrapper for `glob::glob` - async fn glob(&self, suffix: &str) -> anyhow::Result> { - let pattern = format!("{}/{}", self.problem_dir.display(), suffix); - tokio::task::spawn_blocking(move || -> anyhow::Result> { - let paths = glob::glob(&pattern) - .context("blob pattern error")? - .map(|x| match x { - Ok(p) => Ok(p), - Err(err) => { - anyhow::bail!("Glob error: {}", err); - } - }) - .collect::>>()?; - Ok(paths) - }) - .await - .unwrap() - } - - /// Builds single solution - async fn build_solution(&mut self, sol_path: PathBuf) -> anyhow::Result<(String, Command)> { - let sol_id = sol_path - .file_stem() - .unwrap() - .to_str() - .context("path is not utf8")? - .to_owned(); - self.tx - .send_event(Update::BuildSolution(sol_id.clone())) - .await?; - - let out_path = format!("{}/assets/sol-{}", self.out_dir.display(), &sol_id); - Ok(( - sol_id, - self.do_build(&sol_path, &PathBuf::from(&out_path)).await?, - )) - } - - /// Builds all solutions - async fn build_solutions(&mut self) -> anyhow::Result> { - let mut out = HashMap::new(); - for solution_path in self.glob("solutions/*").await? { - let (sol_id, cmd) = self.build_solution(solution_path).await?; - out.insert(sol_id, cmd); - } - Ok(out) - } - - /// Builds single testgen - async fn build_testgen( - &mut self, - testgen_path: &Path, - testgen_name: &str, - ) -> anyhow::Result { - self.tx - .send_event(Update::BuildTestgen(testgen_name.to_string())) - .await?; - let out_path = format!("{}/assets/testgen-{}", self.out_dir.display(), testgen_name); - self.do_build(testgen_path, &Path::new(&out_path)).await - } - - /// Builds all testgens - async fn build_testgens(&mut self) -> anyhow::Result> { - let mut out = HashMap::new(); - for testgen in self.glob("generators/*").await? { - let testgen_name = testgen - .file_stem() - .unwrap() - .to_str() - .context("utf8 error")?; - let testgen_launch_cmd = self.build_testgen(&testgen, testgen_name).await?; - out.insert(testgen_name.to_string(), testgen_launch_cmd); - } - Ok(out) - } - - /// Adds common modifications to a child process builder - fn configure_command(&self, cmd: &mut Command) { - cmd.current_dir(self.problem_dir); - cmd.env("JJS_PROBLEM_SRC", &self.problem_dir); - cmd.env("JJS_PROBLEM_DEST", &self.out_dir); - } - - /// Builds all tests - async fn build_tests( - &mut self, - testgens: &HashMap, - gen_answers: Option<&Command>, - ) -> anyhow::Result> { - let tests_path = format!("{}/assets/tests", self.out_dir.display()); - std::fs::create_dir_all(&tests_path).expect("couldn't create tests output dir"); - self.tx - .send_event(Update::GenerateTests { - count: self.cfg.tests.len(), - }) - .await?; - let mut out = vec![]; - for (i, test_spec) in self.cfg.tests.iter().enumerate() { - let tid = i + 1; - self.tx - .send_event(Update::GenerateTest { test_id: tid }) - .await?; - - let out_file_path = format!("{}/{}-in.txt", &tests_path, tid); - match &test_spec.gen { - crate::manifest::TestGenSpec::Generate { testgen, args } => { - let testgen_cmd = testgens - .get(testgen) - .with_context(|| format!("error: unknown testgen {}", testgen))?; - - let mut entropy_buf = [0; crate::manifest::RANDOM_SEED_LENGTH]; - get_entropy_hex(&mut entropy_buf); - let entropy = String::from_utf8(entropy_buf.to_vec()).unwrap(); // only ASCII can be here - - let mut cmd = testgen_cmd.clone(); - for a in args { - cmd.arg(a); - } - cmd.env("JJS_TEST_ID", &tid.to_string()); - cmd.env("JJS_RANDOM_SEED", &entropy); - self.configure_command(&mut cmd); - let gen_out = cmd.run_quiet().await?; - tokio::fs::write(&out_file_path, gen_out.stdout) - .await - .context("failed to write test")?; - } - crate::manifest::TestGenSpec::File { path } => { - let src_path = self.problem_dir.join("tests").join(path); - if let Err(e) = std::fs::copy(&src_path, &out_file_path) { - anyhow::bail!( - "Couldn't copy test data from {} to {}: {}", - src_path.display(), - out_file_path, - e, - ); - } - } - } - let mut test_info = pom::Test { - path: FileRef { - path: format!("tests/{}-in.txt", tid), - root: FileRefRoot::Problem, - }, - correct: None, - limits: merge_limits(&[self.cfg.limits, test_spec.limits]), - group: test_spec.group.clone(), - }; - if let Some(cmd) = gen_answers { - let test_data = tokio::fs::File::open(&out_file_path).await?; - - let correct_file_path = format!("{}/{}-out.txt", &tests_path, tid); - - let answer_data = tokio::fs::File::create(&correct_file_path).await?; - - let mut cmd = cmd.clone(); - self.configure_command(&mut cmd); - let mut cmd = cmd.to_tokio_command(); - let mut close_handles = vec![]; - unsafe { - let test_data_fd = test_data.into_std().await.into_raw_fd(); - close_handles.push(test_data_fd); - let test_data_fd = libc::dup(test_data_fd); - close_handles.push(test_data_fd); - - let ans_data_fd = answer_data.into_std().await.into_raw_fd(); - close_handles.push(ans_data_fd); - let ans_data_fd = libc::dup(ans_data_fd); - close_handles.push(ans_data_fd); - cmd.pre_exec(move || { - if libc::dup2(test_data_fd, 0) == -1 { - return Err(std::io::Error::last_os_error()); - } - if libc::dup2(ans_data_fd, 1) == -1 { - return Err(std::io::Error::last_os_error()); - } - Ok(()) - }); - } - let output = cmd - .stdin(crate::Stdio::piped()) - .stdout(crate::Stdio::piped()) - .stderr(crate::Stdio::piped()) - .output() - .await - .context("launch main solution error: {}")?; - if !output.status.success() { - anyhow::bail!( - "Error while generating correct answer for test {}: main solution failed: {}", - tid, - String::from_utf8_lossy(&output.stderr) - ); - } - let short_file_path = format!("tests/{}-out.txt", tid); - test_info.correct.replace(FileRef { - path: short_file_path, - root: FileRefRoot::Problem, - }); - for handle in close_handles { - unsafe { - libc::close(handle); - } - } - } - out.push(test_info); - } - Ok(out) - } - - /// Builds all checkers (currently only one is supported) - async fn build_checkers(&mut self) -> anyhow::Result { - // TODO: support multi-file checkers - let checker_path = format!("{}/checkers/main.cpp", self.problem_dir.display()); - self.build_checker(&checker_path).await - } - - /// Builds single checker - async fn build_checker(&mut self, checker_path: &str) -> anyhow::Result { - let out_path = self.out_dir.join("assets/checker"); - self.tx.send_event(Update::BuildChecker).await?; - match &self.cfg.check { - crate::manifest::Check::Custom(_) => { - self.do_build(Path::new(checker_path), Path::new(&out_path)) - .await?; - Ok(FileRef { - path: "checker/bin".to_string(), - root: FileRefRoot::Problem, - }) - } - crate::manifest::Check::Builtin(bc) => { - let src_path = self - .jtl_dir - .join(format!("bin/builtin-checker-{}", bc.name)); - tokio::fs::create_dir(&out_path) - .await - .context("failed to create out directory")?; - tokio::fs::copy(&src_path, &out_path.join("bin")) - .await - .context("failed to copy checker binary")?; - Ok(FileRef { - path: "checker/bin".to_string(), - root: FileRefRoot::Problem, - }) - } - } - } - - /// Builds all modules - /// - /// Module is user-defined program. PPC only builds module and places - /// binaries into compiled problem assets. - async fn build_modules(&self) -> anyhow::Result<()> { - for module in self.glob("modules/*").await? { - let module_name = module.file_name().unwrap().to_str().expect("utf8 error"); - let output_path = self - .out_dir - .join("assets") - .join(format!("module-{}", module_name)); - self.do_build(&module, Path::new(&output_path)).await?; - } - Ok(()) - } - - /// Copies files that should just be copied as is. - /// Currently, only such file is valuer config - async fn copy_raw(&mut self) -> anyhow::Result<()> { - let valuer_cfg_dir = self.out_dir.join("assets/valuer-cfg"); - if let Some(valuer_cfg) = &self.cfg.valuer_cfg { - self.tx.send_event(Update::CopyValuerConfig).await?; - - let src = self.problem_dir.join(valuer_cfg.trim_start_matches('/')); - let dest = valuer_cfg_dir.join("cfg.yaml"); - tokio::fs::create_dir(&valuer_cfg_dir).await?; - if src.is_file() { - tokio::fs::copy(&src, &dest).await?; - } else { - // TODO - anyhow::bail!("Multi-file valuer config is TODO"); - } - } - Ok(()) - } - - /// Main method, which actually builds the problem into - /// redistributable package. - pub async fn build(&mut self) -> anyhow::Result<()> { - self.build_modules().await?; - let solutions = self.build_solutions().await?; - let testgen_launch_info = self.build_testgens().await?; - - let checker_ref = self - .build_checkers() - .await - .context("failed to build checker")?; - - let checker_cmd = self.cfg.check_options.args.clone(); - - let tests = { - let gen_answers = match &self.cfg.check { - crate::manifest::Check::Custom(cs) => cs.pass_correct, - crate::manifest::Check::Builtin(_) => true, - }; - let gen_answers = if gen_answers { - let primary_solution_name = self.cfg.primary_solution.as_ref().context( - "primary-solution must be specified in order to generate tests correct answers", - )?; - let sol_data = match solutions.get(primary_solution_name.as_str()) { - Some(d) => d, - None => { - eprint!("Following solutions are defined: "); - for sol_name in solutions.keys() { - eprint!("{} ", sol_name); - } - anyhow::bail!("Unknown solution {}", primary_solution_name) - } - }; - Some(sol_data) - } else { - None - }; - self.build_tests(&testgen_launch_info, gen_answers).await? - }; - self.copy_raw().await?; - - let valuer_exe = { - let src = self.jtl_dir.join("bin/jjs-svaluer"); - let dest = self.out_dir.join("assets/valuer"); - tokio::fs::copy(&src, &dest) - .await - .context("failed to copy valuer binary")?; - FileRef { - root: FileRefRoot::Problem, - path: "valuer".to_string(), - } - }; - - let valuer_cfg = FileRef { - root: FileRefRoot::Problem, - path: "valuer-cfg".to_string(), - }; - - let problem = pom::Problem { - title: self.cfg.title.clone(), - name: self.cfg.name.clone(), - checker_exe: checker_ref, - checker_cmd, - valuer_exe, - tests, - valuer_cfg, - }; - let manifest_path = format!("{}/manifest.json", self.out_dir.display()); - let manifest_data = - serde_json::to_string(&problem).context("couldn't serialize manifest")?; - std::fs::write(manifest_path, manifest_data).context("couldn't emit manifest") - } -} diff --git a/src/pps/server/src/import.rs b/src/pps/server/src/import.rs deleted file mode 100644 index 3c12a52e..00000000 --- a/src/pps/server/src/import.rs +++ /dev/null @@ -1,93 +0,0 @@ -mod problem_importer; -mod template; -mod valuer_cfg; - -use anyhow::{bail, Context as _}; -use pps_api::{ - import_problem::{Request, Update}, - ImportProblem, SimpleFinish, -}; -use problem_importer::Importer; -use std::{collections::HashSet, path::Path}; - -impl rpc::Handler for crate::Service { - type Error = anyhow::Error; - type Fut = futures_util::future::BoxFuture<'static, anyhow::Result<()>>; - - fn handle( - self, - rx: rpc::UnaryRx, - mut tx: rpc::StreamingTx, - ) -> Self::Fut { - Box::pin(async move { - let req = rx.recv().await?; - let result = execute_import_request(req, &mut tx).await; - tx.finish(result.into()).await?; - Ok(()) - }) - } -} - -pub(crate) async fn execute_import_request( - req: Request, - tx: &mut rpc::StreamingTx, -) -> anyhow::Result<()> { - match detect_import_kind(&req.src_path)? { - ImportKind::Problem => (), - ImportKind::Contest => anyhow::bail!("TODO"), - } - import_problem(&req.src_path, &req.out_path, tx).await?; - - Ok(()) -} - -pub(crate) async fn import_problem( - src: &Path, - dest: &Path, - tx: &mut rpc::StreamingTx, -) -> anyhow::Result<()> { - let manifest_path = src.join("problem.xml"); - let manifest = std::fs::read_to_string(manifest_path).context("failed read problem.xml")?; - let doc = roxmltree::Document::parse(&manifest).context("parse error")?; - - let mut importer = Importer { - src: &src, - dest: &dest, - problem_cfg: Default::default(), - known_generators: HashSet::new(), - doc: doc.root_element(), - limits: pom::Limits::default(), - tx, - }; - - importer.run().await?; - - let manifest_path = dest.join("problem.toml"); - let manifest_toml = - toml::Value::try_from(importer.problem_cfg.clone()).context("serialize ppc config")?; - let manifest_data = toml::ser::to_string_pretty(&manifest_toml) - .with_context(|| format!("stringify ppc config: {:#?}", &importer.problem_cfg))?; - std::fs::write(manifest_path, manifest_data).expect("write ppc manifest"); - - Ok(()) -} - -enum ImportKind { - Problem, - Contest, -} - -fn detect_import_kind(path: &Path) -> anyhow::Result { - if !path.exists() { - bail!("path {} does not exists", path.display()); - } - - if path.join("problem.xml").exists() { - return Ok(ImportKind::Problem); - } - if path.join("contest.xml").exists() { - return Ok(ImportKind::Contest); - } - - bail!("unknown src") -} diff --git a/src/pps/server/src/import/checker_tpl.cmake b/src/pps/server/src/import/checker_tpl.cmake deleted file mode 100644 index 2aa8f906..00000000 --- a/src/pps/server/src/import/checker_tpl.cmake +++ /dev/null @@ -1,4 +0,0 @@ -project(Checker) -cmake_minimum_required(VERSION 3.12) -add_executable(Out main.cpp) -target_include_directories(Out PUBLIC ../../) \ No newline at end of file diff --git a/src/pps/server/src/import/contest_import.rs b/src/pps/server/src/import/contest_import.rs deleted file mode 100644 index 12b9bdfe..00000000 --- a/src/pps/server/src/import/contest_import.rs +++ /dev/null @@ -1,64 +0,0 @@ -// TODO revive when contests are reintroduced -use std::{borrow::Cow, path::Path}; -use thiserror::Error; -#[derive(Error, Debug)] -pub(super) enum ImportContestError { - #[error("io error: {0}")] - Io(#[from] std::io::Error), - #[error("syntax error: {0}")] - XmlSyn(#[from] roxmltree::Error), - #[error("bad context.xml: {0}")] - BadManifest(Cow<'static, str>), -} - -fn go(node: roxmltree::Node, cfg: &mut entity::Contest) -> Result<(), ImportContestError> { - match node.tag_name().name() { - "problem" => { - let index = node.attribute("index").ok_or_else(|| { - ImportContestError::BadManifest("index attribute missing in ".into()) - })?; - let url = node.attribute("url").ok_or_else(|| { - ImportContestError::BadManifest("url attribute missing in ".into()) - })?; - let problem_name = url - .rsplit('/') - .next() - .expect("rsplit() should never be empty"); - let binding = entity::entities::contest::ProblemBinding { - name: problem_name.to_string(), - code: index.to_string(), - }; - cfg.problems.push(binding); - Ok(()) - } - _ => { - for child in node.children() { - go(child, cfg)?; - } - Ok(()) - } - } -} - -pub(super) fn import( - path: &Path, - contest_name: &str, -) -> Result { - let data = std::fs::read_to_string(path)?; - let doc = roxmltree::Document::parse(&data)?; - let mut cfg = entity::Contest { - title: "".to_string(), - id: contest_name.to_string(), - problems: vec![], - judges: vec![], - group: vec![], - unregistered_visible: false, - anon_visible: false, - duration: None, - end_time: None, - start_time: None, - is_virtual: false, - }; - go(doc.root(), &mut cfg)?; - Ok(cfg) -} diff --git a/src/pps/server/src/import/default_valuer_config.yaml b/src/pps/server/src/import/default_valuer_config.yaml deleted file mode 100644 index 69c5de30..00000000 --- a/src/pps/server/src/import/default_valuer_config.yaml +++ /dev/null @@ -1,4 +0,0 @@ -groups: - - name: default - score: 100 - feedback: brief diff --git a/src/pps/server/src/import/gen.cmake b/src/pps/server/src/import/gen.cmake deleted file mode 100644 index 25f642c1..00000000 --- a/src/pps/server/src/import/gen.cmake +++ /dev/null @@ -1,8 +0,0 @@ -project(Generator) -cmake_minimum_required(VERSION 3.12) - -find_package(Jtl CONFIG REQUIRED) - -add_executable(Out main.cpp) -target_include_directories(Out PUBLIC ${Jtl_INCLUDES}) -target_link_libraries(Out PUBLIC ${Jtl_LIBS}) \ No newline at end of file diff --git a/src/pps/server/src/import/problem_importer.rs b/src/pps/server/src/import/problem_importer.rs deleted file mode 100644 index 74a34e2d..00000000 --- a/src/pps/server/src/import/problem_importer.rs +++ /dev/null @@ -1,472 +0,0 @@ -use anyhow::Context as _; -use pps_api::{ - import_problem::{PropertyName, Update}, - SimpleFinish, -}; -use std::{collections::HashSet, future::Future, path::Path, pin::Pin}; - -pub(crate) struct Importer<'a> { - pub(crate) src: &'a Path, - pub(crate) dest: &'a Path, - pub(crate) problem_cfg: crate::manifest::RawProblem, - pub(crate) known_generators: HashSet, - pub(crate) doc: roxmltree::Node<'a, 'a>, - pub(crate) limits: pom::Limits, - pub(crate) tx: &'a mut rpc::StreamingTx, -} - -enum FileCategory { - Validator, - Checker, - Generator, -} - -impl FileCategory { - fn derive(name: &str) -> Option { - if name == "check" || name == "checker" { - return Some(FileCategory::Checker); - } - - if name == "validator" { - return Some(FileCategory::Validator); - } - - if name.starts_with("gen") { - return Some(FileCategory::Generator); - } - - None - } -} - -impl<'a> Importer<'a> { - // is most important section for us: it contains information - // about tests - async fn process_judging_section( - &mut self, - node_judging: roxmltree::Node<'_, '_>, - ) -> anyhow::Result<()> { - let node_testset = node_judging - .first_element_child() - .context(" element does not have a child")?; - assert_eq!(node_testset.tag_name().name(), "testset"); - - let mut test_pattern = None; - let mut ans_pattern = None; - for child in node_testset.children() { - if !child.is_element() { - continue; - } - match child.tag_name().name() { - "time-limit" => { - let tl = child - .text() - .context(" does not contain value")? - .parse::() - .context("parsing failed")?; - self.tx - .send_event(Update::Property { - property_name: PropertyName::TimeLimit, - property_value: tl.to_string(), - }) - .await?; - self.limits.time.replace(tl); - } - "memory-limit" => { - let ml = child - .text() - .context(" does not contain value")? - .parse::() - .context("parsing failed")?; - self.tx - .send_event(Update::Property { - property_name: PropertyName::MemoryLimit, - property_value: ml.to_string(), - }) - .await?; - self.limits.memory.replace(ml); - } - "input-path-pattern" => { - let pat = child.text().unwrap().to_string(); - self.tx - .send_event(Update::Property { - property_name: PropertyName::InputPathPattern, - property_value: pat.clone(), - }) - .await?; - test_pattern.replace(pat); - } - "answer-path-pattern" => { - let pat = child.text().unwrap().to_string(); - self.tx - .send_event(Update::Property { - property_name: PropertyName::OutputPathPattern, - property_value: pat.clone(), - }) - .await?; - ans_pattern.replace(pat); - } - "test-count" => {} - "tests" => { - self.process_tests(child).await?; - } - _ => { - let message = format!( - "unexpected tag in : {}", - child.tag_name().name() - ); - self.tx.send_event(Update::Warning(message)).await?; - } - } - } - Ok(()) - } - - fn import_file( - &mut self, - src_path: impl AsRef, - dest_path: impl AsRef, - ) -> anyhow::Result<()> { - let full_src_path = self.src.join(src_path); - let full_dest_path = self.dest.join(dest_path); - std::fs::copy(&full_src_path, &full_dest_path) - .with_context(|| { - format!( - "copy {} to {}", - full_src_path.display(), - full_dest_path.display() - ) - }) - .map(drop) - } - - async fn process_file(&mut self, file_path: &str, file_type: &str) -> anyhow::Result<()> { - if !file_path.starts_with("files/") { - return Ok(()); - } - let file_name = file_path.trim_start_matches("files/"); - let period_pos = match file_name.find('.') { - Some(p) => p, - None => { - return Ok(()); - } - }; - let file_name = &file_name[..period_pos]; - let category = match FileCategory::derive(file_name) { - Some(cat) => cat, - None => { - if self.known_generators.contains(file_name) { - FileCategory::Generator - } else { - let message = format!( - "couldn't derive file category (stripped name: {})", - file_name - ); - self.tx.send_event(Update::Warning(message)).await?; - - return Ok(()); - } - } - }; - match category { - FileCategory::Validator => { - let message = "ignoring validators: not yet implemented".to_string(); - self.tx.send_event(Update::Warning(message)).await?; - } - FileCategory::Checker => { - // do nothing here, processed separately - } - FileCategory::Generator => { - let gen_dir = self.dest.join("generators").join(file_name); - tokio::fs::create_dir(&gen_dir) - .await - .expect("create generator dir"); - let extension = match file_type { - _ if file_type.starts_with("cpp.g++") => "cpp", - "python.3" => "py", - _ => anyhow::bail!("unknown file type: {}", file_type), - }; - let dest_path = gen_dir.join(format!("main.{}", extension)); - let src_path = self.src.join(file_path); - tokio::fs::copy(&src_path, &dest_path) - .await - .with_context(|| { - format!( - "copy generator src from {} to {}", - src_path.display(), - dest_path.display() - ) - })?; - - if extension == "cpp" { - let cmakefile = gen_dir.join("CMakeLists.txt"); - // currently, CMakeLists are same with generator - let cmakedata = - super::template::get_checker_cmakefile(super::template::CheckerOptions {}); - tokio::fs::write(cmakefile, cmakedata) - .await - .context("write generator's CMakeLists.txt")?; - } - } - } - Ok(()) - } - - async fn process_checker( - &mut self, - node_checker: roxmltree::Node<'_, '_>, - ) -> anyhow::Result<()> { - self.tx.send_event(Update::ImportChecker).await?; - assert_eq!(node_checker.attribute("type"), Some("testlib")); - for child in node_checker.children() { - if !child.is_element() { - continue; - } - if child.tag_name().name() != "source" { - continue; - } - let file_path = child.attribute("path").unwrap(); - self.import_file(Path::new(file_path), Path::new("modules/checker/main.cpp"))?; - let cmakefile = self.dest.join("modules/checker/CMakeLists.txt"); - let cmakedata = - super::template::get_checker_cmakefile(super::template::CheckerOptions {}); - std::fs::write(cmakefile, cmakedata).context("write checker's CMakeLists.txt")?; - } - Ok(()) - } - - async fn process_executable( - &mut self, - node_executable: roxmltree::Node<'_, '_>, - ) -> anyhow::Result<()> { - for node_source in node_executable.children() { - if node_source.tag_name().name() != "source" { - continue; - } - let attr_path = node_source - .attribute("path") - .context(" does not have path attribute")?; - let attr_type = node_source - .attribute("type") - .context(" does not have type attribute")?; - self.process_file(attr_path, attr_type).await?; - } - Ok(()) - } - - async fn process_tests(&mut self, tests_node: roxmltree::Node<'_, '_>) -> anyhow::Result<()> { - self.tx.send_event(Update::ImportTests).await?; - assert_eq!(tests_node.tag_name().name(), "tests"); - let mut cnt: usize = 0; - for test_node in tests_node.children() { - if !test_node.is_element() { - continue; - } - assert_eq!(test_node.tag_name().name(), "test"); - cnt += 1; - let mut ts = crate::manifest::RawTestsSpec { - map: cnt.to_string(), - testgen: None, - files: None, - limits: self.limits, - group: format!( - "g{}", - test_node - .attribute("group") - .unwrap_or("default") - .to_string() - ), - }; - let is_generated = test_node.attribute("method").unwrap() == "generated"; - if is_generated { - let cmd_iter = test_node.attribute("cmd").unwrap().split_whitespace(); - let testgen_cmd = cmd_iter.map(ToOwned::to_owned).collect::>(); - let gen_name = testgen_cmd[0].clone(); - self.known_generators.insert(gen_name); - ts.testgen = Some(testgen_cmd); - } else { - // TODO: use formatf here instead of hardcoded format strings - ts.files = Some("%02d.txt".to_string()); - let src_path = format!("tests/{:0>2}", cnt); - let dest_path = format!("tests/{:0>2}.txt", cnt); - self.import_file(&src_path, &dest_path)?; - } - self.problem_cfg.tests.push(ts); - } - self.tx - .send_event(Update::ImportTestsDone { count: cnt }) - .await?; - Ok(()) - } - - async fn process_solutions(&mut self, node: roxmltree::Node<'_, '_>) -> anyhow::Result<()> { - self.tx.send_event(Update::ImportSolutions).await?; - for solution_node in node.children() { - if !solution_node.is_element() { - continue; - } - let tag = solution_node - .attribute("tag") - .context("solution does not have attribute")?; - if tag == "main" { - self.tx - .send_event(Update::ImportSolution(tag.to_string())) - .await?; - self.problem_cfg.primary_solution = Some("main".to_string()); - let dir = self.dest.join("solutions/main"); - let mut src_path = None; - for child in solution_node.children() { - if !child.is_element() { - continue; - } - if child.tag_name().name() == "source" { - src_path = Some(child.attribute("path").unwrap()); - } - } - let src_path = src_path.unwrap(); - tokio::fs::create_dir_all(&dir) - .await - .context("create main solution dir")?; - self.import_file(Path::new(&src_path), Path::new("solutions/main/main.cpp"))?; - { - let cmake_path = dir.join("CMakeLists.txt"); - let data = include_str!("./solution.cmake"); - std::fs::write(&cmake_path, data) - .context("write CMakeLists.txt for solution")?; - } - } else { - let message = format!( - "skipping solution with tag {}: importing non-main solutions not yet implemented", - tag - ); - self.tx.send_event(Update::Warning(message)).await?; - } - } - Ok(()) - } - - async fn process_names(&mut self, node_names: roxmltree::Node<'_, '_>) -> anyhow::Result<()> { - assert!(node_names.is_element()); - for child in node_names.children() { - if !child.is_element() { - continue; - } - let title = child - .attribute("value") - .context(" does not have value attribute")?; - - self.problem_cfg.title = title.to_string(); - self.tx - .send_event(Update::Property { - property_name: PropertyName::ProblemTitle, - property_value: title.to_string(), - }) - .await?; - break; - } - Ok(()) - } - - fn process_problem(&mut self, node_problem: roxmltree::Node) { - assert_eq!(node_problem.tag_name().name(), "problem"); - if let Some(name) = node_problem.attribute("short-name") { - self.problem_cfg.name = name.to_string(); - } - } - - fn fill_manifest(&mut self) -> anyhow::Result<()> { - let m = &mut self.problem_cfg; - m.valuer = "icpc".to_string(); - m.check_type = "builtin".to_string(); - m.builtin_check = Some(crate::manifest::BuiltinCheck { - name: "polygon-compat".to_string(), - }); - m.check_options = Some(crate::manifest::CheckOptions { - args: vec!["assets/module-checker/bin".to_string()], - }); - m.valuer_cfg = Some("valuer.yaml".to_string()); - let mut random_seed = [0; 8]; - getrandom::getrandom(&mut random_seed)?; - let rand_seed_hex = hex::encode(&random_seed); - assert_eq!(rand_seed_hex.len(), 16); - m.random_seed = Some(rand_seed_hex); - Ok(()) - } - - fn init_dirs(&mut self) -> anyhow::Result<()> { - for suf in &[ - "solutions", - "generators", - "tests", - "modules", - "modules/checker", - ] { - let path = self.dest.join(suf); - std::fs::create_dir(&path).with_context(|| format!("create {}", path.display()))?; - } - - // import testlib - self.import_file(Path::new("files/testlib.h"), Path::new("testlib.h"))?; - Ok(()) - } - - fn go<'b>( - &'b mut self, - node: roxmltree::Node<'b, 'b>, - ) -> Pin> + Send + 'b>> { - Box::pin(async move { - for child in node.children() { - self.feed(child).await?; - } - Ok(()) - }) - } - - async fn feed(&mut self, node: roxmltree::Node<'_, '_>) -> anyhow::Result<()> { - match node.tag_name().name() { - "names" => self.process_names(node).await?, - "solutions" => self.process_solutions(node).await?, - "judging" => self.process_judging_section(node).await?, - "executable" => self.process_executable(node).await?, - "checker" => self.process_checker(node).await?, - "problem" => { - self.process_problem(node); - self.go(node).await?; - } - _ => { - self.go(node).await?; - } - } - Ok(()) - } - - async fn import_valuer_config(&mut self) -> anyhow::Result<()> { - let valuer_cfg_path = self.src.join("files/valuer.cfg"); - let config = if valuer_cfg_path.exists() { - self.tx.send_event(Update::ImportValuerConfig).await?; - let (config, warnings) = super::valuer_cfg::import(&valuer_cfg_path).await?; - for warn in warnings { - self.tx - .send_event(Update::Warning(format!( - "while importing valuer config: {}", - warn - ))) - .await?; - } - serde_yaml::to_string(&config)? - } else { - self.tx.send_event(Update::DefaultValuerConfig).await?; - include_str!("./default_valuer_config.yaml").to_string() - }; - tokio::fs::write(self.dest.join("valuer.yaml"), config).await?; - Ok(()) - } - - pub(crate) async fn run(&mut self) -> anyhow::Result<()> { - self.init_dirs()?; - self.fill_manifest()?; - self.feed(self.doc).await?; - self.import_valuer_config().await?; - Ok(()) - } -} diff --git a/src/pps/server/src/import/solution.cmake b/src/pps/server/src/import/solution.cmake deleted file mode 100644 index 479d4a43..00000000 --- a/src/pps/server/src/import/solution.cmake +++ /dev/null @@ -1,5 +0,0 @@ -project(Solution) -cmake_minimum_required(VERSION 3.12) - -add_executable(Out main.cpp) -target_compile_options(Out PUBLIC -O2) \ No newline at end of file diff --git a/src/pps/server/src/import/template.rs b/src/pps/server/src/import/template.rs deleted file mode 100644 index d8a0d438..00000000 --- a/src/pps/server/src/import/template.rs +++ /dev/null @@ -1,10 +0,0 @@ -//! This module defines templates -//! for CMakeLists.txt files - -static CHECKER_TPL: &str = include_str!("checker_tpl.cmake"); - -pub struct CheckerOptions {} - -pub fn get_checker_cmakefile(_options: CheckerOptions) -> String { - CHECKER_TPL.to_string() -} diff --git a/src/pps/server/src/import/valuer_cfg.pest b/src/pps/server/src/import/valuer_cfg.pest deleted file mode 100644 index 2e6f2f29..00000000 --- a/src/pps/server/src/import/valuer_cfg.pest +++ /dev/null @@ -1,36 +0,0 @@ -config = {SOI ~ definition* ~ EOI} -definition = {global_def | group_def} - -global_def = {"global" ~ "{" ~ (global_option ~ ";")* ~ "}"} -global_option = {("stat_to_judges" | "stat_to_users") ~ num? } - -group_def = {"group" ~ num ~ "{" ~ (group_option ~ ";" )* ~ "}"} -group_option = _{group_option_tests | group_option_score | - group_option_test_score | group_option_requires | - group_option_offline | group_option_sets_marked_if_passed | - group_option_sets_marked | group_option_pass_if_count | - group_option_skip_if_not_rejudge | group_option_skip | - group_option_stat_to_users | group_option_stat_to_judges | - group_option_user_status | group_option_test_all | - group_option_zero_if } -group_option_tests = {"tests" ~ num ~ "-" ~ num} -group_option_score = {"score" ~ num} -group_option_test_score = {"test_score" ~ num} -group_option_requires = {"requires" ~ num_list} -group_option_offline = {"offline"} -group_option_sets_marked = {"sets_marked"} -group_option_skip = {"skip"} -group_option_sets_marked_if_passed = {"sets_marked_if_passed" ~ num_list} -group_option_pass_if_count = {"pass_if_count" ~ num} -group_option_skip_if_not_rejudge = {"skip_if_not_rejudge"} -group_option_stat_to_users = {"stat_to_users"} -group_option_stat_to_judges = {"stat_to_judges"} -// TODO: fix this rule. find out what `STATUS` is. -group_option_user_status = {"user_status" ~ num} -group_option_test_all = {"test_all"} -group_option_zero_if = {"zero_if"} - -num_list = _{num ~ ("," ~ num)*} -num = @{"0" | (ASCII_NONZERO_DIGIT ~ ASCII_DIGIT{0,7})} -WHITESPACE = _{" " | "\n" | "\t"} -COMMENT = _{"#" ~ (!"\n" ~ ANY)*} diff --git a/src/pps/server/src/import/valuer_cfg.rs b/src/pps/server/src/import/valuer_cfg.rs deleted file mode 100644 index 197b92d4..00000000 --- a/src/pps/server/src/import/valuer_cfg.rs +++ /dev/null @@ -1,143 +0,0 @@ -use pest::Parser as _; -use std::path::Path; -use thiserror::Error; - -#[derive(Error, Debug)] -pub(crate) enum ImportValuerCfgError { - #[error("io error: {0}")] - Io(#[from] std::io::Error), - #[error("valuer.cfg has syntax error: {0}")] - Syntax(#[from] pest::error::Error), -} - -use pest_derive::Parser; - -#[derive(Parser)] -#[grammar = "import/valuer_cfg.pest"] -pub(super) struct P; - -struct Visitor<'a> { - config: &'a mut svaluer::Config, - tests_info: std::collections::HashMap, - warnings: Vec, -} - -impl<'a> Visitor<'a> { - fn warn(&mut self, msg: String) { - self.warnings.push(msg); - } - - fn warn_not_sup(&mut self, feat: &str) { - self.warn(format!("not supported feature: {}", feat)); - } - - fn visit_global_def(&mut self, _node: pest::iterators::Pair<'a, Rule>) { - // all global options are not supported currently - self.warn_not_sup("GlobalDefinitions"); - } - - fn visit_group_def(&mut self, node: pest::iterators::Pair<'a, Rule>) { - assert_eq!(node.as_rule(), Rule::group_def); - let mut iter = node.into_inner(); - let group_num_node = iter.next().unwrap(); - assert_eq!(group_num_node.as_rule(), Rule::num); - let num: u32 = group_num_node.as_str().parse().unwrap(); - let mut group_cfg = svaluer::cfg::Group { - name: format!("g{}", num), - feedback: svaluer::cfg::FeedbackKind::Brief, - tests_tag: None, - run_to_first_failure: false, - score: 0, - deps: vec![], - }; - for group_option in iter { - self.visit_group_option(group_option, &mut group_cfg); - } - self.config.groups.push(group_cfg); - } - - fn visit_group_option( - &mut self, - node: pest::iterators::Pair<'a, Rule>, - group: &mut svaluer::cfg::Group, - ) { - match node.as_rule() { - Rule::group_option_tests => { - let mut iter = node.into_inner(); - let num1: u32 = iter.next().unwrap().as_str().parse().unwrap(); - let num2: u32 = iter.next().unwrap().as_str().parse().unwrap(); - assert!(num1 <= num2); - for tid in num1..=num2 { - if self.tests_info.insert(tid, group.name.clone()).is_some() { - self.warn(format!("test {} is mentioned more than once", tid)); - } - } - } - Rule::group_option_score => { - let sc = node.into_inner().next().unwrap().as_str().parse().unwrap(); - group.score = sc; - } - Rule::group_option_requires => { - for num_node in node.into_inner() { - assert_eq!(num_node.as_rule(), Rule::num); - let group_id: u32 = num_node.as_str().parse().unwrap(); - let dep_group_name = format!("g{}", group_id); - group - .deps - .push(svaluer::cfg::GroupRef::ByName(dep_group_name)); - } - } - Rule::group_option_sets_marked_if_passed => { - self.warn_not_sup("GroupOptionSetsMarkedIfPassed"); - } - Rule::group_option_offline => { - group.feedback = svaluer::cfg::FeedbackKind::Hidden; - } - Rule::group_option_test_score => { - self.warn_not_sup("GroupOptionTestScore"); - } - other => panic!("{:?}", other), - } - } - - fn visit(&mut self, node: pest::iterators::Pair<'a, Rule>) { - match node.as_rule() { - Rule::config => { - for child in node.into_inner() { - match child.as_rule() { - Rule::EOI => (), - Rule::definition => self.visit(child), - other => panic!("{:?}", other), - } - } - } - Rule::definition => { - let child = node.into_inner().next().unwrap(); - match child.as_rule() { - Rule::global_def => self.visit_global_def(child), - Rule::group_def => { - self.visit_group_def(child); - } - other => panic!("{:?}", other), - } - } - _ => panic!("{:?}", node), - } - } -} - -pub(crate) async fn import( - path: &Path, -) -> Result<(svaluer::Config, Vec), ImportValuerCfgError> { - let input = tokio::fs::read_to_string(path).await?; - let mut ast = P::parse(Rule::config, &input)?; - let mut config = svaluer::Config { groups: Vec::new() }; - let mut visitor = Visitor { - config: &mut config, - tests_info: std::collections::HashMap::new(), - warnings: Vec::new(), - }; - visitor.visit(ast.next().unwrap()); - let warnings = std::mem::take(&mut visitor.warnings); - Ok((config, warnings)) -} diff --git a/src/pps/server/src/lib.rs b/src/pps/server/src/lib.rs deleted file mode 100644 index 22b5ad14..00000000 --- a/src/pps/server/src/lib.rs +++ /dev/null @@ -1,110 +0,0 @@ -#![feature(is_sorted)] -#![allow(clippy::needless_lifetimes)] - -mod command; -mod compile; -mod import; -mod manifest; - -use anyhow::Context; -use std::{ - path::{Path, PathBuf}, - process::Stdio, - sync::Arc, -}; - -fn check_dir(path: &Path, allow_nonempty: bool) -> anyhow::Result<()> { - if !path.exists() { - anyhow::bail!("error: path {} not exists", path.display()); - } - if !path.is_dir() { - anyhow::bail!("error: path {} is not directory", path.display()); - } - if !allow_nonempty && path.read_dir().unwrap().next().is_some() { - anyhow::bail!("error: dir {} is not empty", path.display()); - } - Ok(()) -} - -#[cfg(target_os = "linux")] -#[tracing::instrument] -fn tune_linux() -> anyhow::Result<()> { - let mut current_limit = libc::rlimit { - rlim_cur: 0, - rlim_max: 0, - }; - unsafe { - if libc::prlimit(0, libc::RLIMIT_STACK, std::ptr::null(), &mut current_limit) != 0 { - anyhow::bail!("get current RLIMIT_STACK"); - } - } - let new_limit = libc::rlimit { - rlim_cur: current_limit.rlim_max, - rlim_max: current_limit.rlim_max, - }; - unsafe { - if libc::prlimit(0, libc::RLIMIT_STACK, &new_limit, std::ptr::null_mut()) != 0 { - anyhow::bail!("update RLIMIT_STACK"); - } - } - - Ok(()) -} - -#[tracing::instrument] -fn tune_resource_limits() -> anyhow::Result<()> { - #[cfg(target_os = "linux")] - tune_linux()?; - - Ok(()) -} - -/// Returns `rpc::Router` with all PPS api routes installed. -pub async fn create_server() -> anyhow::Result { - let mut builder = rpc::RouterBuilder::new(); - - let service = Service(Arc::new(ServiceState::get().await?)); - builder.add_route::(service.clone()); - builder.add_route::(service); - Ok(builder.build()) -} - -/// Starts PPS server on specified port on background tokio task. -#[tracing::instrument(skip(cancel))] -pub async fn serve( - port: u16, - cancel: tokio::sync::CancellationToken, -) -> anyhow::Result> { - tune_resource_limits()?; - - let router = create_server().await?; - - let bind_addr = std::net::SocketAddr::from(([127, 0, 0, 1], port)); - - let server = hyper::Server::try_bind(&bind_addr)? - .serve(router.as_make_service()) - .with_graceful_shutdown(async move { cancel.cancelled().await }); - let (tx, rx) = tokio::sync::oneshot::channel(); - tokio::task::spawn(async move { - server.await.expect("serve error"); - tx.send(()).ok(); - }); - Ok(rx) -} - -#[derive(Clone)] -pub struct Service(pub(crate) Arc); - -pub struct ServiceState { - /// JJS installation directory (used to find JTL binaries) - jjs_dir: PathBuf, -} - -impl ServiceState { - pub async fn get() -> anyhow::Result { - let jjs_dir: PathBuf = std::env::var_os("JJS_PATH") - .context("JJS_PATH not set")? - .into(); - Ok(ServiceState { jjs_dir }) - } -} diff --git a/src/pps/server/src/manifest.rs b/src/pps/server/src/manifest.rs deleted file mode 100644 index 47f1cea2..00000000 --- a/src/pps/server/src/manifest.rs +++ /dev/null @@ -1,299 +0,0 @@ -use anyhow::{bail, Context}; -use serde::{Deserialize, Serialize}; - -/// Length of random seed -/// We need this because mt19937_64 has fixed-length seed -pub const RANDOM_SEED_LENGTH: usize = 16; - -#[derive(Serialize, Deserialize, Debug, Default, Clone)] -pub struct CustomCheck { - #[serde(rename = "pass-correct")] - pub pass_correct: bool, -} - -#[derive(Serialize, Deserialize, Debug, Default, Clone)] -pub struct BuiltinCheck { - #[serde(rename = "name")] - pub name: String, -} - -#[derive(Serialize, Deserialize, Debug, Default, Clone)] -pub struct CheckOptions { - pub args: Vec, -} - -#[derive(Serialize, Deserialize, Debug, Default, Clone)] -pub struct RawTestsSpec { - pub map: String, - pub testgen: Option>, - pub files: Option, - #[serde(default)] - pub limits: pom::Limits, - pub group: String, -} - -impl RawTestsSpec { - fn parse_mapping_chunk(&self, ch: &str) -> anyhow::Result> { - if ch.contains("..") { - let parts: Vec<_> = ch.split("..").collect(); - if parts.len() != 2 { - bail!("range map chunk must look like x..y"); - } - let parts: Result, _> = parts.into_iter().map(|x| x.parse::()).collect(); - match parts { - Ok(parts) => { - let begin = parts[0]; - let end = parts[1]; - if begin > end { - bail!("range begin must be less than or equal to range end"); - } - let idxs: Vec<_> = std::ops::RangeInclusive::new(begin, end).collect(); - return Ok(idxs); - } - Err(e) => { - bail!("couldn't parse range bound: {}", e); - } - } - } - - match ch.parse() { - Ok(num) => Ok(vec![num]), - Err(err) => bail!("couldn't parse number: {}", err), - } - } - - fn parse_mapping(&self) -> anyhow::Result> { - let chunks = self.map.split(','); - let mut out = vec![]; - for ch in chunks { - match self.parse_mapping_chunk(ch) { - Ok(idxs) => { - out.extend(idxs.into_iter()); - } - Err(err) => bail!("failed to parse '{}': {:#}", ch, err), - } - } - if !out.is_sorted() { - bail!("mapping is not sorted"); - } - Ok(out) - } - - fn postprocess(&self) -> anyhow::Result> { - { - let mut cnt = 0; - if self.files.is_some() { - cnt += 1; - } - if self.testgen.is_some() { - cnt += 1; - } - if cnt == 2 { - bail!("exactly one of 'files' and 'testgen' must be specified"); - } - } - let idxs = self.parse_mapping()?; - let mut out = Vec::new(); - if let Some(file_tpl) = &self.files { - for &id in idxs.iter() { - let res = - formatf::format(file_tpl.as_bytes(), &[formatf::Value::Int(i128::from(id))]); - match res { - Ok(file) => { - let file = - String::from_utf8(file).expect("interpolation provided non-utf8 data"); - out.push((id, TestGenSpec::File { path: file })); - } - Err(err) => { - bail!("formatting error: {:?}", err); - // TODO: implement Display for formatf FormatError - } - } - } - } - if let Some(testgen_cmd) = &self.testgen { - let spec = TestGenSpec::Generate { - testgen: testgen_cmd[0].clone(), - args: testgen_cmd[1..].to_vec(), - }; - - for &id in &idxs { - out.push((id, spec.clone())); - } - } - let out = out - .into_iter() - .map(|(id, test_gen_spec)| { - ( - id, - TestSpec { - gen: test_gen_spec, - limits: self.limits, - group: self.group.clone(), - }, - ) - }) - .collect(); - - Ok(out) - } -} - -#[derive(Clone, Debug)] -pub enum TestGenSpec { - Generate { testgen: String, args: Vec }, - File { path: String }, -} - -#[derive(Debug)] -pub struct TestSpec { - pub gen: TestGenSpec, - pub limits: pom::Limits, - pub group: String, -} - -#[derive(Serialize, Deserialize, Debug, Default, Clone)] -pub struct RawProblem { - pub title: String, - - pub name: String, - - #[serde(rename = "random-seed")] - pub random_seed: Option, - - #[serde(rename = "primary-solution")] - pub primary_solution: Option, - - #[serde(rename = "check-type")] - pub check_type: String, - - pub valuer: String, - - #[serde(rename = "custom-check")] - pub custom_check: Option, - - #[serde(rename = "builtin-check")] - pub builtin_check: Option, - - pub tests: Vec, - - #[serde(rename = "check-options")] - pub check_options: Option, - - #[serde(rename = "valuer-cfg")] - pub valuer_cfg: Option, - - #[serde(default)] - pub limits: pom::Limits, -} - -impl RawProblem { - fn process_tests(&self) -> anyhow::Result> { - let mut tests = Vec::new(); - for test_spec in &self.tests { - let mut new_tests = test_spec - .postprocess() - .context("bad test description block")?; - - tests.append(&mut new_tests); - } - tests.sort_by_key(|item| item.0); - let test_ids: Vec<_> = tests.iter().map(|item| item.0).collect(); - if test_ids.is_empty() { - bail!("No tests specified"); - } - - for i in 1..test_ids.len() { - if test_ids[i - 1] == test_ids[i] { - bail!("test {} is specified more than once", test_ids[i]); - } - } - for (i, tid) in test_ids.iter().enumerate() { - if i + 1 != *tid as usize { - bail!("test {} is not specified", i + 1); - } - } - Ok(tests.into_iter().map(|item| item.1).collect()) - } - - pub fn postprocess(mut self) -> anyhow::Result<(Problem, /* warnings */ Vec)> { - let mut warnings = Vec::new(); - let tests = self.process_tests()?; - - let random_seed = match self.random_seed.take() { - Some(s) => { - if s.len() != RANDOM_SEED_LENGTH { - bail!("random-seed must have length {}", RANDOM_SEED_LENGTH); - } - if s.chars().all(|c| c.is_ascii_hexdigit()) { - s.to_lowercase() - } else { - bail!("random-seed is not hex"); - } - } - None => { - warnings.push("random-seed not present, hardcoded seed is used".to_string()); - "6a2c1750a93b8184".to_string() - } - }; - - let out = Problem { - title: self.title, - primary_solution: self.primary_solution, - check: match self.check_type.as_str() { - "custom" => { - let custom_check = match self.custom_check { - Some(cs) => cs, - None => { - bail!("check-type=custom requires [custom-check] section"); - } - }; - Check::Custom(custom_check) - } - "builtin" => { - let builtin_check = match self.builtin_check { - Some(bc) => bc, - None => { - bail!("check-type=builtin requires [builtin-check] section"); - } - }; - Check::Builtin(builtin_check) - } - other => { - bail!("unknown check type: {}", other); - } - }, - tests, - name: self.name, - random_seed, - check_options: self.check_options.unwrap_or_else(|| CheckOptions { - args: vec![], // do not pass additional argv to checker it they are not provided - }), - valuer: self.valuer, - valuer_cfg: self.valuer_cfg, - limits: self.limits, - }; - - Ok((out, warnings)) - } -} - -#[derive(Debug)] -pub enum Check { - Custom(CustomCheck), - Builtin(BuiltinCheck), -} - -#[derive(Debug)] -pub struct Problem { - pub title: String, - pub name: String, - pub primary_solution: Option, - pub check: Check, - pub tests: Vec, - pub random_seed: String, - pub check_options: CheckOptions, - pub valuer: String, - pub valuer_cfg: Option, - pub limits: pom::Limits, -} diff --git a/src/problem-loader/Cargo.toml b/src/problem-loader/Cargo.toml deleted file mode 100644 index f623eecf..00000000 --- a/src/problem-loader/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "problem-loader" -version = "0.1.0" -authors = ["Mikail Bagishov "] -edition = "2018" - - -[dependencies] -pom = {path = "../pom"} -anyhow = "1.0.33" -serde_json = "1.0.59" -async-trait = "0.1.41" -tokio = { version = "0.2.22", features = ["fs"] } -fs_extra = "1.2.0" -mongodb = "1.1.1" -url = "2.1.1" -bson = "1.1.0" -flate2 = "1.0.18" -tar = "0.4.30" -serde = "1.0.117" -tracing = "0.1.21" -tracing-futures = "0.2.4" diff --git a/src/problem-loader/src/lib.rs b/src/problem-loader/src/lib.rs deleted file mode 100644 index f4699f35..00000000 --- a/src/problem-loader/src/lib.rs +++ /dev/null @@ -1,105 +0,0 @@ -//! This library is responsible for fetching problem packages - -pub use registry::Registry; - -mod registry; - -use anyhow::Context; -use std::{collections::HashMap, path::PathBuf}; - -// TODO: cache expiration, checksum, etc -/// Stores cached problem information -struct ProblemCache { - /// Maps problem name to problem cache. - items: HashMap, -} - -impl ProblemCache { - fn new() -> ProblemCache { - ProblemCache { - items: HashMap::new(), - } - } -} -struct ProblemCacheItem { - assets: PathBuf, - manifest: pom::Problem, -} - -pub struct Loader { - registries: Vec>, - cache: tokio::sync::Mutex, - /// Each problem will be represented by ${cache_dir}/${problem_name} - cache_dir: PathBuf, -} - -impl Loader { - pub async fn from_config(conf: &LoaderConfig, cache_dir: PathBuf) -> anyhow::Result { - let mut loader = Loader { - registries: vec![], - cache_dir: cache_dir.to_path_buf(), - cache: tokio::sync::Mutex::new(ProblemCache::new()), - }; - if let Some(fs) = &conf.fs { - let fs_reg = registry::FsRegistry::new(fs.clone()); - loader.registries.push(Box::new(fs_reg)); - } - if let Some(mongodb) = &conf.mongodb { - let mongo_reg = registry::MongoRegistry::new(mongodb) - .await - .context("unable to initialize MongodbRegistry")?; - loader.registries.push(Box::new(mongo_reg)); - } - Ok(loader) - } - - /// Tries to resolve problem named `problem_name` in all configured - /// registries. On success, returns problem manifest to path to assets dir. - pub async fn find( - &self, - problem_name: &str, - ) -> anyhow::Result> { - let mut cache = self.cache.lock().await; - if let Some(cached_info) = cache.items.get(problem_name) { - return Ok(Some(( - cached_info.manifest.clone(), - cached_info.assets.clone(), - ))); - } - // cache for this problem not found, let's load it. - let assets_path = self.cache_dir.join(problem_name); - for registry in &self.registries { - if let Some(manifest) = registry - .get_problem(problem_name, &assets_path) - .await - .with_context(|| { - format!( - "failed to search for problem {} in registry {}", - problem_name, - registry.name() - ) - })? - { - cache.items.insert( - problem_name.to_string(), - ProblemCacheItem { - manifest: manifest.clone(), - assets: assets_path.clone(), - }, - ); - return Ok(Some((manifest, assets_path))); - } - } - // no registry knows about this problem - Ok(None) - } -} - -/// Used in [`from_config`](Loader::from_config) constructor -#[derive(serde::Serialize, serde::Deserialize, Debug)] -pub struct LoaderConfig { - #[serde(default)] - fs: Option, - #[serde(default)] - mongodb: Option, -} diff --git a/src/problem-loader/src/registry.rs b/src/problem-loader/src/registry.rs deleted file mode 100644 index d4c57802..00000000 --- a/src/problem-loader/src/registry.rs +++ /dev/null @@ -1,142 +0,0 @@ -//! defines Registry trait and several registries - -use anyhow::Context as _; -use async_trait::async_trait; -use std::path::{Path, PathBuf}; -use tracing::instrument; - -/// Single problem source. -/// `problem-loader` itself is just abstraction for group of -/// registries. -#[async_trait] -pub trait Registry: Send + Sync { - fn name(&self) -> &'static str { - std::any::type_name::() - } - /// Tries to fetch problem manifest and download assets to given path. - /// Returns None if problem was not found. - async fn get_problem( - &self, - problem_name: &str, - assets_path: &Path, - ) -> anyhow::Result>; -} - -/// Resolves problems from filesystem -#[derive(Debug)] -pub struct FsRegistry { - /// Directory containing all problems - problems_dir: PathBuf, -} - -impl FsRegistry { - pub fn new(problems_dir: PathBuf) -> FsRegistry { - FsRegistry { problems_dir } - } -} - -#[async_trait] -impl Registry for FsRegistry { - #[instrument] - async fn get_problem( - &self, - problem_name: &str, - dest_path: &Path, - ) -> anyhow::Result> { - let problem_dir = self.problems_dir.join(problem_name); - let manifest_path = problem_dir.join("manifest.json"); - if !manifest_path.exists() { - return Ok(None); - } - let manifest = tokio::fs::read(manifest_path).await?; - let manifest = serde_json::from_slice(&manifest).context("invalid problem manifest")?; - let assets_dir = problem_dir.join("assets"); - let dest_path = dest_path.to_path_buf(); - tokio::task::spawn_blocking(move || { - fs_extra::dir::copy(&assets_dir, &dest_path, &fs_extra::dir::CopyOptions::new())?; - Ok::<_, anyhow::Error>(()) - }) - .await - .unwrap()?; - Ok(Some(manifest)) - } -} - -/// Resolves problems via MongoDB -pub struct MongoRegistry { - collection: mongodb::Collection, -} - -impl std::fmt::Debug for MongoRegistry { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("MongoRegistry") - .field("collection", &"..") - .finish() - } -} - -impl MongoRegistry { - #[instrument] - pub async fn new(connection_string: &str) -> anyhow::Result { - let client = mongodb::Client::with_uri_str(connection_string) - .await - .context("database is not available")?; - let database = client.database("jjs"); - let collection = database.collection("problems"); - Ok(MongoRegistry { collection }) - } -} - -#[async_trait] -impl Registry for MongoRegistry { - #[instrument] - async fn get_problem( - &self, - problem_name: &str, - target_path: &Path, - ) -> anyhow::Result> { - // at first, let's find document about this problem - let filter = { - let mut filter = bson::Document::new(); - filter.insert("problem-name", problem_name); - filter - }; - let doc = self - .collection - .find_one(filter, None) - .await - .context("problem document lookup failure")?; - let doc = match doc { - Some(d) => d, - // if we got None, problem not found - None => return Ok(None), - }; - tracing::info!("problem found"); - let manifest = doc - .get_binary_generic("manifest") - .context("storage schema violation for field `manifest`")?; - let manifest = serde_json::from_slice(&manifest).context("invalid problem manifest")?; - - let compressed_assets = std::mem::take( - std::convert::identity(doc) - .get_binary_generic_mut("assets") - .context("storage schema violation for field `assets`")?, - ); - // now we must unpack `compressed_assets` to target_path - - let target_path = target_path.to_path_buf(); - let cur_span = tracing::Span::current(); - tokio::task::spawn_blocking(move || { - let _enter = cur_span.enter(); - let decoder = flate2::bufread::GzDecoder::new(compressed_assets.as_slice()); - let mut archive = tar::Archive::new(decoder); - tracing::info!(compressed_size=compressed_assets.len(), path=%target_path.display(), "Unpacking problem"); - archive.unpack(target_path.join("assets")) - }) - .await - .unwrap() - .context("failed to unpack")?; - - Ok(Some(manifest)) - } -} diff --git a/src/svaluer/Cargo.toml b/src/svaluer/Cargo.toml deleted file mode 100644 index cf5a549b..00000000 --- a/src/svaluer/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "svaluer" -version = "0.1.0" -authors = ["Mikail Bagishov "] -edition = "2018" - -[dependencies] -invoker-api = {path = "../invoker-api"} -anyhow = "1.0.33" -pom = {path = "../pom"} -crossbeam-channel = "0.5.0" -serde_json = "1.0.59" -serde = "1.0.117" -util = {path = "../util"} -serde_yaml = "0.8.14" -log = "0.4.11" -either = "1.6.1" - -[dev-dependencies] -simple_logger = "1.11.0" diff --git a/src/svaluer/Dockerfile b/src/svaluer/Dockerfile deleted file mode 100644 index 4f2a6d20..00000000 --- a/src/svaluer/Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -# TODO use scratch ? -FROM debian:stable-slim -COPY jjs-svaluer /bin/jjs-svaluer -ENTRYPOINT ["/jjs-svaluer"] \ No newline at end of file diff --git a/src/svaluer/src/cfg.rs b/src/svaluer/src/cfg.rs deleted file mode 100644 index 4f7764fe..00000000 --- a/src/svaluer/src/cfg.rs +++ /dev/null @@ -1,199 +0,0 @@ -use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize)] -#[serde(rename_all = "kebab-case")] -pub enum FeedbackKind { - /// no feedback provided - Hidden, - /// Only summary is provided - Brief, - /// Full feedback is provided - Full, -} - -#[derive(Serialize, Deserialize)] -#[serde(untagged)] -pub enum GroupRef { - ByName(String), - ById(u32), -} - -fn default_run_to_first_failure() -> bool { - true -} - -#[derive(Deserialize, Serialize)] -pub struct Group { - /// Group name. - /// It is user to refer from other groups. - pub name: String, - /// Determines what information will be provided to contestant - pub feedback: FeedbackKind, - /// Tag to find tests in this group. If none, same as `name` - pub tests_tag: Option, - /// Stop running group if some test failed - #[serde(default = "default_run_to_first_failure")] - pub run_to_first_failure: bool, - /// Group score - pub score: u32, - /// Required groups - #[serde(default)] - pub deps: Vec, -} - -impl Group { - pub fn tests_tag(&self) -> &str { - self.tests_tag.as_deref().unwrap_or(&self.name) - } -} - -/// SValuer config -/// # Offline tests -/// For offline tests, contestant is not provided with feedback. -/// To activate, set `open_tests_count` and `open_tests_score`. -#[derive(Serialize, Deserialize, Default)] -#[serde(rename_all = "kebab-case")] -pub struct Config { - pub groups: Vec, -} - -const MSG_INVALID_GROUP_REF: &str = "GroupRef refers to nonexistent group"; -const MSG_CIRCULAR_REF: &str = "group dependencies have cycle"; - -fn dfs(graph: &[Vec], used: &mut [u8], has_cycle: &mut bool, v: usize) { - used[v] = 1; - for &w in &graph[v] { - if used[w] == 0 { - dfs(graph, used, has_cycle, w); - } else if used[w] == 1 { - *has_cycle = true; - } - } - used[v] = 2; -} - -impl Config { - pub fn get_group(&self, dep: &GroupRef) -> Option { - match dep { - GroupRef::ById(id) => { - if (*id as usize) < self.groups.len() { - Some(*id as usize) - } else { - None - } - } - GroupRef::ByName(name) => self.groups.iter().position(|g| &g.name == name), - } - } - - pub fn validate(&self, error_sink: &mut Vec) { - let mut group_dep_graph: Vec> = Vec::new(); - - group_dep_graph.resize_with(self.groups.len(), Vec::new); - - for (i, g) in self.groups.iter().enumerate() { - for dep in &g.deps { - match self.get_group(dep) { - Some(j) => { - group_dep_graph[i].push(j); - } - None => { - error_sink.push(MSG_INVALID_GROUP_REF.to_string()); - } - } - } - } - let mut has_cycle = false; - let mut used = vec![0; self.groups.len()]; - for i in 0..self.groups.len() { - if used[i] == 0 { - dfs(&group_dep_graph, &mut used, &mut has_cycle, 0); - } - } - if has_cycle { - error_sink.push(MSG_CIRCULAR_REF.to_string()); - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - mod validate { - use super::*; - - fn check_errs(config: &str, errs: &[&str]) { - let cfg: Config = serde_yaml::from_str(config).unwrap(); - let mut sink = Vec::new(); - - cfg.validate(&mut sink); - if sink != errs { - panic!("expected {:?}, got {:?}", errs, sink); - } - } - #[test] - fn test_ok() { - check_errs( - " -groups: - - name: grp - feedback: full - score: 0 - ", - &[], - ); - } - - #[test] - fn test_invalid_numeric_ref() { - check_errs( - " -groups: - - name: g1 - feedback: full - score: 15 - - name: g2 - feedback: full - score: 85 - deps: - - 2 - ", - &[MSG_INVALID_GROUP_REF], - ); - } - - #[test] - fn test_invalid_named_ref() { - check_errs( - " -groups: - - name: foo - feedback: full - score: 15 - deps: - - bar - ", - &[MSG_INVALID_GROUP_REF], - ); - } - - #[test] - fn test_circular_ref() { - check_errs( - " -groups: - - name: foo - feedback: full - score: 50 - deps: - - bar - - name: bar - feedback: hidden - score: 50 - deps: - - 0 - ", - &[MSG_CIRCULAR_REF], - ) - } - } -} diff --git a/src/svaluer/src/fiber.rs b/src/svaluer/src/fiber.rs deleted file mode 100644 index a8bcfadf..00000000 --- a/src/svaluer/src/fiber.rs +++ /dev/null @@ -1,396 +0,0 @@ -mod group; - -use crate::cfg::Config; -use group::Group; -use invoker_api::{ - valuer_proto::{ - JudgeLog, JudgeLogKind, ProblemInfo, SubtaskVisibleComponents, TestVisibleComponents, - }, - Status, -}; -use log::{debug, info}; -use pom::TestId; -use std::{collections::HashSet, num::NonZeroU32}; -/// Creates single JudgeLog -/// SValuer works by aggegating several fibers (one per judgelog kind). -#[derive(Debug)] -pub(crate) struct Fiber { - kind: JudgeLogKind, - /// If test is not in this set, it will not be included into judge log. - visible_tests: HashSet, - // contains indices for `groups` - active_groups: Vec, - groups: Vec, - finished: bool, - last_live_score: u32, -} - -// TODO: consider unifying with ValuerResponse -#[derive(Debug, Eq, PartialEq)] -pub(crate) enum FiberReply { - Test { test_id: TestId }, - Finish(JudgeLog), - None, - LiveScore { score: u32 }, -} - -#[derive(Copy, Clone, Eq, PartialEq)] -enum GroupVisPreset { - Full, - Brief, - Hidden, -} - -impl GroupVisPreset { - fn subtask_flags_for(self, k: JudgeLogKind) -> SubtaskVisibleComponents { - let mut out = SubtaskVisibleComponents::empty(); - if self == GroupVisPreset::Full || k == JudgeLogKind::Full { - out |= SubtaskVisibleComponents::all(); - } - if self == GroupVisPreset::Brief || k == JudgeLogKind::Full { - out |= SubtaskVisibleComponents::SCORE; - } - out - } - - fn test_flags_for(self, k: JudgeLogKind) -> TestVisibleComponents { - let mut out = TestVisibleComponents::empty(); - if self == GroupVisPreset::Full || k == JudgeLogKind::Full { - out |= TestVisibleComponents::all(); - } - if self == GroupVisPreset::Brief { - out |= TestVisibleComponents::STATUS | TestVisibleComponents::RESOURCE_USAGE; - } - out - } - - fn is_visible_for(self, k: JudgeLogKind) -> bool { - match self { - GroupVisPreset::Brief | GroupVisPreset::Full => true, - GroupVisPreset::Hidden => k == JudgeLogKind::Full, - } - } -} - -impl Fiber { - pub(crate) fn new(cfg: &Config, problem_info: &ProblemInfo, kind: JudgeLogKind) -> Fiber { - let mut groups = Vec::new(); - let mut visible_tests = HashSet::new(); - let mut skipped_groups = HashSet::new(); - for (i, group_cfg) in cfg.groups.iter().enumerate() { - let vis_preset = match group_cfg.feedback { - crate::cfg::FeedbackKind::Brief => GroupVisPreset::Brief, - crate::cfg::FeedbackKind::Full => GroupVisPreset::Full, - crate::cfg::FeedbackKind::Hidden => GroupVisPreset::Hidden, - }; - if !vis_preset.is_visible_for(kind) { - skipped_groups.insert(i); - continue; - } - let mut grp = Group::new(); - grp.set_id(NonZeroU32::new((i + 1) as u32).unwrap()); - let mut tests = Vec::new(); - for (i, test_tag) in problem_info.tests.iter().enumerate() { - if test_tag == group_cfg.tests_tag() { - tests.push((i + 1) as u32); - } - } - visible_tests.extend(tests.iter().map(|test_id| pom::TestId::make(*test_id))); - grp.add_tests(tests); - - grp.set_tests_vis(vis_preset.test_flags_for(kind)) - .set_group_vis(vis_preset.subtask_flags_for(kind)); - grp.set_score(group_cfg.score); - for dep in &group_cfg.deps { - let group_id = cfg.get_group(dep).expect("invalid config"); - if skipped_groups.contains(&group_id) { - continue; - } - grp.add_dep(group_id as u32); - } - if !group_cfg.run_to_first_failure { - grp.set_run_all_tests(); - } - - grp.freeze(); - - groups.push(grp); - } - Fiber { - kind, - visible_tests, - active_groups: (0..groups.len()).collect(), - finished: false, - groups, - last_live_score: 0, - } - } - - pub(crate) fn add(&mut self, notification: &invoker_api::valuer_proto::TestDoneNotification) { - if !self.visible_tests.contains(¬ification.test_id) { - return; - } - if self.finished { - panic!("Fiber is finished, but got notification {:?}", notification); - } - self.add_test(notification.test_id, ¬ification.test_status); - } - - pub(crate) fn kind(&self) -> JudgeLogKind { - self.kind - } - - fn emit_judgelog(&mut self) -> FiberReply { - debug!("Emitting {:?} judge log", self.kind); - let is_full = self.groups.iter().all(|g| g.is_passed()); - let mut judge_log = JudgeLog { - kind: self.kind, - tests: vec![], - subtasks: vec![], - is_full, - score: 0, - }; - for (i, g) in self.groups.iter().enumerate() { - debug!("extending judge log with group {}", i); - g.update_judge_log(&mut judge_log); - } - - FiberReply::Finish(judge_log) - } - - fn poll_groups_for_tests(&mut self) -> Option { - for &i in &self.active_groups { - let g = &mut self.groups[i]; - if let reply @ Some(_) = g.pop_test() { - debug!("group {} returned {}", i, reply.unwrap()); - return reply; - } - debug!("group {} is not ready to run yet", i); - } - None - } - - pub(crate) fn test_is_live(&self, test: TestId) -> bool { - self.kind == JudgeLogKind::Contestant && self.visible_tests.contains(&test) - } - - fn current_score(&self) -> u32 { - self.groups.iter().map(|g| g.score()).sum() - } - - fn running_tests(&self) -> u32 { - self.groups.iter().map(|g| g.running_tests()).sum() - } - - pub(crate) fn poll(&mut self) -> FiberReply { - debug!("Fiber {:?}: poll iteration", self.kind); - if self.finished { - debug!("Returning none: already finished"); - return FiberReply::None; - } - let cur_live_score = self.current_score(); - debug!("live score: {}", cur_live_score); - if cur_live_score != self.last_live_score { - info!( - "live score updated: old={}, cur={}", - self.last_live_score, cur_live_score - ); - self.last_live_score = cur_live_score; - return FiberReply::LiveScore { - score: cur_live_score, - }; - } - let mut new_active_groups = Vec::new(); - for &i in &self.active_groups { - let g = &self.groups[i]; - let is_passed = g.is_passed(); - let is_failed = g.is_failed(); - if is_passed || is_failed { - info!("group {} is finished", i); - } else { - new_active_groups.push(i); - } - assert!(!(is_passed && is_failed)); - if g.is_passed() { - debug!("group {} is passed", i); - for group in &mut self.groups { - group.on_group_pass(i as u32); - } - } else if g.is_failed() { - let mut queue = vec![i as u32]; - while let Some(k) = queue.pop() { - debug!("group {} is failed", k); - for (j, group) in self.groups.iter_mut().enumerate() { - if !group.is_waiting() { - continue; - } - group.on_group_fail(k as u32); - if group.is_skipped() { - queue.push(j as u32); - } - } - } - } - } - self.active_groups = new_active_groups; - if let Some(test_id) = self.poll_groups_for_tests() { - debug!("got test from groups: {}", test_id); - FiberReply::Test { test_id } - } else if self.running_tests() == 0 { - debug!( - "this fiber is finished, emitting judge log of kind {:?}", - self.kind - ); - self.finished = true; - self.emit_judgelog() - } else { - let running_test = self - .groups - .iter() - .map(|g| g.list_running_tests()) - .flatten() - .next() - .expect("unreachable: running_tests() > 0, but no test found"); - debug!( - "no updates yet, waiting for running tests, incl. {:?}", - running_test - ); - - // let's wait - FiberReply::None - } - } - - fn add_test(&mut self, test: TestId, status: &Status) { - debug!("processing status {:?} for test {}", status, test); - if !self.visible_tests.contains(&test) { - debug!("skipping: test is not visible"); - return; - } - for g in &mut self.groups { - g.on_test_done(test, status.clone()); - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use invoker_api::valuer_proto::{ - JudgeLogSubtaskRow, JudgeLogTestRow, SubtaskId, SubtaskVisibleComponents, - TestVisibleComponents, - }; - - fn make_fiber(cfg: &str, problem_info: &[&str], kind: JudgeLogKind) -> Fiber { - Fiber::new( - &serde_yaml::from_str(cfg).unwrap(), - &ProblemInfo { - tests: problem_info.iter().map(ToString::to_string).collect(), - }, - kind, - ) - } - #[test] - fn simple() { - simple_logger::SimpleLogger::new().init().ok(); - let mut f = make_fiber( - " -groups: - - name: samples - feedback: full - score: 0 - - name: online - feedback: brief - score: 60 - deps: - - samples - - name: offline - feedback: hidden - score: 40 - deps: - - online - ", - &["samples", "online", "offline"], - JudgeLogKind::Full, - ); - assert_eq!( - f.poll(), - FiberReply::Test { - test_id: TestId::make(1) - } - ); - assert_eq!(f.poll(), FiberReply::None); - f.add_test(TestId::make(1), &crate::status_util::make_ok_status()); - assert_eq!( - f.poll(), - FiberReply::Test { - test_id: TestId::make(2) - } - ); - assert_eq!(f.poll(), FiberReply::None); - f.add_test(TestId::make(2), &crate::status_util::make_ok_status()); - assert_eq!(f.poll(), FiberReply::LiveScore { score: 60 }); - assert_eq!( - f.poll(), - FiberReply::Test { - test_id: TestId::make(3) - } - ); - assert_eq!(f.poll(), FiberReply::None); - f.add_test(TestId::make(3), &crate::status_util::make_err_status()); - let mut judge_log = match f.poll() { - FiberReply::Finish(log) => log, - oth => panic!("{:?}", oth), - }; - assert_eq!( - judge_log.tests.split_off(0), - vec![ - JudgeLogTestRow { - test_id: TestId::make(1), - status: crate::status_util::make_ok_status(), - components: TestVisibleComponents::all() - }, - JudgeLogTestRow { - test_id: TestId::make(2), - status: crate::status_util::make_ok_status(), - components: TestVisibleComponents::all() - }, - JudgeLogTestRow { - test_id: TestId::make(3), - status: crate::status_util::make_err_status(), - components: TestVisibleComponents::all() - }, - ], - ); - assert_eq!( - judge_log.subtasks.split_off(0), - vec![ - JudgeLogSubtaskRow { - subtask_id: SubtaskId::make(1), - score: 0, - components: SubtaskVisibleComponents::all() - }, - JudgeLogSubtaskRow { - subtask_id: SubtaskId::make(2), - score: 60, - components: SubtaskVisibleComponents::all() - }, - JudgeLogSubtaskRow { - subtask_id: SubtaskId::make(3), - score: 0, - components: SubtaskVisibleComponents::all() - } - ] - ); - assert_eq!( - judge_log, - JudgeLog { - is_full: false, - kind: JudgeLogKind::Full, - score: 60, - tests: vec![], - subtasks: vec![] - } - ); - } -} diff --git a/src/svaluer/src/fiber/group.rs b/src/svaluer/src/fiber/group.rs deleted file mode 100644 index 84c1d5c8..00000000 --- a/src/svaluer/src/fiber/group.rs +++ /dev/null @@ -1,363 +0,0 @@ -use either::{Left, Right}; -use invoker_api::{ - valuer_proto::{ - JudgeLog, JudgeLogSubtaskRow, JudgeLogTestRow, SubtaskId, SubtaskVisibleComponents, - TestVisibleComponents, - }, - Status, -}; -use log::debug; -use pom::TestId; -use std::collections::BTreeSet; - -#[derive(Debug)] -struct RunningState { - queued_tests: BTreeSet, - succeeded_tests: BTreeSet<(TestId, Status)>, - failed_tests: BTreeSet<(TestId, Status)>, - running_tests: BTreeSet, -} - -#[derive(Debug)] -struct WaitingState { - deps: BTreeSet, -} - -#[derive(Debug)] -struct SkippedState { - failed_dep: u32, -} - -#[derive(Debug)] -struct FinishedState { - score: u32, - success: bool, - tests: Vec<(TestId, Status)>, -} - -#[derive(Debug)] -enum State { - Building, - Running(RunningState), - Waiting(WaitingState), - Skipped(SkippedState), - Finished(FinishedState), -} - -#[derive(Debug)] -pub(crate) struct Group { - id: SubtaskId, - dep_groups: Vec, - test_vis_flags: TestVisibleComponents, - subtask_vis_flags: SubtaskVisibleComponents, - run_all_tests: bool, - state: State, - tests: Vec, - score: u32, -} - -impl Group { - pub(crate) fn new() -> Group { - Group { - id: SubtaskId(std::num::NonZeroU32::new(u32::max_value()).unwrap()), - dep_groups: Vec::new(), - test_vis_flags: TestVisibleComponents::empty(), - subtask_vis_flags: SubtaskVisibleComponents::empty(), - run_all_tests: false, - state: State::Building, - tests: Vec::new(), - score: 0, - } - } - - fn check_mutable(&self) { - assert!(matches!(self.state, State::Building)) - } - - pub(crate) fn set_id(&mut self, id: std::num::NonZeroU32) -> &mut Self { - self.check_mutable(); - self.id = SubtaskId(id); - self - } - - pub(crate) fn add_tests(&mut self, range: impl IntoIterator) -> &mut Self { - self.check_mutable(); - self.tests.extend(range.into_iter().map(TestId::make)); // TODO: do not panic - self - } - - pub(crate) fn add_dep(&mut self, dep_id: u32) -> &mut Self { - self.check_mutable(); - self.dep_groups.push(dep_id); - self - } - - pub(crate) fn set_score(&mut self, score: u32) -> &mut Self { - self.check_mutable(); - self.score = score; - self - } - - pub(crate) fn set_tests_vis( - &mut self, - vis: invoker_api::valuer_proto::TestVisibleComponents, - ) -> &mut Self { - self.check_mutable(); - self.test_vis_flags = vis; - self - } - - pub(crate) fn set_group_vis( - &mut self, - vis: invoker_api::valuer_proto::SubtaskVisibleComponents, - ) -> &mut Self { - self.check_mutable(); - self.subtask_vis_flags = vis; - self - } - - pub(crate) fn set_run_all_tests(&mut self) -> &mut Self { - self.check_mutable(); - self.run_all_tests = true; - self - } - - pub(crate) fn freeze(&mut self) { - self.state = State::Waiting(WaitingState { - deps: self.dep_groups.iter().copied().collect(), - }); - self.maybe_stop_waiting(); - } -} - -impl Group { - fn finished(&self) -> Option { - match &self.state { - State::Finished(state) => Some(state.success), - _ => None, - } - } - - pub(crate) fn is_passed(&self) -> bool { - self.finished() == Some(true) - } - - pub(crate) fn is_failed(&self) -> bool { - self.finished() == Some(false) - } - - pub(crate) fn is_skipped(&self) -> bool { - matches!(self.state, State::Skipped(_)) - } - - pub(crate) fn is_waiting(&self) -> bool { - matches!(self.state, State::Waiting(_)) - } - - pub(crate) fn running_tests(&self) -> u32 { - match &self.state { - State::Running(state) => state.running_tests.len() as u32, - _ => 0, - } - } - - pub(crate) fn list_running_tests(&self) -> impl Iterator + '_ { - match &self.state { - State::Running(state) => Left(state.running_tests.iter().copied()), - _ => Right(std::iter::empty()), - } - } - - fn maybe_stop_waiting(&mut self) { - let state = match &mut self.state { - State::Waiting(state) => state, - _ => unreachable!(), - }; - if state.deps.is_empty() { - self.state = State::Running(RunningState { - queued_tests: self.tests.iter().copied().collect(), - failed_tests: BTreeSet::new(), - succeeded_tests: BTreeSet::new(), - running_tests: BTreeSet::new(), - }); - } - } - - pub(crate) fn on_group_pass(&mut self, other_group_id: u32) { - let state = match &mut self.state { - State::Waiting(state) => state, - _ => return, - }; - if state.deps.remove(&other_group_id) { - debug!("group {:?}: dep {} passed", self.id, other_group_id); - self.maybe_stop_waiting(); - } - } - - pub(crate) fn on_group_fail(&mut self, other_group_id: u32) { - let state = match &mut self.state { - State::Waiting(state) => state, - _ => return, - }; - if !state.deps.contains(&other_group_id) { - // that group was not required, so we ignore this failure - return; - } - debug!("group {:?}: dep {} failed", self.id, other_group_id); - self.state = State::Skipped(SkippedState { - failed_dep: other_group_id, - }); - } - - /// Returns next test from this group that can be executed - pub(crate) fn pop_test(&mut self) -> Option { - debug!("Group {:?}: searching for test", self.id); - // we can't run if some deps are running or failed - let state = match &mut self.state { - State::Building => unreachable!(), - State::Finished(_) | State::Skipped(_) => { - debug!("Returning None: group has been done"); - return None; - } - State::Waiting(_) => { - debug!("Returning None: some deps still not finished"); - return None; - } - State::Running(state) => state, - }; - if !state.running_tests.is_empty() && !self.run_all_tests { - debug!("Returning None: run_all_tests=false, and a test is already running"); - return None; - } - if let Some(t) = state.queued_tests.iter().next().copied() { - debug!("found test: {}", t); - state.queued_tests.remove(&t); - state.running_tests.insert(t); - Some(t) - } else { - debug!("Queue is empty"); - None - } - } - - fn running_state(&mut self) -> &mut RunningState { - match &mut self.state { - State::Running(state) => state, - other => panic!("expected RunningState, got {:?}", other), - } - } - - fn mark_test_fail(&mut self, test_id: TestId, status: Status) { - let id = self.id; - let must_run_all_tests = self.run_all_tests; - let state = self.running_state(); - if state.failed_tests.is_empty() { - debug!("group {:?} is now failed", id); - } - state.failed_tests.insert((test_id, status)); - if !must_run_all_tests { - // no other tests should be run - state.queued_tests.clear(); - } - } - - fn mark_test_ok(&mut self, test_id: TestId, status: Status) { - self.running_state() - .succeeded_tests - .insert((test_id, status)); - } - - fn maybe_finish(&mut self) { - let state = self.running_state(); - if state.queued_tests.is_empty() && state.running_tests.is_empty() { - let success = state.failed_tests.is_empty(); - let failed_tests = std::mem::take(&mut state.failed_tests); - let succeeded_tests = std::mem::take(&mut state.succeeded_tests); - let score = if success { self.score } else { 0 }; - self.state = State::Finished(FinishedState { - score, - success, - tests: failed_tests.into_iter().chain(succeeded_tests).collect(), - }) - } - } - - pub(crate) fn on_test_done(&mut self, test_id: TestId, status: Status) { - let state = match &mut self.state { - State::Running(state) => state, - _ => return, - }; - if !state.running_tests.remove(&test_id) { - return; - } - debug!( - "got test result: test={}, status={:?}", - test_id.get(), - status - ); - if status.kind.is_success() { - self.mark_test_ok(test_id, status); - } else { - self.mark_test_fail(test_id, status); - } - self.maybe_finish(); - } - - pub(crate) fn update_judge_log(&self, log: &mut JudgeLog) { - let state = match &self.state { - State::Finished(state) => state, - State::Skipped(_) => { - log.subtasks.push(JudgeLogSubtaskRow { - components: self.subtask_vis_flags, - score: 0, - subtask_id: self.id, - }); - return; - } - other => panic!("update_judge_log: unexpected state {:?}", other), - }; - let self_score = self.score(); - log.score += self_score; - let subtask_entry = JudgeLogSubtaskRow { - components: self.subtask_vis_flags, - score: self_score, - subtask_id: self.id, - }; - log.subtasks.push(subtask_entry); - for (test, status) in &state.tests { - let row = JudgeLogTestRow { - components: self.test_vis_flags, - test_id: *test, - status: status.clone(), - }; - log.tests.push(row); - } - } - - pub(crate) fn score(&self) -> u32 { - if self.is_passed() { self.score } else { 0 } - } -} - -#[cfg(test)] -mod tests { - use super::*; - #[test] - fn simple() { - simple_logger::SimpleLogger::new().init().ok(); - let st = || Status { - kind: invoker_api::StatusKind::Accepted, - code: "MOCK_OK".to_string(), - }; - let mut g = Group::new(); - g.add_tests(1..=3); - g.freeze(); - - assert_eq!(g.pop_test(), Some(TestId::make(1))); - g.on_test_done(TestId::make(1), st()); - assert_eq!(g.pop_test(), Some(TestId::make(2))); - g.on_test_done(TestId::make(2), st()); - assert_eq!(g.pop_test(), Some(TestId::make(3))); - assert_eq!(g.pop_test(), None); - } -} diff --git a/src/svaluer/src/lib.rs b/src/svaluer/src/lib.rs deleted file mode 100644 index 608e61c8..00000000 --- a/src/svaluer/src/lib.rs +++ /dev/null @@ -1,185 +0,0 @@ -//! Core valuing logic -//! It is extracted to library to simplify testing - -#[cfg(test)] -mod tests; - -pub mod cfg; -mod fiber; - -pub use cfg::Config; - -use anyhow::{Context, Result}; -use fiber::{Fiber, FiberReply}; -use invoker_api::valuer_proto::{JudgeLogKind, ProblemInfo, TestDoneNotification, ValuerResponse}; -use log::debug; -use pom::TestId; -use std::collections::HashSet; -/// SValuer is pure. Only `ValuerDriver` actually performs some IO, interacting with environment, such as JJS invoker. -pub trait ValuerDriver: std::fmt::Debug { - /// Retrieves `ProblemInfo`. Will be called once. - fn problem_info(&mut self) -> Result; - /// Sends valuer response - fn send_command(&mut self, cmd: &ValuerResponse) -> Result<()>; - /// Polls notification about test finish - fn poll_notification(&mut self) -> Result>; -} - -/// SValuer itself -#[derive(Debug)] -pub struct SimpleValuer<'a> { - driver: &'a mut dyn ValuerDriver, - /// Amount of tests that are currently running. - running_tests: u32, - /// How many fibers did not emit judge log yet - running_fibers: usize, - /// Amount of tests that were requested to run. - /// It is used for caching purposes. - used_tests: HashSet, - fibers: Vec, -} - -impl<'a> SimpleValuer<'a> { - pub fn new( - driver: &'a mut dyn ValuerDriver, - cfg: &'a cfg::Config, - ) -> anyhow::Result> { - let problem_info = driver - .problem_info() - .context("failed to query problem info")?; - let mut fibers = Vec::new(); - - fibers.push(Fiber::new(cfg, &problem_info, JudgeLogKind::Full)); - fibers.push(Fiber::new(cfg, &problem_info, JudgeLogKind::Contestant)); - - let fibers_cnt = fibers.len(); - Ok(SimpleValuer { - driver, - running_tests: 0, - used_tests: HashSet::new(), - fibers, - running_fibers: fibers_cnt, - }) - } - - /// Creates ValuerResponse for executing test `test_id`. - /// Returns early if this test was already requested. - fn send_run_on_test_query(&mut self, test_id: TestId, live: bool) -> anyhow::Result<()> { - if !self.used_tests.insert(test_id) { - return Ok(()); - } - let cmd = ValuerResponse::Test { test_id, live }; - self.running_tests += 1; - - self.driver - .send_command(&cmd) - .context("failed to send TEST command")?; - Ok(()) - } - - /// Executes one iteration. - /// Returns false when valuing finishes. - fn step(&mut self) -> anyhow::Result { - debug!("Running next step"); - - debug!("Polling fibers"); - // do we have something new from fibers? - for fiber in &mut self.fibers { - let reply = fiber.poll(); - debug!("Polling fiber {:?}: {:?}", fiber.kind(), &reply); - match reply { - FiberReply::LiveScore { score } => { - if fiber.kind() == JudgeLogKind::Contestant { - debug!("Step done: sending live score"); - let live_score = ValuerResponse::LiveScore { score }; - self.driver - .send_command(&live_score) - .context("failed to send new live score")?; - return Ok(true); - } else { - debug!("Ignoring live score: kind mismatch"); - } - } - FiberReply::Test { test_id } => { - let is_live = self.fibers.iter().any(|fib| fib.test_is_live(test_id)); - debug!( - "Step done: test execution requested (test id {}, live: {})", - test_id, is_live - ); - self.send_run_on_test_query(test_id, is_live)?; - return Ok(true); - } - FiberReply::Finish(judge_log) => { - debug!("Step done: new judge log {:?} emitted", judge_log.kind); - let resp = ValuerResponse::JudgeLog(judge_log); - self.running_fibers -= 1; - self.driver - .send_command(&resp) - .context("failed to submit judge log")?; - return Ok(true); - } - FiberReply::None => { - debug!("No updates from this fiber"); - continue; - } - } - } - // do we have pending notifications? - if let Some(notification) = self - .driver - .poll_notification() - .context("failed to poll for notification")? - { - debug!("Step done: got notification"); - self.process_notification(notification); - return Ok(true); - } - - // do we have running tests? - if self.running_tests != 0 { - debug!("Step done: waiting for running tests completion"); - return Ok(true); - } - if self.running_fibers != 0 { - debug!("Step done: waiting for running fibers completion"); - return Ok(true); - } - - Ok(false) - } - - /// Runs to valuing completion - pub fn exec(mut self) -> anyhow::Result<()> { - loop { - let should_run = self.step()?; - if !should_run { - break; - } - } - self.driver.send_command(&ValuerResponse::Finish) - } - - fn process_notification(&mut self, notification: TestDoneNotification) { - assert_ne!(self.running_tests, 0); - self.running_tests -= 1; - for fiber in self.fibers.iter_mut() { - fiber.add(¬ification); - } - } -} - -pub mod status_util { - pub fn make_ok_status() -> invoker_api::Status { - invoker_api::Status { - code: "OK".to_string(), - kind: invoker_api::StatusKind::Accepted, - } - } - - pub fn make_err_status() -> invoker_api::Status { - invoker_api::Status { - code: "NOT_OK".to_string(), - kind: invoker_api::StatusKind::Rejected, - } - } -} diff --git a/src/svaluer/src/main.rs b/src/svaluer/src/main.rs deleted file mode 100644 index 2b4d6189..00000000 --- a/src/svaluer/src/main.rs +++ /dev/null @@ -1,275 +0,0 @@ -//! Simple valuer -use anyhow::Context; -use log::debug; -use pom::TestId; -use std::collections::HashSet; - -/// CLI-based driver, useful for manual testing valuer config -#[derive(Debug)] -struct TermDriver { - current_tests: HashSet, - full_judge_log: Option, -} - -mod term_driver { - use super::TermDriver; - use anyhow::{Context, Result}; - use invoker_api::valuer_proto; - use pom::TestId; - use std::{ - io::{stdin, stdout, Write}, - str::FromStr, - }; - fn read_value(what: impl AsRef) -> Result - where - ::Err: std::error::Error, - { - let mut user_input = String::new(); - loop { - print!("{}> ", what.as_ref()); - stdout().flush()?; - user_input.clear(); - stdin() - .read_line(&mut user_input) - .context("failed to read line")?; - let user_input = user_input.trim(); - match user_input.parse() { - // These are different Ok's: one is anyhow::Result::Ok, other is Result<.., ::Err>> - Ok(x) => break Ok(x), - Err(err) => { - eprintln!("failed to parse your input: {}. Please, enter again.", err); - continue; - } - } - } - } - - impl svaluer::ValuerDriver for TermDriver { - fn problem_info(&mut self) -> Result { - let test_count = read_value("test count")?; - let mut tests = Vec::new(); - for i in 1..=test_count { - let group = read_value(format!("group test #{} belongs to", i))?; - tests.push(group); - } - let info = valuer_proto::ProblemInfo { tests }; - Ok(info) - } - - fn send_command(&mut self, resp: &valuer_proto::ValuerResponse) -> Result<()> { - match resp { - valuer_proto::ValuerResponse::Finish => { - let judge_log = self.full_judge_log.take().expect("full judge log missing"); - - println!("Judging finished"); - println!("Score: {}", judge_log.score); - if judge_log.is_full { - println!("Full solution"); - } else { - println!("Partial solution"); - } - } - valuer_proto::ValuerResponse::LiveScore { score } => { - println!("Current score: {}", *score); - } - valuer_proto::ValuerResponse::Test { test_id, live } => { - println!("Run should be executed on test {}", test_id.get()); - if *live { - println!("Current test: {}", test_id.get()); - } - let not_dup = self.current_tests.insert(*test_id); - assert!(not_dup); - } - valuer_proto::ValuerResponse::JudgeLog { .. } => { - // TODO print judge log - } - } - Ok(()) - } - - fn poll_notification(&mut self) -> Result> { - fn create_status(ok: bool) -> invoker_api::Status { - if ok { - svaluer::status_util::make_ok_status() - } else { - svaluer::status_util::make_err_status() - } - } - - fn read_status(tid: TestId) -> Result { - let outcome = read_value(format!("test {} status", tid.get()))?; - let test_status = create_status(outcome); - Ok(valuer_proto::TestDoneNotification { - test_id: tid, - test_status, - }) - } - match self.current_tests.len() { - 0 => Ok(None), - 1 => { - let tid = self.current_tests.drain().next().unwrap(); - Ok(Some(read_status(tid)?)) - } - _ => { - let test_id = loop { - let tid: std::num::NonZeroU32 = read_value("next finished test")?; - if !self.current_tests.remove(&TestId(tid)) { - eprintln!( - "Test {} was already finished or is not requested to run", - tid.get() - ); - eprintln!("Current tests: {:?}", &self.current_tests); - continue; - } - break TestId(tid); - }; - Ok(Some(read_status(test_id)?)) - } - } - } - } -} - -use json_driver::JsonDriver; - -mod json_driver { - use anyhow::{bail, Context, Result}; - use serde::Deserialize; - use std::{ - io::Write, - time::{Duration, Instant}, - }; - use svaluer::ValuerDriver; - /// Json-RPC driver, used in integration with JJS invoker - #[derive(Debug)] - pub struct JsonDriver { - chan: crossbeam_channel::Receiver, - } - #[derive(Deserialize)] - #[serde(untagged)] - enum Message { - ProblemInfo(invoker_api::valuer_proto::ProblemInfo), - TestDoneNotify(invoker_api::valuer_proto::TestDoneNotification), - } - fn json_driver_thread_func(chan: crossbeam_channel::Sender) { - let mut buf = String::new(); - loop { - buf.clear(); - if let Err(err) = std::io::stdin().read_line(&mut buf) { - eprintln!("svaluer: fatal: io error: {}", err); - break; - } - let notify = match serde_json::from_str(&buf) { - Ok(val) => val, - Err(err) => { - eprintln!( - "svaluer: error: failed to deserialize invoker TestDoneNotification: {}", - err - ); - continue; - } - }; - if chan.send(notify).is_err() { - // we get error, if receiver is closed. It means we should stop. - break; - } - } - } - const WAIT_TIMEOUT: Duration = Duration::from_millis(100); - impl JsonDriver { - pub fn new() -> Self { - let (send, recv) = crossbeam_channel::unbounded(); - std::thread::spawn(move || { - json_driver_thread_func(send); - }); - Self { chan: recv } - } - - fn poll(&mut self) -> Option { - match self.chan.recv_timeout(WAIT_TIMEOUT) { - Ok(msg) => Some(msg), - Err(_err) => None, - } - } - } - - impl ValuerDriver for JsonDriver { - fn problem_info(&mut self) -> Result { - let begin_time = Instant::now(); - const TIMEOUT: Duration = Duration::from_secs(1); - let message = loop { - if let Some(msg) = self.poll() { - break msg; - } - if Instant::now().duration_since(begin_time) > TIMEOUT { - bail!("timeout"); - } - std::thread::sleep(Duration::from_millis(100)); - }; - let problem_info = match message { - Message::ProblemInfo(pi) => pi, - Message::TestDoneNotify(tdn) => bail!("got TestDoneNotification {:?} instead", tdn), - }; - Ok(problem_info) - } - - fn send_command(&mut self, cmd: &invoker_api::valuer_proto::ValuerResponse) -> Result<()> { - let cmd = serde_json::to_string(cmd).context("failed to serialize")?; - println!("{}", cmd); - std::io::stdout().flush().context("failed to flush")?; - Ok(()) - } - - fn poll_notification( - &mut self, - ) -> Result> { - match self.poll() { - None => Ok(None), - Some(msg) => match msg { - Message::TestDoneNotify(tdn) => Ok(Some(tdn)), - Message::ProblemInfo(pi) => bail!("got ProblemInfo {:?} instead", pi), - }, - } - } - } -} - -fn parse_config() -> anyhow::Result { - let path = std::path::Path::new("cfg.yaml"); - let data = std::fs::read_to_string(path).context("failed to read cfg.yaml")?; - Ok(serde_yaml::from_str(&data).context("failed to parse config")?) -} - -fn main_cli_mode() -> anyhow::Result<()> { - let mut driver = TermDriver { - current_tests: HashSet::new(), - full_judge_log: None, - }; - let cfg = parse_config()?; - let valuer = svaluer::SimpleValuer::new(&mut driver, &cfg)?; - valuer.exec() -} - -fn main_json_mode() -> anyhow::Result<()> { - let mut driver = JsonDriver::new(); - let cfg = parse_config()?; - let valuer = svaluer::SimpleValuer::new(&mut driver, &cfg)?; - valuer.exec() -} - -fn main() -> anyhow::Result<()> { - if std::env::var("RUST_LOG").is_err() { - std::env::set_var("RUST_LOG", "info,svaluer=debug"); - } - util::log::setup(); - let json_mode = std::env::var("JJS_VALUER").is_ok(); - if json_mode { - debug!("Mode: JSON"); - main_json_mode()? - } else { - debug!("Mode: CLI"); - main_cli_mode()? - } - - Ok(()) -} diff --git a/src/svaluer/src/tests.rs b/src/svaluer/src/tests.rs deleted file mode 100644 index bd7cc9bd..00000000 --- a/src/svaluer/src/tests.rs +++ /dev/null @@ -1,287 +0,0 @@ -use super::*; -use invoker_api::{ - valuer_proto::{ - JudgeLog, JudgeLogSubtaskRow, JudgeLogTestRow, SubtaskId, SubtaskVisibleComponents, - TestVisibleComponents, - }, - Status, -}; -use status_util::{make_err_status, make_ok_status}; -use std::collections::VecDeque; - -#[derive(Debug)] -struct TestMock { - test_id: TestId, - live: bool, - status: Status, -} - -#[derive(Debug)] -struct MockDriver { - tests: VecDeque, - pending_notifications: VecDeque, - live_scores: VecDeque, - problem_info: ProblemInfo, - judge_logs: Vec, -} -impl MockDriver { - fn new(problem_info: ProblemInfo) -> Self { - Self { - tests: VecDeque::new(), - problem_info, - live_scores: VecDeque::new(), - pending_notifications: VecDeque::new(), - judge_logs: Vec::new(), - } - } - - fn add_test(&mut self, test_id: u32, live: bool, ok: bool) -> &mut Self { - let mock = TestMock { - test_id: TestId::make(test_id), - live, - status: if ok { - make_ok_status() - } else { - make_err_status() - }, - }; - self.tests.push_back(mock); - self - } - - fn add_judge_log(&mut self, judge_log: JudgeLog) -> &mut Self { - self.judge_logs.push(judge_log); - self - } - - fn add_live_score(&mut self, score: u32) -> &mut Self { - self.live_scores.push_back(score); - self - } - - fn check_finish(&mut self) { - if !self.pending_notifications.is_empty() { - panic!("not all notifications are delivered"); - } - if !self.live_scores.is_empty() { - panic!("not all live scores were emitted"); - } - if !self.tests.is_empty() { - panic!("not all tests were executed"); - } - if let Some(judge_log) = self.judge_logs.first() { - panic!("judge log {:?} was not emitted", judge_log.kind); - } - } - - fn check_live_score(&mut self, score: u32) { - match self.live_scores.pop_front() { - Some(expected) => { - if expected != score { - panic!( - "expected live score {}, but valuer gave {}", - expected, score - ); - } - } - None => panic!("no more live scores expected, but got {}", score), - } - } - - fn check_test(&mut self, test_id: TestId, live: bool) { - match self.tests.pop_front() { - Some(mock) => { - if mock.test_id != test_id { - panic!( - "expected {} to be next test, but got {} instead", - mock.test_id.get(), - test_id.get() - ); - } - if mock.live != live { - panic!("live flag differs: expected {}, actual {}", mock.live, live); - } - self.pending_notifications.push_back(TestDoneNotification { - test_id: mock.test_id, - test_status: mock.status, - }) - } - None => panic!( - "No more test runs expected, but got request for {}", - test_id.get() - ), - } - } - - fn check_judge_log(&mut self, judge_log: &JudgeLog) { - let cnt = self - .judge_logs - .iter() - .filter(|log| log.kind == judge_log.kind) - .count(); - if cnt == 0 { - panic!("Judge log of kind {:?} is not expected", judge_log.kind) - } - if cnt > 1 { - panic!( - "Invalid test data: duplicated judge log: {:?}", - judge_log.kind - ) - } - let expected = { - let pos = self - .judge_logs - .iter() - .position(|log| log.kind == judge_log.kind) - .expect("it was checked earlier that `cnt` > 1"); - self.judge_logs.remove(pos) - }; - assert_eq!(expected.tests, judge_log.tests); - assert_eq!(expected.subtasks, judge_log.subtasks); - assert_eq!(expected.score, judge_log.score); - assert_eq!(expected.kind, judge_log.kind); - assert_eq!(expected.is_full, judge_log.is_full); - // In case new field is added, of course an assert should be added. - // But as additional check, compare full logs. - assert_eq!(&expected, judge_log); - } - - fn exec(&mut self, cfg: impl AsRef) { - simple_logger::SimpleLogger::new().init().ok(); - let cfg = cfg.as_ref(); - let cfg = serde_yaml::from_str(cfg).expect("failed to parse config"); - let valuer = SimpleValuer::new(self, &cfg).unwrap(); - valuer.exec().unwrap(); - } -} - -impl ValuerDriver for MockDriver { - fn problem_info(&mut self) -> Result { - Ok(self.problem_info.clone()) - } - - fn send_command(&mut self, cmd: &ValuerResponse) -> Result<()> { - match cmd { - ValuerResponse::Finish => self.check_finish(), - ValuerResponse::JudgeLog(judge_log) => self.check_judge_log(judge_log), - ValuerResponse::LiveScore { score } => self.check_live_score(*score), - ValuerResponse::Test { test_id, live } => self.check_test(*test_id, *live), - } - Ok(()) - } - - fn poll_notification(&mut self) -> Result> { - Ok(self.pending_notifications.pop_front()) - } -} - -mod simple { - use super::*; - #[test] - fn simple_ok() { - let full_log = JudgeLog { - is_full: true, - kind: JudgeLogKind::Full, - tests: vec![ - JudgeLogTestRow { - test_id: TestId::make(1), - status: make_ok_status(), - components: TestVisibleComponents::all(), - }, - JudgeLogTestRow { - test_id: TestId::make(2), - status: make_ok_status(), - components: TestVisibleComponents::all(), - }, - ], - subtasks: vec![ - JudgeLogSubtaskRow { - subtask_id: SubtaskId::make(1), - score: 64, - components: SubtaskVisibleComponents::SCORE, - }, - JudgeLogSubtaskRow { - subtask_id: SubtaskId::make(2), - score: 36, - components: SubtaskVisibleComponents::SCORE, - }, - ], - score: 100, - }; - let mut contestant_log = full_log.clone(); - contestant_log.kind = JudgeLogKind::Contestant; - contestant_log.subtasks.pop(); - contestant_log.tests.pop(); - contestant_log.tests[0].components = - TestVisibleComponents::STATUS | TestVisibleComponents::RESOURCE_USAGE; - contestant_log.score = 64; - MockDriver::new(ProblemInfo { - tests: vec!["online".to_string(), "offline".to_string()], - }) - .add_test(1, true, true) - .add_test(2, false, true) - .add_judge_log(full_log) - .add_judge_log(contestant_log) - .add_live_score(64) - .exec( - " -groups: - - name: online - feedback: brief - score: 64 - - name: offline - feedback: hidden - score: 36 - deps: - - online - ", - ); - } - - #[test] - fn status_err() { - let full_log = JudgeLog { - is_full: false, - kind: JudgeLogKind::Full, - tests: vec![JudgeLogTestRow { - test_id: TestId::make(1), - status: make_err_status(), - components: TestVisibleComponents::all(), - }], - subtasks: vec![ - JudgeLogSubtaskRow { - subtask_id: SubtaskId::make(1), - score: 0, - components: SubtaskVisibleComponents::all(), - }, - JudgeLogSubtaskRow { - subtask_id: SubtaskId::make(2), - score: 0, - components: SubtaskVisibleComponents::all(), - }, - ], - score: 0, - }; - let mut contestant_log = full_log.clone(); - contestant_log.kind = JudgeLogKind::Contestant; - MockDriver::new(ProblemInfo { - tests: vec!["samples".to_string(), "online".to_string()], - }) - .add_test(1, true, false) - .add_judge_log(full_log) - .add_judge_log(contestant_log) - .exec( - " -groups: - - name: samples - score: 0 - feedback: full - - name: online - score: 100 - feedback: brief - deps: - - samples - ", - ); - } -} From e9319dde8245f7f8ffa570f3845fd3166063a7a6 Mon Sep 17 00:00:00 2001 From: Mikail Bagishov Date: Sat, 1 May 2021 13:26:23 +0300 Subject: [PATCH 2/7] cpp ci --- .github/workflows/pr.yaml | 19 -------------- actions/pr.yaml | 13 --------- src/devtool/src/check.rs | 55 --------------------------------------- 3 files changed, 87 deletions(-) diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 97b4d24a..fb71abf5 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -120,25 +120,6 @@ jobs: with: command: clippy args: "--workspace -- -Dwarnings" - cpp: - name: cpp - runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v1 - - name: Install system dependencies - run: sudo apt-get install -y libssl-dev cmake - - name: Install Rust toolchain - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: "clippy,rustfmt" - override: true - - name: Install clang static analyzer - run: sudo apt install clang-tools - - name: compile testlib - run: cargo jjs-check --no-default --testlib - - name: Run static analyzer - run: cargo jjs-check --no-default --clang-analyzer unit-tests: name: unit-tests runs-on: ubuntu-18.04 diff --git a/actions/pr.yaml b/actions/pr.yaml index 3ba349c4..cf985ff2 100644 --- a/actions/pr.yaml +++ b/actions/pr.yaml @@ -113,19 +113,6 @@ jobs: with: command: clippy args: --workspace -- -Dwarnings - cpp: - name: cpp - runs-on: "ubuntu-18.04" - steps: - - uses: actions/checkout@v1 - - $include: sysdeps - - $include: rustc - - name: Install clang static analyzer - run: sudo apt install clang-tools - - name: compile testlib - run: cargo jjs-check --no-default --testlib - - name: Run static analyzer - run: cargo jjs-check --no-default --clang-analyzer unit-tests: name: unit-tests runs-on: "ubuntu-18.04" diff --git a/src/devtool/src/check.rs b/src/devtool/src/check.rs index 040b5b94..dd7c016d 100644 --- a/src/devtool/src/check.rs +++ b/src/devtool/src/check.rs @@ -39,49 +39,6 @@ fn shellcheck(runner: &Runner) { } } -fn static_analysis() -> anyhow::Result<()> { - std::fs::remove_dir_all("src/jtl/cmake-build-analysis").ok(); - std::fs::create_dir_all("src/jtl/cmake-build-analysis")?; - Command::new("scan-build") - .arg(cmake_bin()) - .current_dir("./src/jtl/cmake-build-analysis") - .arg("..") - .try_exec()?; - - let analysis_output_dir = tempfile::TempDir::new().context("failed to get temp dir")?; - - Command::new("scan-build") - .current_dir("./src/jtl/cmake-build-analysis") - .arg("-o") - .arg(&analysis_output_dir.path()) - .arg("make") - .args(&["-j", "4"]) - .try_exec()?; - - let dir_items = std::fs::read_dir(analysis_output_dir.path())?.count(); - if dir_items != 0 { - // make sure dir is saved - analysis_output_dir.into_path(); - anyhow::bail!("Analyzer found bugs"); - } - - Ok(()) -} - -fn check_testlib(runner: &Runner) { - info!("checking testlib"); - std::fs::create_dir("src/jtl/cmake-build-debug").ok(); - Command::new(cmake_bin()) - .current_dir("./src/jtl/cmake-build-debug") - .arg("-DCMAKE_EXPORT_COMPILE_COMMANDS=On") - .arg("..") - .run_on(runner); - Command::new(cmake_bin()) - .current_dir("./src/jtl/cmake-build-debug") - .args(&["--build", "."]) - .args(&["--target", "all"]) - .run_on(runner); -} #[derive(Clap)] pub struct CheckOpts { @@ -91,12 +48,6 @@ pub struct CheckOpts { /// Run shellcheck #[clap(long)] shellcheck: bool, - /// Build testlib - #[clap(long)] - testlib: bool, - /// Analyze testlib - #[clap(long)] - clang_analyzer: bool, /// Do not run default checks #[clap(long)] no_default: bool, @@ -112,11 +63,5 @@ pub fn check(opts: &CheckOpts, runner: &Runner) -> anyhow::Result<()> { if opts.shellcheck || !opts.no_default { shellcheck(runner); } - if opts.testlib || !opts.no_default { - check_testlib(runner); - } - if opts.clang_analyzer { - static_analysis().context("static analysis failed")?; - } Ok(()) } From b5122170873498ed3cb8d53f4fe81eaf6f377d78 Mon Sep 17 00:00:00 2001 From: Mikail Bagishov Date: Sat, 1 May 2021 13:27:51 +0300 Subject: [PATCH 3/7] fmt --- src/devtool/src/check.rs | 1 - src/devtool/src/ci.rs | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/devtool/src/check.rs b/src/devtool/src/check.rs index dd7c016d..2f18ba6f 100644 --- a/src/devtool/src/check.rs +++ b/src/devtool/src/check.rs @@ -39,7 +39,6 @@ fn shellcheck(runner: &Runner) { } } - #[derive(Clap)] pub struct CheckOpts { /// Run autopep8 diff --git a/src/devtool/src/ci.rs b/src/devtool/src/ci.rs index 6f433319..aa24d8af 100644 --- a/src/devtool/src/ci.rs +++ b/src/devtool/src/ci.rs @@ -74,7 +74,8 @@ impl BuildInfo { } pub fn is_pr_e2e(&self) -> bool { - matches!(self.ty, + matches!( + self.ty, BuildType::Check { ty: CheckJobType::EndToEnd, .. From bbba2bc2d65f988d024a1557d58c8734c9efbe50 Mon Sep 17 00:00:00 2001 From: Mikail Bagishov Date: Sat, 1 May 2021 13:29:31 +0300 Subject: [PATCH 4/7] Allow smoke to fail --- bors.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bors.toml b/bors.toml index e1cda873..d8831b51 100644 --- a/bors.toml +++ b/bors.toml @@ -8,7 +8,7 @@ status = [ 'codegen', 'py-test', 'py-fmt', -'smoke' +# 'smoke' ] delete-merged-branches = true timeout-sec = 900 From 64d338348a231f31125d34c4b556e007b6ffbcfb Mon Sep 17 00:00:00 2001 From: Mikail Bagishov Date: Sat, 1 May 2021 13:36:26 +0300 Subject: [PATCH 5/7] update builder --- Cargo.lock | 1 - src/devtool/Cargo.toml | 1 - src/devtool/src/check.rs | 1 - src/dist-builder/src/artifact.rs | 5 ---- src/dist-builder/src/builder.rs | 48 ++------------------------------ src/dist-builder/src/emit.rs | 6 ---- src/dist-builder/src/main.rs | 22 +-------------- src/dist-builder/src/package.rs | 5 ---- 8 files changed, 4 insertions(+), 85 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 710f1187..5a994a7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -299,7 +299,6 @@ dependencies = [ "log", "serde", "serde_json", - "tempfile", "toml", "util", ] diff --git a/src/devtool/Cargo.toml b/src/devtool/Cargo.toml index 4054c20c..87160732 100644 --- a/src/devtool/Cargo.toml +++ b/src/devtool/Cargo.toml @@ -16,4 +16,3 @@ util = {path = "../util"} lazy_static = "1.4.0" anyhow = "1.0.33" serde_json = "1.0.59" -tempfile = "3.1.0" diff --git a/src/devtool/src/check.rs b/src/devtool/src/check.rs index 2f18ba6f..ac701360 100644 --- a/src/devtool/src/check.rs +++ b/src/devtool/src/check.rs @@ -1,4 +1,3 @@ -use anyhow::Context as _; use clap::Clap; use log::{debug, info}; use std::process::Command; diff --git a/src/dist-builder/src/artifact.rs b/src/dist-builder/src/artifact.rs index c86fa89d..ebc3d70c 100644 --- a/src/dist-builder/src/artifact.rs +++ b/src/dist-builder/src/artifact.rs @@ -3,11 +3,6 @@ pub(crate) struct RustArtifact { pub(crate) install_name: String, } -pub(crate) struct CmakeArtifact { - pub(crate) package_name: String, -} - pub(crate) enum Artifact { Rust(RustArtifact), - Cmake(CmakeArtifact), } diff --git a/src/dist-builder/src/builder.rs b/src/dist-builder/src/builder.rs index 9f94c32f..897380b6 100644 --- a/src/dist-builder/src/builder.rs +++ b/src/dist-builder/src/builder.rs @@ -1,7 +1,7 @@ use crate::{ - artifact::{Artifact, CmakeArtifact, RustArtifact}, + artifact::{Artifact, RustArtifact}, cfg::BuildProfile, - package::{CmakePackage, RustPackage}, + package::{RustPackage}, Params, }; use anyhow::Context as _; @@ -12,7 +12,6 @@ use util::cmd::CommandExt as _; pub struct Builder<'a> { params: &'a Params, rust_packages: Vec, - cmake_packages: Vec, } impl<'a> Builder<'a> { @@ -20,7 +19,6 @@ impl<'a> Builder<'a> { Builder { params, rust_packages: Vec::new(), - cmake_packages: Vec::new(), } } @@ -28,10 +26,6 @@ impl<'a> Builder<'a> { self.rust_packages.push(pkg); } - pub(crate) fn push_cmake(&mut self, pkg: CmakePackage) { - self.cmake_packages.push(pkg); - } - fn build_rust(&self) -> anyhow::Result> { let mut cmd = Command::new("cargo"); cmd.env("CARGO_PROFILE_RELEASE_INCREMENTAL", "false"); @@ -72,44 +66,8 @@ impl<'a> Builder<'a> { Ok(artifacts) } - fn build_cmake(&self) -> anyhow::Result> { - let mut artifacts = Vec::new(); - for pkg in &self.cmake_packages { - let install_dir = self - .params - .build - .canonicalize()? - .join("jjs-out") - .join(&pkg.name); - let build_dir = self.params.build.join("cmake-builds").join(&pkg.name); - std::fs::create_dir_all(&build_dir).ok(); - - let mut cmd_configure = Command::new("cmake"); - cmd_configure.arg(format!( - "-DCMAKE_BUILD_TYPE={}", - self.params.cfg.build.profile.as_str() - )); - cmd_configure.arg(format!("-DCMAKE_INSTALL_PREFIX={}", install_dir.display())); - cmd_configure.arg(self.params.src.join("src").join(&pkg.name)); - cmd_configure.current_dir(&build_dir); - cmd_configure.try_exec().context("failed to configure")?; - - let mut cmd_build = Command::new("cmake"); - cmd_build.current_dir(&build_dir); - cmd_build.args(&["--build", ".", "--target", "install"]); - cmd_build.try_exec().context("build error")?; - - artifacts.push(Artifact::Cmake(CmakeArtifact { - package_name: pkg.name.clone(), - })); - } - Ok(artifacts) - } - pub(crate) fn build(self) -> anyhow::Result> { - let mut rust_artifacts = self.build_rust()?; - let mut cmake_packages = self.build_cmake()?; - rust_artifacts.append(&mut cmake_packages); + let rust_artifacts = self.build_rust()?; Ok(rust_artifacts) } } diff --git a/src/dist-builder/src/emit.rs b/src/dist-builder/src/emit.rs index 72542a76..704aba10 100644 --- a/src/dist-builder/src/emit.rs +++ b/src/dist-builder/src/emit.rs @@ -86,12 +86,6 @@ impl DockerEmitter { .context("context preparation error")?; Self::emit_inner(params, &ctx_dir, &rs_art.package_name, &options)?; } - Artifact::Cmake(cm_art) => { - let install_dir = params.build.join("jjs-out").join(&cm_art.package_name); - std::fs::create_dir_all(&install_dir)?; - - Self::emit_inner(params, &install_dir, &cm_art.package_name, &options)?; - } } } for oth_pkg in other_packages { diff --git a/src/dist-builder/src/main.rs b/src/dist-builder/src/main.rs index 06de58cc..180a0cf9 100644 --- a/src/dist-builder/src/main.rs +++ b/src/dist-builder/src/main.rs @@ -25,7 +25,7 @@ mod package; use crate::{ cfg::BuildProfile, - package::{CmakePackage, MetaPackage, OtherPackage, RustPackage, Section}, + package::{MetaPackage, OtherPackage, RustPackage, Section}, }; use anyhow::Context as _; use clap::Clap as _; @@ -190,11 +190,8 @@ fn make_rust_package_list() -> Vec { //add("cleanup", "jjs-cleanup", Section::Tool); //add("envck", "jjs-env-check", Section::Tool); //add("setup", "jjs-setup", Section::Tool); - add("pps-cli", "jjs-pps", Section::Tool); //add("userlist", "jjs-userlist", Section::Tool); add("cli", "jjs-cli", Section::Tool); - add("invoker", "jjs-invoker", Section::Daemon); - add("svaluer", "jjs-svaluer", Section::Tool); /*add( "configure-toolchains", "jjs-configure-toolchains", @@ -213,15 +210,6 @@ fn make_other_package_list() -> Vec { pkgs } -fn make_cmake_package_list() -> Vec { - let mut pkgs = Vec::new(); - pkgs.push(CmakePackage { - name: "jtl".to_string(), - section: Section::Tool, - }); - pkgs -} - fn make_meta_package_list() -> Vec { let mut pkgs = Vec::new(); pkgs.push(MetaPackage { @@ -265,10 +253,6 @@ fn build_jjs_components(params: &Params) -> anyhow::Result<()> { .into_iter() .filter(|pkg| check_filter(¶ms.cfg.components, &pkg.name, pkg.section)) .collect::>(); - let cmake_pkgs = make_cmake_package_list() - .into_iter() - .filter(|pkg| check_filter(¶ms.cfg.components, &pkg.name, pkg.section)) - .collect::>(); let meta_pkgs = make_meta_package_list() .into_iter() .filter(|pkg| check_meta_pkg_filter(¶ms.cfg.components, pkg.section)) @@ -279,10 +263,6 @@ fn build_jjs_components(params: &Params) -> anyhow::Result<()> { println!("Will build: {}", &pkg.name); builder.push_rust(pkg); } - for pkg in cmake_pkgs { - println!("Will build: {}", &pkg.name); - builder.push_cmake(pkg); - } let artifacts = builder.build().context("build error")?; if let Some(docker_cfg) = ¶ms.cfg.emit.docker { diff --git a/src/dist-builder/src/package.rs b/src/dist-builder/src/package.rs index aa2feb60..ebda516f 100644 --- a/src/dist-builder/src/package.rs +++ b/src/dist-builder/src/package.rs @@ -7,11 +7,6 @@ pub(crate) struct RustPackage { pub(crate) section: Section, } -pub(crate) struct CmakePackage { - pub(crate) name: String, - pub(crate) section: Section, -} - #[derive(Debug)] pub(crate) struct OtherPackage { /// As in sources From d70ac1f024288fb25563ba091e802bfbfa2b6ef8 Mon Sep 17 00:00:00 2001 From: Mikail Bagishov Date: Sat, 1 May 2021 13:40:41 +0300 Subject: [PATCH 6/7] fmt --- src/dist-builder/src/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dist-builder/src/builder.rs b/src/dist-builder/src/builder.rs index 897380b6..0fd70a3c 100644 --- a/src/dist-builder/src/builder.rs +++ b/src/dist-builder/src/builder.rs @@ -1,7 +1,7 @@ use crate::{ artifact::{Artifact, RustArtifact}, cfg::BuildProfile, - package::{RustPackage}, + package::RustPackage, Params, }; use anyhow::Context as _; From cb30a29040cd69af786bcdc6cdeee7b1ef74340a Mon Sep 17 00:00:00 2001 From: Mikail Bagishov Date: Sat, 1 May 2021 13:44:19 +0300 Subject: [PATCH 7/7] clippy --- src/devtool/src/check.rs | 4 ---- src/dist-builder/src/main.rs | 14 ++++++-------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/devtool/src/check.rs b/src/devtool/src/check.rs index ac701360..da2550ef 100644 --- a/src/devtool/src/check.rs +++ b/src/devtool/src/check.rs @@ -3,10 +3,6 @@ use log::{debug, info}; use std::process::Command; use util::cmd::{CommandExt, Runner}; -fn cmake_bin() -> &'static str { - "cmake" -} - fn autopep8(runner: &Runner) { info!("running autopep8"); let python_files: Vec<_> = diff --git a/src/dist-builder/src/main.rs b/src/dist-builder/src/main.rs index 180a0cf9..2251febb 100644 --- a/src/dist-builder/src/main.rs +++ b/src/dist-builder/src/main.rs @@ -101,8 +101,8 @@ fn main() { let opt: Opt = Opt::parse(); let tool_info = cfg::ToolInfo { - cargo: opt.cargo.as_deref().unwrap_or_else(|| "cargo").to_string(), - cmake: opt.cmake.as_deref().unwrap_or_else(|| "cmake").to_string(), + cargo: opt.cargo.as_deref().unwrap_or("cargo").to_string(), + cmake: opt.cmake.as_deref().unwrap_or("cmake").to_string(), docker: opt .docker_name .as_deref() @@ -202,20 +202,18 @@ fn make_rust_package_list() -> Vec { } fn make_other_package_list() -> Vec { - let mut pkgs = Vec::new(); - pkgs.push(OtherPackage { + let pkgs = vec![OtherPackage { name: "apiserver".to_string(), section: Section::Daemon, - }); + }]; pkgs } fn make_meta_package_list() -> Vec { - let mut pkgs = Vec::new(); - pkgs.push(MetaPackage { + let pkgs = vec![MetaPackage { name: "toolkit".to_string(), section: Section::Tool, - }); + }]; pkgs }