From 9dacf748651ea7139c0e9f3dee9ae66d949bf73f Mon Sep 17 00:00:00 2001 From: Katharina Fey Date: Sat, 31 Oct 2020 18:57:39 +0100 Subject: [PATCH] Add 'apps/servers/octopus/' from commit '623954d19fdf0dca47db319e5c88ee561aa8d25c' git-subtree-dir: apps/servers/octopus git-subtree-mainline: 4e09fe2509904ee64d2470ca8d41006d51e4ffd6 git-subtree-split: 623954d19fdf0dca47db319e5c88ee561aa8d25c --- apps/servers/octopus/.envrc | 1 + apps/servers/octopus/.gitignore | 3 + apps/servers/octopus/Cargo.lock | 2330 +++++++++++++++++ apps/servers/octopus/Cargo.toml | 28 + apps/servers/octopus/LICENSE | 661 +++++ apps/servers/octopus/README | 13 + apps/servers/octopus/TODO | 12 + apps/servers/octopus/fake-readme.md | 26 + apps/servers/octopus/shell.nix | 10 + apps/servers/octopus/src/cli.rs | 79 + apps/servers/octopus/src/config.rs | 17 + apps/servers/octopus/src/git/log.rs | 117 + apps/servers/octopus/src/git/mod.rs | 58 + apps/servers/octopus/src/git/tree.rs | 176 ++ apps/servers/octopus/src/main.rs | 29 + apps/servers/octopus/src/pages/files.rs | 20 + apps/servers/octopus/src/pages/mod.rs | 15 + apps/servers/octopus/src/pages/overview.rs | 24 + apps/servers/octopus/src/pages/p404.rs | 13 + apps/servers/octopus/src/pages/repo/about.rs | 26 + .../servers/octopus/src/pages/repo/details.rs | 38 + apps/servers/octopus/src/pages/repo/mod.rs | 7 + apps/servers/octopus/src/project/mod.rs | 8 + apps/servers/octopus/src/repo.rs | 43 + apps/servers/octopus/src/state/mod.rs | 14 + apps/servers/octopus/src/templ_data/files.rs | 13 + apps/servers/octopus/src/templ_data/mod.rs | 38 + .../octopus/src/templ_data/overview.rs | 11 + apps/servers/octopus/src/templ_data/repo.rs | 80 + apps/servers/octopus/static/fakeavi.png | Bin 0 -> 29366 bytes apps/servers/octopus/static/main.css | 81 + apps/servers/octopus/static/octopus.png | Bin 0 -> 53947 bytes apps/servers/octopus/static/octopus.svg | 58 + apps/servers/octopus/static/rust.png | Bin 0 -> 56915 bytes apps/servers/octopus/supergit/Cargo.toml | 10 + apps/servers/octopus/supergit/src/bin/test.rs | 16 + apps/servers/octopus/supergit/src/branch.rs | 22 + apps/servers/octopus/supergit/src/commit.rs | 11 + apps/servers/octopus/supergit/src/diff.rs | 5 + apps/servers/octopus/supergit/src/files.rs | 7 + apps/servers/octopus/supergit/src/lib.rs | 55 + .../octopus/supergit/src/raw/#tree_walk.rs# | 1 + .../octopus/supergit/src/raw/.#tree_walk.rs | 1 + .../octopus/supergit/src/raw/branch_walk.rs | 19 + apps/servers/octopus/supergit/src/raw/mod.rs | 45 + .../octopus/supergit/src/raw/tree_walk.rs | 1 + apps/servers/octopus/templates/404.html | 11 + apps/servers/octopus/templates/core.html | 40 + apps/servers/octopus/templates/files.html | 17 + apps/servers/octopus/templates/index.html | 7 + .../servers/octopus/templates/repo/about.html | 6 + apps/servers/octopus/templates/repo/base.html | 37 + .../octopus/templates/repo/details.html | 49 + 53 files changed, 4409 insertions(+) create mode 100644 apps/servers/octopus/.envrc create mode 100644 apps/servers/octopus/.gitignore create mode 100644 apps/servers/octopus/Cargo.lock create mode 100644 apps/servers/octopus/Cargo.toml create mode 100644 apps/servers/octopus/LICENSE create mode 100644 apps/servers/octopus/README create mode 100644 apps/servers/octopus/TODO create mode 100644 apps/servers/octopus/fake-readme.md create mode 100644 apps/servers/octopus/shell.nix create mode 100644 apps/servers/octopus/src/cli.rs create mode 100644 apps/servers/octopus/src/config.rs create mode 100644 apps/servers/octopus/src/git/log.rs create mode 100644 apps/servers/octopus/src/git/mod.rs create mode 100644 apps/servers/octopus/src/git/tree.rs create mode 100644 apps/servers/octopus/src/main.rs create mode 100644 apps/servers/octopus/src/pages/files.rs create mode 100644 apps/servers/octopus/src/pages/mod.rs create mode 100644 apps/servers/octopus/src/pages/overview.rs create mode 100644 apps/servers/octopus/src/pages/p404.rs create mode 100644 apps/servers/octopus/src/pages/repo/about.rs create mode 100644 apps/servers/octopus/src/pages/repo/details.rs create mode 100644 apps/servers/octopus/src/pages/repo/mod.rs create mode 100644 apps/servers/octopus/src/project/mod.rs create mode 100644 apps/servers/octopus/src/repo.rs create mode 100644 apps/servers/octopus/src/state/mod.rs create mode 100644 apps/servers/octopus/src/templ_data/files.rs create mode 100644 apps/servers/octopus/src/templ_data/mod.rs create mode 100644 apps/servers/octopus/src/templ_data/overview.rs create mode 100644 apps/servers/octopus/src/templ_data/repo.rs create mode 100644 apps/servers/octopus/static/fakeavi.png create mode 100644 apps/servers/octopus/static/main.css create mode 100644 apps/servers/octopus/static/octopus.png create mode 100644 apps/servers/octopus/static/octopus.svg create mode 100644 apps/servers/octopus/static/rust.png create mode 100644 apps/servers/octopus/supergit/Cargo.toml create mode 100644 apps/servers/octopus/supergit/src/bin/test.rs create mode 100644 apps/servers/octopus/supergit/src/branch.rs create mode 100644 apps/servers/octopus/supergit/src/commit.rs create mode 100644 apps/servers/octopus/supergit/src/diff.rs create mode 100644 apps/servers/octopus/supergit/src/files.rs create mode 100644 apps/servers/octopus/supergit/src/lib.rs create mode 100644 apps/servers/octopus/supergit/src/raw/#tree_walk.rs# create mode 120000 apps/servers/octopus/supergit/src/raw/.#tree_walk.rs create mode 100644 apps/servers/octopus/supergit/src/raw/branch_walk.rs create mode 100644 apps/servers/octopus/supergit/src/raw/mod.rs create mode 100644 apps/servers/octopus/supergit/src/raw/tree_walk.rs create mode 100644 apps/servers/octopus/templates/404.html create mode 100644 apps/servers/octopus/templates/core.html create mode 100644 apps/servers/octopus/templates/files.html create mode 100644 apps/servers/octopus/templates/index.html create mode 100644 apps/servers/octopus/templates/repo/about.html create mode 100644 apps/servers/octopus/templates/repo/base.html create mode 100644 apps/servers/octopus/templates/repo/details.html diff --git a/apps/servers/octopus/.envrc b/apps/servers/octopus/.envrc new file mode 100644 index 00000000000..051d09d292a --- /dev/null +++ b/apps/servers/octopus/.envrc @@ -0,0 +1 @@ +eval "$(lorri direnv)" diff --git a/apps/servers/octopus/.gitignore b/apps/servers/octopus/.gitignore new file mode 100644 index 00000000000..91ea9099ee2 --- /dev/null +++ b/apps/servers/octopus/.gitignore @@ -0,0 +1,3 @@ +/target +**/*.rs.bk +testrepo \ No newline at end of file diff --git a/apps/servers/octopus/Cargo.lock b/apps/servers/octopus/Cargo.lock new file mode 100644 index 00000000000..42f0f4d1df0 --- /dev/null +++ b/apps/servers/octopus/Cargo.lock @@ -0,0 +1,2330 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "actix-codec" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09e55f0a5c2ca15795035d90c46bd0e73a5123b72f68f12596d6ba5282051380" +dependencies = [ + "bitflags", + "bytes", + "futures-core", + "futures-sink", + "log", + "tokio", + "tokio-util 0.2.0", +] + +[[package]] +name = "actix-codec" +version = "0.3.0" +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 0.3.1", +] + +[[package]] +name = "actix-connect" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c95cc9569221e9802bf4c377f6c18b90ef10227d787611decf79fd47d2a8e76c" +dependencies = [ + "actix-codec 0.2.0", + "actix-rt", + "actix-service", + "actix-utils 1.0.6", + "derive_more", + "either", + "futures", + "http", + "log", + "trust-dns-proto", + "trust-dns-resolver", +] + +[[package]] +name = "actix-files" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193b22cb1f7b4ff12a4eb2415d6d19e47e44ea93e05930b30d05375ea29d3529" +dependencies = [ + "actix-http", + "actix-service", + "actix-web", + "bitflags", + "bytes", + "derive_more", + "futures-core", + "futures-util", + "log", + "mime", + "mime_guess", + "percent-encoding", + "v_htmlescape", +] + +[[package]] +name = "actix-http" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c16664cc4fdea8030837ad5a845eb231fb93fc3c5c171edfefb52fad92ce9019" +dependencies = [ + "actix-codec 0.2.0", + "actix-connect", + "actix-rt", + "actix-service", + "actix-threadpool", + "actix-utils 1.0.6", + "base64", + "bitflags", + "brotli2", + "bytes", + "chrono", + "copyless", + "derive_more", + "either", + "encoding_rs", + "failure", + "flate2", + "futures-channel", + "futures-core", + "futures-util", + "fxhash", + "h2", + "http", + "httparse", + "indexmap", + "language-tags", + "lazy_static", + "log", + "mime", + "percent-encoding", + "pin-project 0.4.27", + "rand", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "sha1", + "slab", + "time", +] + +[[package]] +name = "actix-macros" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a60f9ba7c4e6df97f3aacb14bb5c0cd7d98a49dcbaed0d7f292912ad9a6a3ed2" +dependencies = [ + "quote 1.0.7", + "syn 1.0.48", +] + +[[package]] +name = "actix-router" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd1f7dbda1645bf7da33554db60891755f6c01c1b2169e2f4c492098d30c235" +dependencies = [ + "bytestring", + "http", + "log", + "regex", + "serde", +] + +[[package]] +name = "actix-rt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143fcc2912e0d1de2bcf4e2f720d2a60c28652ab4179685a1ee159e0fb3db227" +dependencies = [ + "actix-macros", + "actix-threadpool", + "copyless", + "futures-channel", + "futures-util", + "smallvec", + "tokio", +] + +[[package]] +name = "actix-server" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45407e6e672ca24784baa667c5d32ef109ccdd8d5e0b5ebb9ef8a67f4dfb708e" +dependencies = [ + "actix-codec 0.3.0", + "actix-rt", + "actix-service", + "actix-utils 2.0.0", + "futures-channel", + "futures-util", + "log", + "mio", + "mio-uds", + "num_cpus", + "slab", + "socket2", +] + +[[package]] +name = "actix-service" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0052435d581b5be835d11f4eb3bce417c8af18d87ddf8ace99f8e67e595882bb" +dependencies = [ + "futures-util", + "pin-project 0.4.27", +] + +[[package]] +name = "actix-testing" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47239ca38799ab74ee6a8a94d1ce857014b2ac36f242f70f3f75a66f691e791c" +dependencies = [ + "actix-macros", + "actix-rt", + "actix-server", + "actix-service", + "log", + "socket2", +] + +[[package]] +name = "actix-threadpool" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d209f04d002854b9afd3743032a27b066158817965bf5d036824d19ac2cc0e30" +dependencies = [ + "derive_more", + "futures-channel", + "lazy_static", + "log", + "num_cpus", + "parking_lot", + "threadpool", +] + +[[package]] +name = "actix-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e5b4faaf105e9a6d389c606c298dcdb033061b00d532af9df56ff3a54995a8" +dependencies = [ + "actix-codec 0.2.0", + "actix-rt", + "actix-service", + "actix-utils 1.0.6", + "derive_more", + "either", + "futures", + "log", +] + +[[package]] +name = "actix-utils" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf8f5631bf01adec2267808f00e228b761c60c0584cc9fa0b5364f41d147f4e" +dependencies = [ + "actix-codec 0.2.0", + "actix-rt", + "actix-service", + "bitflags", + "bytes", + "either", + "futures", + "log", + "pin-project 0.4.27", + "slab", +] + +[[package]] +name = "actix-utils" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9022dec56632d1d7979e59af14f0597a28a830a9c1c7fec8b2327eb9f16b5a" +dependencies = [ + "actix-codec 0.3.0", + "actix-rt", + "actix-service", + "bitflags", + "bytes", + "either", + "futures-channel", + "futures-sink", + "futures-util", + "log", + "pin-project 0.4.27", + "slab", +] + +[[package]] +name = "actix-web" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3158e822461040822f0dbf1735b9c2ce1f95f93b651d7a7aded00b1efbb1f635" +dependencies = [ + "actix-codec 0.2.0", + "actix-http", + "actix-macros", + "actix-router", + "actix-rt", + "actix-server", + "actix-service", + "actix-testing", + "actix-threadpool", + "actix-tls", + "actix-utils 1.0.6", + "actix-web-codegen", + "awc", + "bytes", + "derive_more", + "encoding_rs", + "futures", + "fxhash", + "log", + "mime", + "net2", + "pin-project 0.4.27", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "time", + "url", +] + +[[package]] +name = "actix-web-codegen" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a71bf475cbe07281d0b3696abb48212db118e7e23219f13596ce865235ff5766" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.7", + "syn 1.0.48", +] + +[[package]] +name = "addr2line" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" + +[[package]] +name = "aho-corasick" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b476ce7103678b0c6d3d395dbbae31d48ff910bd28be979ba5d48c6351131d0d" +dependencies = [ + "memchr", +] + +[[package]] +name = "arc-swap" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" + +[[package]] +name = "askama" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dc2a4b6d7f812d2b13d251ae792caecebd635d6401761162d4b71d5ebe1a010" +dependencies = [ + "askama_derive", + "askama_escape", + "askama_shared", +] + +[[package]] +name = "askama_derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23ee2fff0f22ad5d215cace1227cd036c28e81e26206763bb837b6d0e766c87d" +dependencies = [ + "askama_shared", + "nom", + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", +] + +[[package]] +name = "askama_escape" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0de942230b5beedaa9e1d64df5b76fa1c97002e4c7982897be899cccf40621d" + +[[package]] +name = "askama_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6dfa6b6d254fd066a8bbed9a8f913123e3f701db89216ad4f0aff04ad87718c" +dependencies = [ + "askama_escape", + "humansize", + "num-traits", + "serde", + "serde_derive", + "toml", +] + +[[package]] +name = "async-channel" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59740d83946db6a5af71ae25ddf9562c2b176b2ca42cf99a455f09f4a220d6b9" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-executor" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d373d78ded7d0b3fa8039375718cde0aace493f2e34fb60f51cbf567562ca801" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "once_cell", + "vec-arena", +] + +[[package]] +name = "async-global-executor" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "124ac8c265e407641c3362b8f4d39cdb4e243885b71eef087be27199790f5a3a" +dependencies = [ + "async-executor", + "async-io", + "futures-lite", + "num_cpus", + "once_cell", +] + +[[package]] +name = "async-io" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54bc4c1c7292475efb2253227dbcfad8fe1ca4c02bc62c510cc2f3da5c4704e" +dependencies = [ + "concurrent-queue", + "fastrand", + "futures-lite", + "libc", + "log", + "nb-connect", + "once_cell", + "parking", + "polling", + "vec-arena", + "waker-fn", + "winapi 0.3.9", +] + +[[package]] +name = "async-mutex" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-std" +version = "1.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9fa76751505e8df1c7a77762f60486f60c71bbd9b8557f4da6ad47d083732ed" +dependencies = [ + "async-global-executor", + "async-io", + "async-mutex", + "blocking", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "num_cpus", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0" + +[[package]] +name = "async-trait" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b246867b8b3b6ae56035f1eb1ed557c1d8eae97f0d53696138a50fa0e3a3b8c0" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.7", + "syn 1.0.48", +] + +[[package]] +name = "atomic-waker" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "awc" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7601d4d1d7ef2335d6597a41b5fe069f6ab799b85f53565ab390e7b7065aac5" +dependencies = [ + "actix-codec 0.2.0", + "actix-http", + "actix-rt", + "actix-service", + "base64", + "bytes", + "derive_more", + "futures-core", + "log", + "mime", + "percent-encoding", + "rand", + "serde", + "serde_json", + "serde_urlencoded", +] + +[[package]] +name = "backtrace" +version = "0.3.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707b586e0e2f247cbde68cdd2c3ce69ea7b7be43e1c5b426e37c9319c4b9838e" +dependencies = [ + "addr2line", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "blocking" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e170dbede1f740736619b776d7251cb1b9095c435c34d8ca9f57fcd2f335e9" +dependencies = [ + "async-channel", + "async-task", + "atomic-waker", + "fastrand", + "futures-lite", + "once_cell", +] + +[[package]] +name = "brotli-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "brotli2" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" +dependencies = [ + "brotli-sys", + "libc", +] + +[[package]] +name = "bumpalo" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" + +[[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 = "cache-padded" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba" + +[[package]] +name = "cc" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed67cbde08356238e75fc4656be4749481eeffb09e19f320a25237d5221c985d" +dependencies = [ + "jobserver", +] + +[[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" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "time", + "winapi 0.3.9", +] + +[[package]] +name = "cloudabi" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467" +dependencies = [ + "bitflags", +] + +[[package]] +name = "concurrent-queue" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" +dependencies = [ + "cache-padded", +] + +[[package]] +name = "copyless" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536" + +[[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-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg", + "cfg-if 0.1.10", + "lazy_static", +] + +[[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 = "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 = "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.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "event-listener" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" + +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.7", + "syn 1.0.48", + "synstructure", +] + +[[package]] +name = "fastrand" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca5faf057445ce5c9d4329e382b2ce7ca38550ef3b73a5348362d5f24e0c7fe3" +dependencies = [ + "instant", +] + +[[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 = "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.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-io" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1798854a4727ff944a7b12aa999f58ce7aa81db80d2dfaaf2ba06f065ddd2b" + +[[package]] +name = "futures-lite" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6c079abfac3ab269e2927ec048dabc89d009ebfdda6b8ee86624f30c689658" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[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-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 = "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 = "gimli" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724" + +[[package]] +name = "git2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77519ef7c5beee314d0804d4534f01e0f9e8d9acdee2b7a48627e590b27e0ec4" +dependencies = [ + "bitflags", + "libc", + "libgit2-sys", + "log", + "openssl-probe", + "openssl-sys", + "url", +] + +[[package]] +name = "gloo-timers" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[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 0.3.1", + "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 = "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 = "httparse" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" + +[[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 = "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 = "indexmap" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2" +dependencies = [ + "autocfg", + "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 = "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", +] + +[[package]] +name = "itoa" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" + +[[package]] +name = "jobserver" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2" +dependencies = [ + "libc", +] + +[[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 = "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 = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + +[[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.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743" + +[[package]] +name = "libgit2-sys" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9ec6bca50549d34a392611dde775123086acbd994e3fff64954777ce2dc2e51" +dependencies = [ + "cc", + "libc", + "libssh2-sys", + "libz-sys", + "openssl-sys", + "pkg-config", +] + +[[package]] +name = "libssh2-sys" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca46220853ba1c512fc82826d0834d87b06bcd3c2a42241b7de72f3d2fe17056" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libz-sys" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "602113192b08db8f38796c4e85c39e960c145965140e918018bcde1952429655" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[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.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 = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "markdown" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef3aab6a1d529b112695f72beec5ee80e729cb45af58663ec902c8fac764ecdd" +dependencies = [ + "lazy_static", + "pipeline", + "regex", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matches" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" + +[[package]] +name = "memchr" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "mime_guess" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" +dependencies = [ + "adler", + "autocfg", +] + +[[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", + "net2", + "slab", + "winapi 0.2.8", +] + +[[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 = "nb-connect" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8123a81538e457d44b933a02faf885d3fe8408806b23fa700e8f01c6c3a98998" +dependencies = [ + "libc", + "winapi 0.3.9", +] + +[[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 = "nom" +version = "4.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" +dependencies = [ + "memchr", + "version_check 0.1.5", +] + +[[package]] +name = "num-integer" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" +dependencies = [ + "autocfg", +] + +[[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.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37fd5004feb2ce328a52b0b3d01dbf4ffff72583493900ed15f22d4111c51693" + +[[package]] +name = "once_cell" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad" + +[[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", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + +[[package]] +name = "parking_lot" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b" +dependencies = [ + "cfg-if 0.1.10", + "cloudabi", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi 0.3.9", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pin-project" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffbc8e94b38ea3d2d8ba92aea2983b503cd75d0888d75b86bb37970b5698e15" +dependencies = [ + "pin-project-internal 0.4.27", +] + +[[package]] +name = "pin-project" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee41d838744f60d959d7074e3afb6b35c7456d0f61cad38a24e35e6553f73841" +dependencies = [ + "pin-project-internal 1.0.1", +] + +[[package]] +name = "pin-project-internal" +version = "0.4.27" +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", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81a4ffa594b66bff340084d4081df649a7dc049ac8d7fc458d8e628bfbbb2f86" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.7", + "syn 1.0.48", +] + +[[package]] +name = "pin-project-lite" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pipeline" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d15b6607fa632996eb8a17c9041cb6071cb75ac057abd45dece578723ea8c7c0" + +[[package]] +name = "pkg-config" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + +[[package]] +name = "polling" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a7bc6b2a29e632e45451c941832803a18cce6781db04de8a04696cdca8bde4" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "log", + "wepoll-sys", + "winapi 0.3.9", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20" + +[[package]] +name = "proc-macro-hack" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598" + +[[package]] +name = "proc-macro-nested" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a" + +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +dependencies = [ + "unicode-xid 0.1.0", +] + +[[package]] +name = "proc-macro2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +dependencies = [ + "unicode-xid 0.2.1", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +dependencies = [ + "proc-macro2 0.4.30", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2 1.0.24", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "regex" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8963b85b8ce3074fecffde43b4b0dded83ce2f367dc8d363afc56679f3ee820b" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", +] + +[[package]] +name = "regex-syntax" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cab7a364d15cde1e505267766a2d3c4e22a843e1a601f0fa7564c0f82ced11c" + +[[package]] +name = "resolv-conf" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11834e137f3b14e309437a8276714eed3a80d1ef894869e510f2c0c0b98b9f4a" +dependencies = [ + "hostname", + "quick-error", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "serde" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.7", + "syn 1.0.48", +] + +[[package]] +name = "serde_json" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" +dependencies = [ + "dtoa", + "itoa", + "serde", + "url", +] + +[[package]] +name = "sha1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" + +[[package]] +name = "signal-hook-registry" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e12110bc539e657a646068aaf5eb5b63af9d0c1f7b29c97113fad80e15f035" +dependencies = [ + "arc-swap", + "libc", +] + +[[package]] +name = "slab" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" + +[[package]] +name = "smallvec" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252" + +[[package]] +name = "socket2" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1fa70dc5c8104ec096f4fe7ede7a221d35ae13dcd19ba1ad9a81d2cab9a1c44" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "redox_syscall", + "winapi 0.3.9", +] + +[[package]] +name = "supergit" +version = "0.1.0" +dependencies = [ + "async-std", + "git2", +] + +[[package]] +name = "syn" +version = "0.15.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "unicode-xid 0.1.0", +] + +[[package]] +name = "syn" +version = "1.0.48" +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", +] + +[[package]] +name = "synstructure" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.7", + "syn 1.0.48", + "unicode-xid 0.2.1", +] + +[[package]] +name = "termcolor" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" +dependencies = [ + "winapi-util", +] + +[[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 = "tinyvec" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117" + +[[package]] +name = "tokio" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd" +dependencies = [ + "bytes", + "futures-core", + "iovec", + "lazy_static", + "libc", + "memchr", + "mio", + "mio-uds", + "pin-project-lite", + "signal-hook-registry", + "slab", + "winapi 0.3.9", +] + +[[package]] +name = "tokio-util" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "log", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "log", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0987850db3733619253fe60e17cb59b82d37c7e6c0236bb81e4d6b87c879f27" +dependencies = [ + "cfg-if 0.1.10", + "log", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tracing-futures" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c" +dependencies = [ + "pin-project 0.4.27", + "tracing", +] + +[[package]] +name = "trust-dns-proto" +version = "0.18.0-alpha.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a7f3a2ab8a919f5eca52a468866a67ed7d3efa265d48a652a9a3452272b413f" +dependencies = [ + "async-trait", + "enum-as-inner", + "failure", + "futures", + "idna", + "lazy_static", + "log", + "rand", + "smallvec", + "socket2", + "tokio", + "url", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.18.0-alpha.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f90b1502b226f8b2514c6d5b37bafa8c200d7ca4102d57dc36ee0f3b7a04a2f" +dependencies = [ + "cfg-if 0.1.10", + "failure", + "futures", + "ipconfig", + "lazy_static", + "log", + "lru-cache", + "resolv-conf", + "smallvec", + "tokio", + "trust-dns-proto", +] + +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check 0.9.2", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" +dependencies = [ + "matches", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" + +[[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 = "url" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" +dependencies = [ + "idna", + "matches", + "percent-encoding", +] + +[[package]] +name = "v_escape" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "660b101c07b5d0863deb9e7fb3138777e858d6d2a79f9e6049a27d1cc77c6da6" +dependencies = [ + "v_escape_derive", +] + +[[package]] +name = "v_escape_derive" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2ca2a14bc3fc5b64d188b087a7d3a927df87b152e941ccfbc66672e20c467ae" +dependencies = [ + "nom", + "proc-macro2 1.0.24", + "quote 1.0.7", + "syn 1.0.48", +] + +[[package]] +name = "v_htmlescape" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33e939c0d8cf047514fb6ba7d5aac78bc56677a6938b2ee67000b91f2e97e41" +dependencies = [ + "cfg-if 0.1.10", + "v_escape", +] + +[[package]] +name = "vcpkg" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c" + +[[package]] +name = "vec-arena" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eafc1b9b2dfc6f5529177b62cf806484db55b32dc7c9658a118e11bbeb33061d" + +[[package]] +name = "version_check" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" + +[[package]] +name = "version_check" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" + +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "wasm-bindgen" +version = "0.2.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42" +dependencies = [ + "cfg-if 0.1.10", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2 1.0.24", + "quote 1.0.7", + "syn 1.0.48", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7866cab0aa01de1edf8b5d7936938a7e397ee50ce24119aef3e1eaa3b6171da" +dependencies = [ + "cfg-if 0.1.10", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038" +dependencies = [ + "quote 1.0.7", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.7", + "syn 1.0.48", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307" + +[[package]] +name = "web-sys" +version = "0.3.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bf6ef87ad7ae8008e15a355ce696bed26012b7caa21605188cfd8214ab51e2d" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webgit" +version = "0.2.0" +dependencies = [ + "actix-files", + "actix-rt", + "actix-web", + "askama", + "env_logger", + "git2", + "markdown", +] + +[[package]] +name = "wepoll-sys" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcb14dea929042224824779fbc82d9fab8d2e6d3cbc0ac404de8edf489e77ff" +dependencies = [ + "cc", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi 0.3.9", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +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 = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] diff --git a/apps/servers/octopus/Cargo.toml b/apps/servers/octopus/Cargo.toml new file mode 100644 index 00000000000..afc01fdcab4 --- /dev/null +++ b/apps/servers/octopus/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "webgit" +description = "A lightweight web frontend for git repositories" +version = "0.2.0" +authors = ["Kaiden Fey "] +edition = "2018" + +[dependencies] +actix-files = "0.2" +actix-rt = "1.0.0" +actix-web = "2.0.0" +askama = "0.8" +env_logger = "0.6" +git2 = "0.11" +markdown = { version = "0.3.0", optional = true } + +[build-dependencies] +askama = "0.8" + +[features] +default = ["markdown-readme"] +markdown-readme = ["markdown"] + +[workspace] +members = [ + ".", + "supergit", +] \ No newline at end of file diff --git a/apps/servers/octopus/LICENSE b/apps/servers/octopus/LICENSE new file mode 100644 index 00000000000..0ad25db4bd1 --- /dev/null +++ b/apps/servers/octopus/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/apps/servers/octopus/README b/apps/servers/octopus/README new file mode 100644 index 00000000000..2834983a3f3 --- /dev/null +++ b/apps/servers/octopus/README @@ -0,0 +1,13 @@ + .'.' + .'-'. + . ( o O) + \_ ` _, _ +-.___'.) ( ,-' + '-.O.'-..-.. octopus git mono-repo explorer + ./\/\/ | \_.-._ + ; + ._/ + + +A visualiser for mono-repos, with per project pages, histories, and +committer data. \ No newline at end of file diff --git a/apps/servers/octopus/TODO b/apps/servers/octopus/TODO new file mode 100644 index 00000000000..38e8a108932 --- /dev/null +++ b/apps/servers/octopus/TODO @@ -0,0 +1,12 @@ +TODO +==== + +Things that need doing for the next milestone/ version. For now this +will just be a list of basic features and data that octopus needs +access to from a repo. + +- contributors/ number of contributors +- commits on $branch for the log +- Render a README, or markdown README. Markdown support should be optional +- Build a lazy abstraction over the repo tree for the explorer +- diff --git a/apps/servers/octopus/fake-readme.md b/apps/servers/octopus/fake-readme.md new file mode 100644 index 00000000000..d851cd66163 --- /dev/null +++ b/apps/servers/octopus/fake-readme.md @@ -0,0 +1,26 @@ +# spacekookie's project monorepo + +**Welcome to my personal code and project monorepo archive!** + +It contains most projects I work on in my own time, including the +tools to host and manage this collection of projects. Projects that +are deemed note-worthy enough have their own project pages. When +browsing the file hierarchy, you will be notified about these project +pages, but not immediately taken to them. + + +## Structure + +The root of the project contains a list of directories, each for one +project. The git history of this repository might be very non-linear, +considering that it was created by merging multiple earlier +repositories in via sub-trees. + +You can also get a per-project history, by cloning only a sub-tree of +this repo, or by looking at the log page on a project. + + +## Self hosted + +The software that is hosting this code archive is called [`octopus`](./) +and included in this repository. diff --git a/apps/servers/octopus/shell.nix b/apps/servers/octopus/shell.nix new file mode 100644 index 00000000000..aefc4932482 --- /dev/null +++ b/apps/servers/octopus/shell.nix @@ -0,0 +1,10 @@ +with import {}; + +stdenv.mkDerivation { + name = "webgit"; + buildInputs = with pkgs; [ + rustracer rustup clangStdenv + + cargo-watch openssl pkg-config + ]; +} diff --git a/apps/servers/octopus/src/cli.rs b/apps/servers/octopus/src/cli.rs new file mode 100644 index 00000000000..500a901954e --- /dev/null +++ b/apps/servers/octopus/src/cli.rs @@ -0,0 +1,79 @@ +use clap::{App, Arg}; +use colored::Colorize; +use std::{ + env, + fs::File, + path::{Path, PathBuf}, +}; + +pub struct Paths { + pub config: File, + pub data: PathBuf, +} + +/// Initialise the application by getting valid path options +pub fn init() -> Paths { + let app = App::new("webgit") + .about("The friendly and simple git web frontend") + .version("0.0.0") + .arg( + Arg::with_name("CONFIG") + .short("c") + .long("config") + .takes_value(true) + .help( + "Provide the path to the system configuration. Alternatively \ + set WEBGIT_CONFIG_PATH in your env", + ), + ) + .arg( + Arg::with_name("DATA_DIR") + .short("d") + .long("data-dir") + .takes_value(true) + .help( + "Specify where webgit should save git repositories. Alternatively \ + set WEBGIT_DATA_DIR in your env", + ), + ); + + let matches = app.get_matches(); + + Paths { + config: File::open( + env::var_os("WEBGIT_CONFIG_PATH") + .map(|os| match os.into_string() { + Ok(p) => p.to_owned(), + Err(_) => { + eprintln!("{}: Failed to parse provided config path!", "Error:".red()); + std::process::exit(2); + } + }) + .unwrap_or_else(|| match matches.value_of("CONFIG") { + Some(p) => p.to_owned(), + None => { + eprintln!("{}: No config provided!", "Error:".red()); + std::process::exit(2); + } + }), + ) + .expect(&format!("{}: Config file not found!", "Error:".red())), + data: Path::new( + &env::var_os("WEBGIT_DATA_DIR") + .map(|os| { + os.into_string().expect(&format!( + "{}: Failed to parse provided data-dir path!", + "Error".red() + )) + }) + .unwrap_or_else(|| match matches.value_of("CONFIG") { + Some(p) => p.to_owned(), + None => { + eprintln!("{}: No data dir provided!", "Error:".red()); + std::process::exit(2); + } + }), + ) + .into(), + } +} diff --git a/apps/servers/octopus/src/config.rs b/apps/servers/octopus/src/config.rs new file mode 100644 index 00000000000..99e8cffd94b --- /dev/null +++ b/apps/servers/octopus/src/config.rs @@ -0,0 +1,17 @@ +//! Configuration to run octopus + +pub struct Config { + app_path: String, + port: u16, + handle_ssl: bool, + cache_path: String, + repos_path: String, + repo_discovery: bool, + repos: Vec +} + +pub struct RepoConfig { + name: String, + description: String, + category: String, +} diff --git a/apps/servers/octopus/src/git/log.rs b/apps/servers/octopus/src/git/log.rs new file mode 100644 index 00000000000..c8f4aa37ccf --- /dev/null +++ b/apps/servers/octopus/src/git/log.rs @@ -0,0 +1,117 @@ +//! libgit2 log parsing + +use crate::git::{tree::FileNode, Repo}; +use git2::Oid; +use std::collections::{BTreeMap, BTreeSet}; + +/// A file-commit referenced graph thing +/// +/// git is _weird_! It's essentially just a glorified key-value store +/// and it shows. There's no utilities to figure out how thing are +/// related, and all the actual graph things in git are sugar on top +/// of this store. +/// +/// In order to make sense of anything in a repo we need to quite +/// heavily parse the log. This type here is the result of this +/// parsing: you can ask it smart questions like "when did this file +/// change" and it will tell you (sort of). +#[derive(Debug, Default)] +pub(crate) struct CommitGraph { + /// The correct order of commits in the log + order: Vec, + /// List of all files, and the commits in which they were touched + file_refs: BTreeMap>, + /// Map of commit IDs to metadata + commit_refs: BTreeMap, +} + +#[derive(Debug)] +pub(crate) struct CommitNode { + id: String, + author: String, + message: String, + touches: BTreeSet, + time: i64, +} + +fn build_diff_log(repo: &Repo, log: Vec<(String, Vec)>) -> Vec { + todo!() +} + +/// Walk through all commits from a given ref and build a commit graph +pub(crate) fn create_commit_log(rev: String, repo: &Repo) -> CommitGraph { + let mut walker = repo.get_inner().revwalk().unwrap(); + walker.push(Oid::from_str(rev.as_str()).unwrap()).unwrap(); + let mut commits = walker + .into_iter() + .map(|oid| { + let oid = oid.unwrap(); + repo.get_inner().find_commit(oid).unwrap() + }) + .collect::>(); + commits.reverse(); + + let mut initial: Vec<(_, _)> = commits + .into_iter() + .map(|commit| { + let id = format!("{}", commit.id()); + (id.clone(), repo.get_tree(id.as_str())) + }) + .collect(); + + // split off rest of the diffs and dissolve the len(1) vec + let log = initial.split_off(1); + let previous = initial.remove(0).1; + + let mut order = vec![]; + let (commit_refs, file_refs) = log.into_iter().fold( + (BTreeMap::new(), BTreeMap::new()), + |(mut cm, mut fm), (cid, current)| { + let commit_id = format!("{}", cid); + + let d = repo + .get_inner() + .diff_tree_to_tree(Some(&previous), Some(¤t), None) + .unwrap(); + + // Store the commit to preserve order + order.push(commit_id.clone()); + + // For each file, store this commit as one that touched it + let touches = d.deltas().fold(BTreeSet::new(), |mut set, delta| { + let file_id = format!("{}", delta.new_file().id()); + fm.entry(file_id.clone()) + .or_insert(vec![]) + .push(commit_id.clone()); + set.insert(file_id); + set + }); + + // From the commit, build a metadata object + let commit_u = repo + .get_inner() + .find_commit(Oid::from_str(cid.as_str()).unwrap()) + .unwrap(); + let author_u = commit_u.author(); + let commit = CommitNode { + id: commit_id, + message: commit_u.message().unwrap().to_owned(), + author: format!("{} {}", author_u.name().unwrap(), author_u.email().unwrap()), + touches, + time: author_u.when().seconds(), + }; + + // Insert the metadata object + cm.insert(cid.clone(), commit); + + // We pass both the modified maps into the next commit + (cm, fm) + }, + ); + + CommitGraph { + order, + file_refs, + commit_refs, + } +} diff --git a/apps/servers/octopus/src/git/mod.rs b/apps/servers/octopus/src/git/mod.rs new file mode 100644 index 00000000000..244e2f45e6c --- /dev/null +++ b/apps/servers/octopus/src/git/mod.rs @@ -0,0 +1,58 @@ +//! Wrappers for libgit2 + +pub mod log; +pub mod tree; + +use git2::{self, Repository}; +use log::CommitGraph; +use tree::Tree; + +/// A top-level wrapper API for all libgit2 functions +pub struct Repo { + inner: Repository, + commits: Option, + rev: Option, +} + +impl Repo { + pub(crate) fn new(path: &str) -> Self { + Self { + inner: Repository::open(path).expect(&format!("`{}` is not a valid git repo", path)), + commits: None, + rev: None, + } + } + + pub(self) fn get_inner(&self) -> &Repository { + &self.inner + } + + pub(self) fn get_tree<'r>(&'r self, rev: &str) -> git2::Tree<'r> { + self.inner + .revparse_single(rev) + .unwrap() + .peel_to_tree() + .unwrap() + } + + pub(crate) fn clear_cache(&mut self) { + self.rev = None; + self.commits = None; + } + + /// Load and cache commits for a specific rev + pub(crate) fn load_commits(&mut self, rev: String) { + self.rev = Some(rev.clone()); + self.commits = Some(log::create_commit_log(rev, &self)); + } + + /// Load the tree of files for the current rev + /// + /// Will fail if no rev was previously cached + pub(crate) fn get_file_tree(&self) -> Tree { + tree::parse_tree( + self.get_tree(self.rev.as_ref().unwrap().as_str()), + self.get_inner(), + ) + } +} diff --git a/apps/servers/octopus/src/git/tree.rs b/apps/servers/octopus/src/git/tree.rs new file mode 100644 index 00000000000..5343a57c246 --- /dev/null +++ b/apps/servers/octopus/src/git/tree.rs @@ -0,0 +1,176 @@ +//! Tree handling utilities +//! +//! The way that libgit2 handles trees is super low-level and overkill +//! for what we need. In this module we knock it down a notch or two. +//! +//! This code takes a tree returned by +//! `crate::git::repo::Repo::get_tree()`, and transforms it into a +//! `TreeData` type that the template engine can render. + +use crate::templ_data::repo::{CommitData, FileData, TreeData}; +use git2::{self, ObjectType, TreeWalkMode}; +use std::collections::BTreeMap; + +/// A cache of a repository tree +#[derive(Default, Debug, Clone)] +pub(crate) struct Tree { + inner: BTreeMap, +} + +impl Tree { + /// Insert a node into a subtree with it's full path + fn insert_to_subtree(&mut self, mut path: Vec, name: String, node: TreeNode) { + // If we are given a path, resolve it first + let curr = if path.len() > 0 { + let rest = path.split_off(1); + let mut curr = self.inner.get_mut(&path[0]).unwrap(); + + for dir in rest { + match curr { + TreeNode::Dir(ref mut d) => { + curr = d.children.inner.get_mut(&dir).unwrap(); + } + _ => panic!("Not a tree!"), + } + } + + match curr { + TreeNode::Dir(ref mut d) => &mut d.children, + TreeNode::File(_) => panic!("Not a tree!"), + } + } else { + // If no path was given, we assume the root is meant + self + }; + + curr.inner.insert(name, node); + } + + /// Walk through the tree and only return filenode objects + pub(crate) fn flatten(&self) -> Vec { + self.inner.values().fold(vec![], |mut vec, node| { + match node { + TreeNode::File(f) => vec.push(f.clone()), + TreeNode::Dir(d) => vec.append(&mut d.children.flatten()), + } + + vec + }) + } + + /// Get all the commits that touch a file + pub(crate) fn grab_path_history(&self, mut path: String) -> String { + let mut path: Vec = path + .split("/") + .filter_map(|seg| match seg { + "" => None, + val => Some(val.into()), + }) + .collect(); + + let leaf = if path.len() > 0 { + let rest = path.split_off(1); + let mut curr = self.inner.get(&path[0]).unwrap(); + + for dir in rest { + match curr { + TreeNode::Dir(d) => curr = d.children.inner.get(&dir).unwrap(), + TreeNode::File(_) => break, // we reached the leaf + } + } + + curr + } else { + panic!("No valid path!"); + }; + + match leaf { + TreeNode::File(f) => f.id.clone(), + _ => panic!("Not a leaf!"), + } + } +} + +#[derive(Clone, Debug)] +pub(crate) enum TreeNode { + File(FileNode), + Dir(DirNode), +} + +impl TreeNode { + fn name(&self) -> String { + match self { + Self::File(f) => f.name.clone(), + Self::Dir(d) => d.name.clone(), + } + } +} + +#[derive(Clone, Debug)] +pub(crate) struct FileNode { + pub id: String, + pub path: Vec, + pub name: String, +} + +#[derive(Clone, Debug)] +pub(crate) struct DirNode { + pub path: Vec, + pub name: String, + pub children: Tree, +} + +impl DirNode { + fn append(&mut self, node: TreeNode) { + self.children.inner.insert(node.name(), node); + } +} + +/// Take a series of path-segments and render a tree at that location +pub(crate) fn parse_tree(tree: git2::Tree, repo: &git2::Repository) -> Tree { + let mut root = Tree::default(); + + tree.walk(TreeWalkMode::PreOrder, |path, entry| { + let path: Vec = path + .split("/") + .filter_map(|seg| match seg { + "" => None, + val => Some(val.into()), + }) + .collect(); + let name = entry.name().unwrap().to_string(); + + match entry.kind() { + // For every tree in the tree we create a new TreeNode with the path we know about + Some(ObjectType::Tree) => { + root.insert_to_subtree( + path.clone(), + name.clone(), + TreeNode::Dir(DirNode { + path, + name, + children: Tree::default(), + }), + ); + } + // If we encounter a blob, this is a file that we can simply insert into the tree + Some(ObjectType::Blob) => { + root.insert_to_subtree( + path.clone(), + name.clone(), + TreeNode::File(FileNode { + id: format!("{}", entry.id()), + path, + name, + }), + ); + } + _ => {} + } + + 0 + }) + .unwrap(); + + root +} diff --git a/apps/servers/octopus/src/main.rs b/apps/servers/octopus/src/main.rs new file mode 100644 index 00000000000..8ed6445dd4a --- /dev/null +++ b/apps/servers/octopus/src/main.rs @@ -0,0 +1,29 @@ +//mod git; +mod pages; +mod repo; +mod templ_data; + +mod project; + +use actix_files as fs; +use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer}; +use std::io; +use std::path::PathBuf; + +#[actix_rt::main] +async fn main() -> io::Result<()> { + std::env::set_var("RUST_LOG", "actix_server=info,octopus=debug"); + env_logger::init(); + let root = PathBuf::new(); + + HttpServer::new(move || { + App::new() + .service(fs::Files::new("/static", root.join("static"))) + .service(web::resource("/").route(web::get().to(pages::overview))) + .service(web::resource("/tree").route(web::get().to(pages::files))) + .default_service(web::resource("").route(web::get().to(pages::p404))) + }) + .bind("127.0.0.1:8080")? + .run() + .await +} diff --git a/apps/servers/octopus/src/pages/files.rs b/apps/servers/octopus/src/pages/files.rs new file mode 100644 index 00000000000..73a86a46918 --- /dev/null +++ b/apps/servers/octopus/src/pages/files.rs @@ -0,0 +1,20 @@ +//! The main file browser + +use crate::templ_data::{files::Files, BaseData}; +use actix_web::{web, HttpRequest, HttpResponse, Result}; +use askama::Template; + +pub async fn render(req: HttpRequest) -> Result { + let files = Files { + base: BaseData { + sitename: "dev.spacekookie.de".into(), + ..BaseData::default() + }, + readme: None, + path: "".into(), + } + .render() + .unwrap(); + + Ok(HttpResponse::Ok().content_type("text/html").body(files)) +} diff --git a/apps/servers/octopus/src/pages/mod.rs b/apps/servers/octopus/src/pages/mod.rs new file mode 100644 index 00000000000..2f1ed579c9a --- /dev/null +++ b/apps/servers/octopus/src/pages/mod.rs @@ -0,0 +1,15 @@ +//! All the pages in webgit +//! +//! A page is defined by it's template type as well as it's route, +//! which is exported from the module and then called by the router + +// pub mod repo; + +mod overview; +pub use overview::render as overview; + +mod p404; +pub use p404::render as p404; + +mod files; +pub use files::render as files; diff --git a/apps/servers/octopus/src/pages/overview.rs b/apps/servers/octopus/src/pages/overview.rs new file mode 100644 index 00000000000..ca8c9b37064 --- /dev/null +++ b/apps/servers/octopus/src/pages/overview.rs @@ -0,0 +1,24 @@ +//! Overview page +//! +//! This is the first page a user sees when they just go to the site +//! root. It renders the `README`, or `README.md` file from the modo +//! repo root, to provide users with a starting point. + +use crate::templ_data::{overview::Index, BaseData}; +use actix_web::{web, HttpRequest, HttpResponse, Result}; +use askama::Template; + +pub async fn render(req: HttpRequest) -> Result { + let readme: String = markdown::to_html(include_str!("../../fake-readme.md").into()); + + let index = Index { + base: BaseData { + sitename: "dev.spacekookie.de".into(), + ..BaseData::default() + }, + readme, + } + .render() + .unwrap(); + Ok(HttpResponse::Ok().content_type("text/html").body(index)) +} diff --git a/apps/servers/octopus/src/pages/p404.rs b/apps/servers/octopus/src/pages/p404.rs new file mode 100644 index 00000000000..6427a19c60b --- /dev/null +++ b/apps/servers/octopus/src/pages/p404.rs @@ -0,0 +1,13 @@ +use actix_web::{HttpResponse, Result}; +use askama::Template; + +#[derive(Template)] +#[template(path = "404.html")] +struct P404; + +/// Render a simple 404 page +pub async fn render() -> Result { + Ok(HttpResponse::NotFound() + .content_type("text/html") + .body(P404.render().unwrap())) +} diff --git a/apps/servers/octopus/src/pages/repo/about.rs b/apps/servers/octopus/src/pages/repo/about.rs new file mode 100644 index 00000000000..1f207e2d56a --- /dev/null +++ b/apps/servers/octopus/src/pages/repo/about.rs @@ -0,0 +1,26 @@ +use crate::templ_data::repo::*; +use actix_web::{web, HttpRequest, HttpResponse, Result}; +use askama::Template; + +/// Renders the "repository/about" subpage +pub async fn render(req: HttpRequest, path: web::Path) -> Result { + let repo = pages::About { + readme: include_str!("../../../README").to_string(), + repo: RepoData { + owner: "spacekookie".into(), + name: "octopus".into(), + tagline: "A lightweight web frontend for git repositories".into(), + num_commit: 141, + num_branch: 1, + num_tag: 0, + num_contributor: 3, + size: "13.12M".into(), + logo: "fakeavi.png".into(), + }, + base: Default::default(), + } + .render() + .unwrap(); + + Ok(HttpResponse::Ok().content_type("text/html").body(repo)) +} diff --git a/apps/servers/octopus/src/pages/repo/details.rs b/apps/servers/octopus/src/pages/repo/details.rs new file mode 100644 index 00000000000..7298e15af4b --- /dev/null +++ b/apps/servers/octopus/src/pages/repo/details.rs @@ -0,0 +1,38 @@ +use crate::templ_data::repo::*; +use actix_web::{web, HttpRequest, HttpResponse, Result}; +use askama::Template; + +/// Renders the "repository/about" subpage +pub async fn render(req: HttpRequest, path: web::Path) -> Result { + let last_commit = CommitData { + hash: "84a9a0".into(), + message: "Updating just like... a bunch of shit".into(), + author: "Katharina Fey".into(), + date: "Today".into(), + diff: (125, 55), + }; + + let repo = pages::Details { + branches: vec![BranchData { + name: "develop".into(), + last_commit: last_commit.clone(), + }], + commits: vec![last_commit], + repo: RepoData { + owner: "spacekookie".into(), + name: "octopus".into(), + tagline: "A lightweight web frontend for git repositories".into(), + num_commit: 141, + num_branch: 1, + num_tag: 0, + num_contributor: 3, + size: "13.12M".into(), + logo: "fakeavi.png".into(), + }, + base: Default::default(), + } + .render() + .unwrap(); + + Ok(HttpResponse::Ok().content_type("text/html").body(repo)) +} diff --git a/apps/servers/octopus/src/pages/repo/mod.rs b/apps/servers/octopus/src/pages/repo/mod.rs new file mode 100644 index 00000000000..2b93592624a --- /dev/null +++ b/apps/servers/octopus/src/pages/repo/mod.rs @@ -0,0 +1,7 @@ +//! The repository page subtree + +mod about; +mod details; + +pub use about::render as about; +pub use details::render as details; diff --git a/apps/servers/octopus/src/project/mod.rs b/apps/servers/octopus/src/project/mod.rs new file mode 100644 index 00000000000..cf81fd40687 --- /dev/null +++ b/apps/servers/octopus/src/project/mod.rs @@ -0,0 +1,8 @@ +//! Octopus project + +use std::{fs::File, path::PathBuf}; + +/// Check if a directory is a valid project +pub(crate) fn is_valid(p: PathBuf) -> bool { + p.join(".octopus").exists() +} diff --git a/apps/servers/octopus/src/repo.rs b/apps/servers/octopus/src/repo.rs new file mode 100644 index 00000000000..ca1f889027e --- /dev/null +++ b/apps/servers/octopus/src/repo.rs @@ -0,0 +1,43 @@ +use git2::{Commit, Error, Repository as Backend}; +use std::collections::HashSet; + +/// A structure that represents an existing bare repo on disk +pub struct Repository { + inner: Backend, +} + +impl Repository { + /// Open an existing bare repo from disk storage + pub fn open(path: &'static str) -> Self { + Self { + inner: Backend::open_bare(path).unwrap(), + } + } + + /// Get all commits on head + pub fn head<'a>(&'a self) -> Result>, Error> { + let mut walker = self.inner.revwalk().unwrap(); + walker.push_head()?; + walker + .into_iter() + .map(|oid| { + let oid = oid.unwrap(); + self.inner.find_commit(oid) + }) + .collect() + } + + /// Return the list of contributors + fn contributors(&self) -> Result, Error> { + let head = self.head()?; + Ok(head + .iter() + .map(|c| c.author()) + .fold(HashSet::new(), |mut set, author| { + set.insert(author.name().unwrap().to_owned()); + set + }) + .into_iter() + .collect()) + } +} diff --git a/apps/servers/octopus/src/state/mod.rs b/apps/servers/octopus/src/state/mod.rs new file mode 100644 index 00000000000..5e7f9276bd9 --- /dev/null +++ b/apps/servers/octopus/src/state/mod.rs @@ -0,0 +1,14 @@ +//! Core octopus state handling + +use std::sync::Arc; + +pub(crate) type StateRef = Arc; + +/// Holds all state handles for the application +pub(crate) struct OctoState {} + +impl OctoState { + pub(crate) fn new() -> StateRef { + Arc::new(Self {}) + } +} diff --git a/apps/servers/octopus/src/templ_data/files.rs b/apps/servers/octopus/src/templ_data/files.rs new file mode 100644 index 00000000000..27a5bde99e5 --- /dev/null +++ b/apps/servers/octopus/src/templ_data/files.rs @@ -0,0 +1,13 @@ +//! File browser template data + +use super::BaseData; +use askama::Template; + +// This struct needs escapng=none to render README files it encounters along the way +#[derive(Template)] +#[template(path = "files.html", escape = "none")] +pub(crate) struct Files { + pub base: BaseData, + pub path: String, + pub readme: Option, +} diff --git a/apps/servers/octopus/src/templ_data/mod.rs b/apps/servers/octopus/src/templ_data/mod.rs new file mode 100644 index 00000000000..7645e95ef82 --- /dev/null +++ b/apps/servers/octopus/src/templ_data/mod.rs @@ -0,0 +1,38 @@ +//! Octopus template data structures +//! +//! All pages are generated by the server via template files that have +//! data inputs. Because the templates follow a well-defined +//! structure (i.e. `core` extended by `/base` extended by +//! `/`, the structure of these template data structures +//! is the same. +//! +//! The actual page initialisation and rendering is nested in the +//! `page` module, which then uses the appropriate template structures +//! defined here. + +pub(crate) mod overview; +pub(crate) mod files; + +use std::env; + +/// A basic application wide template structure +pub(crate) struct BaseData { + pub version: String, + pub source: String, + pub siteurl: String, + pub sitename: String, + pub has_wiki: bool, +} + +impl Default for BaseData { + fn default() -> Self { + Self { + version: env!("CARGO_PKG_VERSION").into(), + source: env::var("_OCTOPUS_SOURCE") + .unwrap_or("https://dev.spacekookie.de/web/octopus".to_string()), + siteurl: env::var("_OCTOPUS_SITE_URL").unwrap_or("localhost:8080".to_string()), + sitename: env::var("_OCTOPUS_SITE_NAME").unwrap_or("test-octopus".to_string()), + has_wiki: true, + } + } +} diff --git a/apps/servers/octopus/src/templ_data/overview.rs b/apps/servers/octopus/src/templ_data/overview.rs new file mode 100644 index 00000000000..693db0a85e7 --- /dev/null +++ b/apps/servers/octopus/src/templ_data/overview.rs @@ -0,0 +1,11 @@ +//! Template data for the main overview + +use super::BaseData; +use askama::Template; + +#[derive(Template)] +#[template(path = "index.html", escape = "none")] +pub(crate) struct Index { + pub base: BaseData, + pub readme: String, +} diff --git a/apps/servers/octopus/src/templ_data/repo.rs b/apps/servers/octopus/src/templ_data/repo.rs new file mode 100644 index 00000000000..989c9b40462 --- /dev/null +++ b/apps/servers/octopus/src/templ_data/repo.rs @@ -0,0 +1,80 @@ +//! Repository specific template data + +use std::collections::BTreeMap; + +/// A simple overview of a repository +/// +/// This type can be generated by the octopus Repository state wrapper +#[derive(Clone)] +pub(crate) struct RepoData { + pub owner: String, + pub name: String, + pub tagline: String, + pub num_commit: usize, + pub num_branch: usize, + pub num_tag: usize, + pub num_contributor: usize, + pub size: String, + pub logo: String, +} + +/// Data about an individual commit +#[derive(Clone)] +pub(crate) struct CommitData { + pub hash: String, + pub message: String, + pub author: String, + pub date: String, + pub diff: (usize, usize), +} + +/// Data about a branch +#[derive(Clone)] +pub(crate) struct BranchData { + pub name: String, + pub last_commit: CommitData, +} + +/// Data about a repository tree +#[derive(Clone)] +pub(crate) struct TreeData { + /// The path segments in the current directory + curr_dir: Vec, + /// The set of children in this tree segment + files: BTreeMap, +} + +/// Information about a concrete file in a tree +#[derive(Clone)] +pub(crate) struct FileData { + name: String, + last_commit: CommitData, + is_directory: bool, +} + +pub(crate) mod pages { + use super::*; + use crate::templ_data::BaseData; + use askama::Template; + + #[derive(Template)] + #[template(path = "repo/about.html")] + pub(crate) struct About { + pub base: BaseData, + pub repo: RepoData, + + // Template specific + pub readme: String, + } + + #[derive(Template)] + #[template(path = "repo/details.html")] + pub(crate) struct Details { + pub base: BaseData, + pub repo: RepoData, + + // Template specifics + pub branches: Vec, + pub commits: Vec, + } +} diff --git a/apps/servers/octopus/static/fakeavi.png b/apps/servers/octopus/static/fakeavi.png new file mode 100644 index 0000000000000000000000000000000000000000..1538bb91f953147280bd78e2c4e4d70e6bcf800b GIT binary patch literal 29366 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 + + + + + image/svg+xml + + + + + + + + + diff --git a/apps/servers/octopus/static/rust.png b/apps/servers/octopus/static/rust.png new file mode 100644 index 0000000000000000000000000000000000000000..a706d7cd20fc8ce71489f34b50cf01011c104193 GIT binary patch literal 56915 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 literal 0 HcmV?d00001 diff --git a/apps/servers/octopus/supergit/Cargo.toml b/apps/servers/octopus/supergit/Cargo.toml new file mode 100644 index 00000000000..029503e87c4 --- /dev/null +++ b/apps/servers/octopus/supergit/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "supergit" +description = "A strongly typed, read-only representation of a git repository" +version = "0.1.0" +authors = ["Mx Kookie "] +edition = "2018" + +[dependencies] +git2 = "0.11" +async-std = { version = "1.0", features = ["unstable"] } \ No newline at end of file diff --git a/apps/servers/octopus/supergit/src/bin/test.rs b/apps/servers/octopus/supergit/src/bin/test.rs new file mode 100644 index 00000000000..166047e9dd1 --- /dev/null +++ b/apps/servers/octopus/supergit/src/bin/test.rs @@ -0,0 +1,16 @@ +//! A test binary to use during development + +use supergit::raw::RawRepository; + +fn main() { + let path = match std::env::args().nth(1) { + Some(p) => p, + None => { + eprintln!("USAGE: supergit-test "); + std::process::exit(2); + } + }; + + let rr = RawRepository::open(path.as_str()).unwrap(); + +} diff --git a/apps/servers/octopus/supergit/src/branch.rs b/apps/servers/octopus/supergit/src/branch.rs new file mode 100644 index 00000000000..81abbffed11 --- /dev/null +++ b/apps/servers/octopus/supergit/src/branch.rs @@ -0,0 +1,22 @@ +use crate::{Commit, CommitId}; + +/// Abstraction for a branch history slice +pub struct Branch { + name: String, + head: CommitId, + history: Vec, +} + +/// A commit represented as a relationship to a branch +/// +/// Most commits will be simple, meaning they are in sequence on the +/// branch. Two types of merge commits exist: normal, and octopus. +/// All branches leading into this branch are a reverse tree +pub enum BranchCommit { + /// A single commit + Commit(Commit), + /// A merge commit from one other branch + Merge(Branch), + /// An octopus merge with multiple branches + Octopus(Vec), +} diff --git a/apps/servers/octopus/supergit/src/commit.rs b/apps/servers/octopus/supergit/src/commit.rs new file mode 100644 index 00000000000..46a6ab4f7c8 --- /dev/null +++ b/apps/servers/octopus/supergit/src/commit.rs @@ -0,0 +1,11 @@ +pub type CommitId = usize; + +/// Represent a commit on a repository +/// +/// This abstraction only contains metadata required to fetch the full +/// commit from disk, if it is queried. Any operation on this type +/// will block to first load +pub struct Commit { + pub id: CommitId, + hash: String, +} diff --git a/apps/servers/octopus/supergit/src/diff.rs b/apps/servers/octopus/supergit/src/diff.rs new file mode 100644 index 00000000000..e92a4cd1804 --- /dev/null +++ b/apps/servers/octopus/supergit/src/diff.rs @@ -0,0 +1,5 @@ + +/// A diff between two commits +pub struct Diff { + +} diff --git a/apps/servers/octopus/supergit/src/files.rs b/apps/servers/octopus/supergit/src/files.rs new file mode 100644 index 00000000000..681b8877256 --- /dev/null +++ b/apps/servers/octopus/supergit/src/files.rs @@ -0,0 +1,7 @@ + +pub type FileId = usize; + +/// A file to have ever existed in a git repo +pub struct File { + id: FileId, +} diff --git a/apps/servers/octopus/supergit/src/lib.rs b/apps/servers/octopus/supergit/src/lib.rs new file mode 100644 index 00000000000..887ccc029e1 --- /dev/null +++ b/apps/servers/octopus/supergit/src/lib.rs @@ -0,0 +1,55 @@ +//! Strongly typed git repository explorer library +//! +//! This library exposes a read-only view into a git repository. To +//! get started, open an existing bare repo, and then call `sync()` to +//! build a cache of it. Every time you want your view of the repo to +//! update, call `sync()` again. If you want the sync operation to be +//! blocking, call `sync_blocking()` instead. +//! +//! + + +mod branch; +pub use branch::{Branch, BranchCommit}; + +mod commit; +pub use commit::{CommitId, Commit}; + +mod diff; +pub use diff::Diff; + +pub mod raw; + +use std::sync::atomic::{AtomicUsize, Ordering}; +use async_std::sync::{Arc, RwLock}; + +use raw::RawRepository; + +/// Represents a git repository with lazy data loading +pub struct Repository { + raw: RawRepository, +} + +impl Repository { + pub fn open(path: &std::path::Path) -> Arc { + todo!() + } + + /// Sync the repository with the backing git files + /// + /// This function can be invoked manually, but should be invoked + /// basically every time your program expects changes to have + /// happened. Polling this function is not recommended. + pub fn sync(&self) { + todo!() + } +} + +/////////// IDs are created from the same pool to save on code size //////////// + +const ID_CTR: AtomicUsize = AtomicUsize::new(0); + +/// Get monotonically increasing IDs for objects +pub(crate) fn id() -> usize { + ID_CTR.fetch_add(1, Ordering::Relaxed) +} diff --git a/apps/servers/octopus/supergit/src/raw/#tree_walk.rs# b/apps/servers/octopus/supergit/src/raw/#tree_walk.rs# new file mode 100644 index 00000000000..a693f624af4 --- /dev/null +++ b/apps/servers/octopus/supergit/src/raw/#tree_walk.rs# @@ -0,0 +1 @@ +//! Walk the file tree for a particular commit \ No newline at end of file diff --git a/apps/servers/octopus/supergit/src/raw/.#tree_walk.rs b/apps/servers/octopus/supergit/src/raw/.#tree_walk.rs new file mode 120000 index 00000000000..a0d26661593 --- /dev/null +++ b/apps/servers/octopus/supergit/src/raw/.#tree_walk.rs @@ -0,0 +1 @@ +spacekookie@qq.53166 \ No newline at end of file diff --git a/apps/servers/octopus/supergit/src/raw/branch_walk.rs b/apps/servers/octopus/supergit/src/raw/branch_walk.rs new file mode 100644 index 00000000000..d4232c48656 --- /dev/null +++ b/apps/servers/octopus/supergit/src/raw/branch_walk.rs @@ -0,0 +1,19 @@ +//! Walk along a branch parsing commit metadata + +use std::collections::{BTreeMap, BTreeSet}; + +pub struct CommitHistory { + /// The correct order of commit IDs + order: Vec, + /// Map of commit IDs to commit metadata + meta: BTreeMap, +} + +pub struct CommitNode { + id: String, + author: String, + commiter: String, + message: String, + touches: BTreeSet, + time: u64, +} diff --git a/apps/servers/octopus/supergit/src/raw/mod.rs b/apps/servers/octopus/supergit/src/raw/mod.rs new file mode 100644 index 00000000000..7bf6c0a396a --- /dev/null +++ b/apps/servers/octopus/supergit/src/raw/mod.rs @@ -0,0 +1,45 @@ +//! Raw representation wrappers for libgit2 + +mod branch_walk; +mod tree_walk; + +use crate::{Branch, BranchCommit}; +use git2::{self, Repository}; + +pub type RawResult = Result; + +/// An error abstraction for raw git operations +#[derive(Debug)] +pub enum RawError { + AllBad, +} + +impl From for RawError { + fn from(_: git2::Error) -> Self { + Self::AllBad + } +} + +/// Represent a raw branch +pub struct RawBranch { + name: String, + head: String, +} + +/// Wrap a libgit2 repository to provide an API fascade +pub struct RawRepository { + inner: Repository, +} + +impl RawRepository { + pub fn open(path: &str) -> RawResult { + Ok(Self { + inner: Repository::open(path)?, + }) + } + + /// Parse branch data from repository + pub fn parse_branches(&self) -> RawResult> { + todo!() + } +} diff --git a/apps/servers/octopus/supergit/src/raw/tree_walk.rs b/apps/servers/octopus/supergit/src/raw/tree_walk.rs new file mode 100644 index 00000000000..05337640cd1 --- /dev/null +++ b/apps/servers/octopus/supergit/src/raw/tree_walk.rs @@ -0,0 +1 @@ +//! Walk the file tree for a particular commit diff --git a/apps/servers/octopus/templates/404.html b/apps/servers/octopus/templates/404.html new file mode 100644 index 00000000000..02168e78d05 --- /dev/null +++ b/apps/servers/octopus/templates/404.html @@ -0,0 +1,11 @@ + + + + 404 - octopus + + + +

404

+

This ain't it chief

+ + diff --git a/apps/servers/octopus/templates/core.html b/apps/servers/octopus/templates/core.html new file mode 100644 index 00000000000..4112cc66943 --- /dev/null +++ b/apps/servers/octopus/templates/core.html @@ -0,0 +1,40 @@ + + + + + + + + + {% block title %}{% endblock %} + + + +
+ + +
+ + {# Limits the width #} +
+
+ {% block content %}{% endblock %} +
+ + + +
+ + diff --git a/apps/servers/octopus/templates/files.html b/apps/servers/octopus/templates/files.html new file mode 100644 index 00000000000..02b02018f68 --- /dev/null +++ b/apps/servers/octopus/templates/files.html @@ -0,0 +1,17 @@ +{% extends "core.html" %} + +{% block content %} + +

File Tree

+ +

Following is a copy of the file tree. You can clone any sub-directry that is marked as a "project".

+ +
+ + {# header section #} + +
+ +{% endblock %} diff --git a/apps/servers/octopus/templates/index.html b/apps/servers/octopus/templates/index.html new file mode 100644 index 00000000000..fd23cc2c311 --- /dev/null +++ b/apps/servers/octopus/templates/index.html @@ -0,0 +1,7 @@ +{% extends "core.html" %} + +{% block content %} + +{{ readme }} + +{% endblock %} diff --git a/apps/servers/octopus/templates/repo/about.html b/apps/servers/octopus/templates/repo/about.html new file mode 100644 index 00000000000..5c476aa79df --- /dev/null +++ b/apps/servers/octopus/templates/repo/about.html @@ -0,0 +1,6 @@ +{% extends "base.html" %} + +{% block child_content %} +
{{ readme }}
+{% endblock %} + diff --git a/apps/servers/octopus/templates/repo/base.html b/apps/servers/octopus/templates/repo/base.html new file mode 100644 index 00000000000..10994557285 --- /dev/null +++ b/apps/servers/octopus/templates/repo/base.html @@ -0,0 +1,37 @@ +{% extends "../core.html" %} +{% block title %}octopus | /{{ repo.owner }}/{{ repo.name }}{% endblock %} + +{% block content %} +
+ +

{{ repo.owner }} / {{ repo.name }}

+

🐙 It's a water animal

+
+ Clone + Star + RSS +
+
+ +
+ + +{% block child_content %}{% endblock %} + +{% endblock %} diff --git a/apps/servers/octopus/templates/repo/details.html b/apps/servers/octopus/templates/repo/details.html new file mode 100644 index 00000000000..46bf9b6461f --- /dev/null +++ b/apps/servers/octopus/templates/repo/details.html @@ -0,0 +1,49 @@ +{% extends "base.html" %} + +{% block child_content %} + + + + + + + + + + + {% for b in branches %} + + + + + + + {% endfor %} + +
BranchCommit messageAuthorDate
{{ b.name }}{{ b.last_commit.message }}{{ b.last_commit.author }}{{ b.last_commit.date }}
+ + + + + + + + + + + + + {% for c in commits %} + + + + + + + {% endfor %} + +
HashCommit messageAuthorDateLines
{{ c.hash }}{{ c.message }}{{ c.author }}{{ c.date }}+{{ c.diff.0 }}/ -{{ c.diff.1 }} +
+ + +{% endblock %}