Compare commits
263 Commits
Author | SHA1 | Date | |
---|---|---|---|
d27fc2352d
|
|||
5d7e5d219a
|
|||
3ca483e2ee | |||
f670505a1b | |||
ba4574a66d | |||
06dc3a73d3 | |||
36711cbf8f | |||
6c3d6c0bfa | |||
a23d4e5192 | |||
f40d35270f | |||
8d6e60fb40 | |||
144c980e89 | |||
7e30e49240
|
|||
06ce86b4ec | |||
05b9804c86 | |||
881e09194c | |||
52764a906a | |||
f66920bda5 | |||
6186f27ea2 | |||
8250c3de35 | |||
98e9c19ace | |||
7451a2e571 | |||
51cb97c103 | |||
63967c79b9 | |||
a555e8ed48 | |||
ab32765efa | |||
938aa648e8 | |||
0b37d01594 | |||
aa8d3a0f26 | |||
aea1768f52 | |||
f5f328acf1 | |||
689ec4fe95 | |||
73db3915b3 | |||
0e4ee009c9 | |||
35d5c8531e | |||
e3bcf4f4ca | |||
a6f33097d3 | |||
4b9a0f95e3 | |||
1f340728a1 | |||
16079253b8 | |||
cb97f0feee | |||
366b3496f2 | |||
a73f07e491 | |||
4ddaa84e5f | |||
74a9f74455 | |||
fca16947f6 | |||
83a4cb57d8
|
|||
9aa9b5359a | |||
00ee175e8b
|
|||
c0bafa6079 | |||
18fb75e13e | |||
9a578565bd | |||
ffb7acc738 | |||
8b058d9c53 | |||
30906da803 | |||
665db0b8c5 | |||
558137e2ee | |||
4708c19eb1 | |||
0e12778ea3
|
|||
fe2fc171ce | |||
061d7f8e07 | |||
cd5eaeefbf | |||
a0e4e5be88 | |||
f179bd875e
|
|||
7445bdd29d | |||
44a40cb086 | |||
2c23df798f
|
|||
3c5c206f9b
|
|||
c03d297b6b | |||
ca640fc6ad
|
|||
6c2e158310 | |||
68bc22e990 | |||
c1bf500c9b
|
|||
d21bcd7946 | |||
51ff4c2ebb | |||
862e928262 | |||
fb149da06c | |||
872a81d6c2 | |||
20828c7db4
|
|||
a88600f02a | |||
b392a05b42 | |||
52fea6787b
|
|||
713b0487fc | |||
8d7c769d84 | |||
566fcf181b
|
|||
2d9c2b7097 | |||
b7237a6a16 | |||
0a2d77920e | |||
6198dcf26d | |||
51236eee78 | |||
3db8f6830b | |||
8b19bdc0ae | |||
eab043194a | |||
13b3611a65
|
|||
0d7f435d49
|
|||
eec82fa04a | |||
c2cf11d794
|
|||
f5f9a4a0d3 | |||
554f0d21cf
|
|||
db78428191 | |||
22bc5496f1 | |||
3bb1784e52
|
|||
6a5dec8cb7 | |||
41a0d64b65 | |||
a5249e2a64
|
|||
f053c6bbf7 | |||
dd16ed862b | |||
65dc0205d0
|
|||
0100b754f4
|
|||
8d90ffff1e | |||
2bec463cbe | |||
e49135f128 | |||
f00b20dd19 | |||
d98bfcd55a | |||
ea96746a54 | |||
08ff91324c | |||
30e97ddc51 | |||
6d4ec8f546 | |||
499362cbce | |||
51ba8c19b4 | |||
33d1eb784e | |||
111a9720d6 | |||
e9c8612f62 | |||
f6b48c6ac6 | |||
afc357c025 | |||
7aec5d5045 | |||
502dda0b6e | |||
40831cfa57 | |||
b841816173 | |||
6e38e92f52 | |||
fa323161e5 | |||
4697035936 | |||
19b7ae0e6b | |||
ecf052c73b | |||
7d297fc456 | |||
a2a8261095 | |||
8aac012161 | |||
c05843f07a | |||
9df487ef1b | |||
5d4c82065e | |||
b6164cbc08 | |||
f5c06b1546 | |||
7beddf2ccc | |||
6ccb548f21 | |||
dc8afc0a52 | |||
f723158edc | |||
af7163711d | |||
0e6224dd7b | |||
d257ddd7fd | |||
d3dce34d13 | |||
24b9f06aad | |||
a008055c33 | |||
b403155c86 | |||
791a160964 | |||
e59041d246 | |||
c8a66ae37c | |||
b0e3bacc33 | |||
2dce1ba01d | |||
68831446d5 | |||
b8e903766c | |||
156f484b87 | |||
1b9e04f41b | |||
ebc5c26a6f | |||
d5e30ba727 | |||
cdbf3e5c06 | |||
4012e835a6 | |||
481f4d5e3d | |||
4df06b344c | |||
47b6b27e59 | |||
21cb4d15a5 | |||
c68b5812c2 | |||
c4f852f9d4 | |||
f104bf9ce6 | |||
e2a4d41633 | |||
8fec5b457f | |||
3eaba6b87c | |||
6ca1eafe60 | |||
66fa759bb6 | |||
84439d2d71 | |||
bed16ef4fb | |||
e10e9250a1 | |||
e9accd6be8 | |||
218f55237a | |||
f679eaa1cd | |||
fc668d961a | |||
b4aaa0bcf5 | |||
4a94af0f75 | |||
41205a4404 | |||
9c7f7a3bdf | |||
db510c709f | |||
c6319dd5eb | |||
42c094a7d7 | |||
330c21b12c | |||
9a0d8dfc37 | |||
633873814b | |||
95c54b95c1 | |||
a68a49f6ae | |||
6c7cb9df97 | |||
0a4ec4ecd4 | |||
3ead212fe7 | |||
b001db6558 | |||
5543301140 | |||
028795effa | |||
23303d818a | |||
886caeca1c | |||
6fbd437f34 | |||
13095b0445 | |||
6c8a635e12 | |||
d0ea0c8a68 | |||
6bd843d9b8 | |||
f4206140b3 | |||
7139663544 | |||
0c9ef2abd2 | |||
391bb6faeb | |||
d4248df45a | |||
4b5d962c2c | |||
c93c83f004 | |||
dbbbdad3fa | |||
e82037c23b | |||
ecbc63f522 | |||
315eb514f4 | |||
9139c8f005 | |||
96ded8a0a8 | |||
15692cbb08 | |||
98d80faf3a | |||
a0cb623dc6 | |||
28582e58e0 | |||
e79e1e2634 | |||
097a1affcf | |||
df022f538c | |||
b4327ff28f | |||
38a837bc70 | |||
743fe98d1b | |||
d0e2f21339 | |||
ebe844d305 | |||
c0119ccc97 | |||
6ae96e9b33 | |||
85bd714eb8 | |||
4d63a3cb0b | |||
5d7d06abef | |||
a84885a2ca | |||
ee1de29158 | |||
e48279c6d8 | |||
3df296e542 | |||
a65f8d9d72 | |||
ec04b0a76f | |||
5387265a3e | |||
0379d4bfc0 | |||
7e1b86ace1 | |||
f000dbd27c | |||
3fd245da4a | |||
6f292796a4 | |||
95bc3491ec | |||
9b961032aa | |||
32a2cc7132 | |||
aeb1293067 | |||
fd70162033 | |||
fa93e0e8b7 | |||
33b215f1e5 | |||
4029216a18 | |||
c67fcd84ca | |||
f6492890ae | |||
901b492641 |
18
.github/dependabot.yml
vendored
18
.github/dependabot.yml
vendored
@ -1,10 +1,12 @@
|
|||||||
version: 2
|
version: 2
|
||||||
updates:
|
updates:
|
||||||
- package-ecosystem: cargo
|
- package-ecosystem: cargo
|
||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: daily
|
interval: daily
|
||||||
time: "04:00"
|
time: "04:00"
|
||||||
open-pull-requests-limit: 10
|
open-pull-requests-limit: 10
|
||||||
assignees:
|
assignees:
|
||||||
- vbrandl
|
- vbrandl
|
||||||
|
labels:
|
||||||
|
- dependencies
|
||||||
|
17
.github/workflows/audit.yml
vendored
17
.github/workflows/audit.yml
vendored
@ -3,26 +3,19 @@ on:
|
|||||||
schedule:
|
schedule:
|
||||||
- cron: '0 1 * * *'
|
- cron: '0 1 * * *'
|
||||||
push:
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- '**/Cargo.toml'
|
- '**/Cargo.toml'
|
||||||
- '**/Cargo.lock'
|
- '**/Cargo.lock'
|
||||||
pull_request:
|
- ".cargo/audit.toml"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
security_audit:
|
security_audit:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Cache cargo registry, index and build directory
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
~/.cargo/registry
|
|
||||||
~/.cargo/git
|
|
||||||
./target
|
|
||||||
key: audit-${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
|
||||||
|
|
||||||
- uses: actions-rs/audit-check@v1
|
- uses: actions-rs/audit-check@v1
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
19
.github/workflows/release.yml
vendored
19
.github/workflows/release.yml
vendored
@ -6,8 +6,12 @@ on:
|
|||||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
tests:
|
||||||
|
uses: vbrandl/hoc/.github/workflows/rust.yml@master
|
||||||
|
|
||||||
publish:
|
publish:
|
||||||
name: Publishing for ${{ matrix.os }}
|
name: Publishing for ${{ matrix.os }}
|
||||||
|
needs: [tests]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@ -29,7 +33,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Install stable toolchain
|
- name: Install stable toolchain
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@ -44,7 +48,7 @@ jobs:
|
|||||||
~/.cargo/registry
|
~/.cargo/registry
|
||||||
~/.cargo/git
|
~/.cargo/git
|
||||||
./target
|
./target
|
||||||
key: release-${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
- name: Cargo build
|
- name: Cargo build
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
@ -74,3 +78,14 @@ jobs:
|
|||||||
target/${{ matrix.target }}/release/hoc-${{ matrix.artifact_prefix }}.sha256
|
target/${{ matrix.target }}/release/hoc-${{ matrix.artifact_prefix }}.sha256
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
changelog:
|
||||||
|
name: Update Changelog
|
||||||
|
needs: [tests]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: taiki-e/create-gh-release-action@v1
|
||||||
|
with:
|
||||||
|
changelog: CHANGELOG.md
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
33
.github/workflows/rust.yml
vendored
33
.github/workflows/rust.yml
vendored
@ -1,13 +1,19 @@
|
|||||||
on: [push, pull_request]
|
on:
|
||||||
|
workflow_call:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 0 * * *"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
rustfmt:
|
rustfmt:
|
||||||
name: Rustfmt
|
name: Rustfmt
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Install stable toolchain
|
- name: Install stable toolchain
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@ -17,15 +23,6 @@ jobs:
|
|||||||
override: true
|
override: true
|
||||||
components: rustfmt
|
components: rustfmt
|
||||||
|
|
||||||
- name: Cache cargo registry, index and build directory
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
~/.cargo/registry
|
|
||||||
~/.cargo/git
|
|
||||||
./target
|
|
||||||
key: rustfmt-${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
|
||||||
|
|
||||||
- name: Check Formatting
|
- name: Check Formatting
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
@ -37,7 +34,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Install stable toolchain
|
- name: Install stable toolchain
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@ -48,13 +45,13 @@ jobs:
|
|||||||
components: rustfmt
|
components: rustfmt
|
||||||
|
|
||||||
- name: Cache cargo registry, index and build directory
|
- name: Cache cargo registry, index and build directory
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cargo/registry
|
~/.cargo/registry
|
||||||
~/.cargo/git
|
~/.cargo/git
|
||||||
./target
|
./target
|
||||||
key: clippy-${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
- name: Clippy Linting
|
- name: Clippy Linting
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
@ -74,7 +71,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Install stable toolchain
|
- name: Install stable toolchain
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@ -84,13 +81,13 @@ jobs:
|
|||||||
override: true
|
override: true
|
||||||
|
|
||||||
- name: Cache cargo registry, index and build directory
|
- name: Cache cargo registry, index and build directory
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cargo/registry
|
~/.cargo/registry
|
||||||
~/.cargo/git
|
~/.cargo/git
|
||||||
./target
|
./target
|
||||||
key: test-${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
- name: Run Tests
|
- name: Run Tests
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
|
145
CHANGELOG.md
Normal file
145
CHANGELOG.md
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
|
||||||
|
## [0.31.0] 2023-02-13
|
||||||
|
|
||||||
|
### Dependency Updates
|
||||||
|
|
||||||
|
* Updated [`tokio`](https://github.com/tokio-rs/tokio) from 1.24.1 to 1.24.2 ([#547])
|
||||||
|
* Updated [`badgers`](https://github.com/vbrandl/badgers) from 1.1.0 to 1.2.0 ([#548])
|
||||||
|
* Updated [`reqwest`](https://github.com/seanmonstar/reqwest) from 0.11.13 to 0.11.14 ([#549])
|
||||||
|
* Updated [`bumpalo`](https://github.com/fitzgen/bumpalo) from 3.10.0 to 3.12.0 ([#550])
|
||||||
|
* Updated [`libgit2-sys`](https://github.com/rust-lang/git2-rs) from 0.14.1+1.5.0 to 0.14.2+1.5.1 ([#551])
|
||||||
|
* Updated [`git2`](https://github.com/rust-lang/git2-rs) from 0.16.0 to 0.16.1 ([#552])
|
||||||
|
* Updated [`actix-rt`](https://github.com/actix/actix-net) from 2.7.0 to 2.8.0 ([#553])
|
||||||
|
* Updated [`actix-web`](https://github.com/actix/actix-web) from 4.2.1 to 4.3.0 ([#554])
|
||||||
|
* Updated [`awc`](https://github.com/actix/actix-web) from 3.0.1 to 3.1.0 ([#555])
|
||||||
|
* Updated [`tokio`](https://github.com/tokio-rs/tokio) from 1.24.2 to 1.25.0 ([#558])
|
||||||
|
* Updated [`ructe`](https://github.com/kaj/ructe) from 0.15.0 to 0.16.1 ([#559])
|
||||||
|
* Updated [`futures`](https://github.com/rust-lang/futures-rs) from 0.3.25 to 0.3.26 ([#560])
|
||||||
|
* Updated [`bytes`](https://github.com/tokio-rs/bytes) from 1.3.0 to 1.4.0 ([#561])
|
||||||
|
* Updated [`serde_json`](https://github.com/serde-rs/json) from 1.0.91 to 1.0.92 ([#562])
|
||||||
|
* Updated [`vergen`](https://github.com/rustyhorde/vergen) from 7.5.0 to 7.5.1 ([#563])
|
||||||
|
* Updated [`serde_json`](https://github.com/serde-rs/json) from 1.0.92 to 1.0.93 ([#564])
|
||||||
|
|
||||||
|
[#547]: https://github.com/vbrandl/hoc/pull/547
|
||||||
|
[#548]: https://github.com/vbrandl/hoc/pull/548
|
||||||
|
[#550]: https://github.com/vbrandl/hoc/pull/550
|
||||||
|
[#551]: https://github.com/vbrandl/hoc/pull/551
|
||||||
|
[#552]: https://github.com/vbrandl/hoc/pull/552
|
||||||
|
[#553]: https://github.com/vbrandl/hoc/pull/553
|
||||||
|
[#554]: https://github.com/vbrandl/hoc/pull/554
|
||||||
|
[#555]: https://github.com/vbrandl/hoc/pull/555
|
||||||
|
[#558]: https://github.com/vbrandl/hoc/pull/558
|
||||||
|
[#559]: https://github.com/vbrandl/hoc/pull/559
|
||||||
|
[#560]: https://github.com/vbrandl/hoc/pull/560
|
||||||
|
[#561]: https://github.com/vbrandl/hoc/pull/561
|
||||||
|
[#562]: https://github.com/vbrandl/hoc/pull/562
|
||||||
|
[#563]: https://github.com/vbrandl/hoc/pull/563
|
||||||
|
[#564]: https://github.com/vbrandl/hoc/pull/564
|
||||||
|
|
||||||
|
|
||||||
|
## [0.30.0] 2023-01-16
|
||||||
|
|
||||||
|
### New Features
|
||||||
|
|
||||||
|
* Allow customization of the badge label ([#546])
|
||||||
|
|
||||||
|
### Dependency Updates
|
||||||
|
|
||||||
|
* Updated [`tracing-actix-web`](https://github.com/LukeMathWalker/tracing-actix-web) from 0.7.1 to 0.7.2 ([#542])
|
||||||
|
* Updated [`git2`](https://github.com/rust-lang/git2-rs) from 0.15.0 to 0.16.0 ([#544])
|
||||||
|
|
||||||
|
|
||||||
|
[#542]: https://github.com/vbrandl/hoc/pull/542
|
||||||
|
[#544]: https://github.com/vbrandl/hoc/pull/544
|
||||||
|
[#546]: https://github.com/vbrandl/hoc/pull/546
|
||||||
|
|
||||||
|
## [0.29.0] 2023-01-07
|
||||||
|
|
||||||
|
### Dependency Updates
|
||||||
|
|
||||||
|
* Updated [`badgers`](https://github.com/vbrandl/badgers) from 1.0.0 to 1.1.0 ([#530])
|
||||||
|
* Updated [`serde_json`](https://github.com/serde-rs/json) from 1.0.90 to 1.0.91 ([#531])
|
||||||
|
* Updated [`vergen`](https://github.com/rustyhorde/vergen) from 7.3.1 to 7.4.4 ([#533])
|
||||||
|
* Updated [`tracing-actix-web`](https://github.com/LukeMathWalker/tracing-actix-web) from 0.6.2 to 0.7.1 ([#534])
|
||||||
|
* Updated [`serde`](https://github.com/serde-rs/serde) from 1.0.151 to 1.0.152 ([#535])
|
||||||
|
* Updated [`tokio`](https://github.com/tokio-rs/tokio) from 1.23.0 to 1.23.1 ([#536])
|
||||||
|
* Updated [`vergen`](https://github.com/rustyhorde/vergen) from 7.4.4 to 7.5.0 ([#537])
|
||||||
|
* Updated [`tokio`](https://github.com/tokio-rs/tokio) from 1.23.1 to 1.24.1 ([#539])
|
||||||
|
|
||||||
|
[#530]: https://github.com/vbrandl/hoc/pull/530
|
||||||
|
[#531]: https://github.com/vbrandl/hoc/pull/531
|
||||||
|
[#533]: https://github.com/vbrandl/hoc/pull/533
|
||||||
|
[#534]: https://github.com/vbrandl/hoc/pull/534
|
||||||
|
[#535]: https://github.com/vbrandl/hoc/pull/535
|
||||||
|
[#536]: https://github.com/vbrandl/hoc/pull/536
|
||||||
|
[#537]: https://github.com/vbrandl/hoc/pull/537
|
||||||
|
[#539]: https://github.com/vbrandl/hoc/pull/539
|
||||||
|
|
||||||
|
## [0.28.0] 2022-12-18
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fixed clippy lint `needless_borrow` ([#526])
|
||||||
|
|
||||||
|
### Dependency Updates
|
||||||
|
|
||||||
|
* Updated [`bytes`](https://github.com/tokio-rs/bytes) from 1.2.1 to 1.3.0 ([#519])
|
||||||
|
* Updated [`config`](https://github.com/mehcode/config-rs) from 0.13.2 to 0.13.3 ([#522])
|
||||||
|
* Updated [`serde_json`](https://github.com/serde-rs/json) from 1.0.88 to 1.0.90 ([#527])
|
||||||
|
* Updated [`serde`](https://github.com/serde-rs/serde) from 1.0.147 to 1.0.151 ([#528])
|
||||||
|
|
||||||
|
[#519]: https://github.com/vbrandl/hoc/pull/519
|
||||||
|
[#522]: https://github.com/vbrandl/hoc/pull/522
|
||||||
|
[#526]: https://github.com/vbrandl/hoc/pull/526
|
||||||
|
[#527]: https://github.com/vbrandl/hoc/pull/527
|
||||||
|
[#528]: https://github.com/vbrandl/hoc/pull/528
|
||||||
|
|
||||||
|
## [0.27.0] 2022-10-21
|
||||||
|
|
||||||
|
### Dependency Updates
|
||||||
|
|
||||||
|
* Updated [`futures`](https://github.com/rust-lang/futures-rs) from 0.3.24 to 0.3.25 ([#511])
|
||||||
|
* Updated [`serde_json`](https://github.com/serde-rs/json) from 1.0.86 to 1.0.87 ([#510])
|
||||||
|
* Updated [`serde`](https://github.com/serde-rs/serde) from 1.0.145 to 1.0.147 ([#512])
|
||||||
|
* Updated [`tracing-actix-web`](https://github.com/LukeMathWalker/tracing-actix-web) from 0.6.1 to 0.6.2 ([#513])
|
||||||
|
* Updated [`reqwest`](https://github.com/seanmonstar/reqwest) from 0.11.12 to 0.11.13 ([#515])
|
||||||
|
* Updated [`tokio`](https://github.com/tokio-rs/tokio) from 1.21.2 to 1.22.0 ([#516])
|
||||||
|
* Updated [`serde_json`](https://github.com/serde-rs/json) from 1.0.87 to 1.0.88 ([#517])
|
||||||
|
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix clippy lint `needless-borrow` ([#514])
|
||||||
|
|
||||||
|
[#511]: https://github.com/vbrandl/hoc/pull/511
|
||||||
|
[#510]: https://github.com/vbrandl/hoc/pull/510
|
||||||
|
[#512]: https://github.com/vbrandl/hoc/pull/512
|
||||||
|
[#513]: https://github.com/vbrandl/hoc/pull/513
|
||||||
|
[#514]: https://github.com/vbrandl/hoc/pull/514
|
||||||
|
[#515]: https://github.com/vbrandl/hoc/pull/515
|
||||||
|
[#516]: https://github.com/vbrandl/hoc/pull/516
|
||||||
|
[#517]: https://github.com/vbrandl/hoc/pull/517
|
||||||
|
|
||||||
|
|
||||||
|
## [0.26.0] 2022-10-03
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* Updated [`tracing-subscriber`](https://github.com/tokio-rs/tracing) from 0.3.15 to 0.3.16 ([#501])
|
||||||
|
* Updated [`tracing`](https://github.com/tokio-rs/tracing) from 0.1.36 to 0.1.37 ([#502])
|
||||||
|
* Updated [`serde_json`](https://github.com/serde-rs/json) from 1.0.85 to 1.0.86 ([#503])
|
||||||
|
* Updated [`tracing-bunyan-formatter`](https://github.com/LukeMathWalker/tracing-bunyan-formatter) from 0.3.3 to 0.3.4 ([#504])
|
||||||
|
* Updated [`dotenvy`](https://github.com/allan2/dotenvy) from 0.15.5 to 0.15.6 ([#508])
|
||||||
|
|
||||||
|
[#501]: https://github.com/vbrandl/hoc/pull/501
|
||||||
|
[#502]: https://github.com/vbrandl/hoc/pull/502
|
||||||
|
[#503]: https://github.com/vbrandl/hoc/pull/503
|
||||||
|
[#504]: https://github.com/vbrandl/hoc/pull/504
|
||||||
|
[#508]: https://github.com/vbrandl/hoc/pull/508
|
771
Cargo.lock
generated
771
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
45
Cargo.toml
45
Cargo.toml
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "hoc"
|
name = "hoc"
|
||||||
version = "0.22.3"
|
version = "0.31.0"
|
||||||
authors = ["Valentin Brandl <vbrandl@riseup.net>"]
|
authors = ["Valentin Brandl <vbrandl@riseup.net>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
@ -13,34 +13,35 @@ path = "src/main.rs"
|
|||||||
name = "hoc"
|
name = "hoc"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-rt = "2.7.0"
|
actix-rt = "2.8.0"
|
||||||
actix-web = "4.0.1"
|
actix-web = "4.3.0"
|
||||||
badge = "0.3.0"
|
badgers = "1.2.0"
|
||||||
bytes = "1.1.0"
|
bytes = "1.4.0"
|
||||||
config = { version = "0.13.1", features = ["toml"] }
|
config = { version = "0.13.3", features = ["toml"] }
|
||||||
dotenv = "0.15.0"
|
dotenvy = "0.15.6"
|
||||||
futures = "0.3.21"
|
futures = "0.3.26"
|
||||||
git2 = "0.14.4"
|
git2 = "0.16.1"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
|
mime = "0.3"
|
||||||
number_prefix = "0.4.0"
|
number_prefix = "0.4.0"
|
||||||
openssl-probe = "0.1.5"
|
openssl-probe = "0.1.5"
|
||||||
reqwest = "0.11.10"
|
reqwest = "0.11.14"
|
||||||
serde = "1.0.137"
|
serde = "1.0.152"
|
||||||
serde_derive = "1.0.136"
|
serde_derive = "1.0.137"
|
||||||
serde_json = "1.0.81"
|
serde_json = "1.0.93"
|
||||||
tracing = "0.1.34"
|
tracing = "0.1.37"
|
||||||
tracing-actix-web = "0.5.1"
|
tracing-actix-web = "0.7.2"
|
||||||
tracing-bunyan-formatter = "0.3.2"
|
tracing-bunyan-formatter = "0.3.6"
|
||||||
tracing-futures = "0.2.5"
|
tracing-futures = "0.2.5"
|
||||||
tracing-log = "0.1.3"
|
tracing-log = "0.1.3"
|
||||||
tracing-subscriber = { version = "0.3.11", features = ["registry", "env-filter"] }
|
tracing-subscriber = { version = "0.3.16", features = ["registry", "env-filter"] }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
ructe = "0.14.0"
|
ructe = { version = "0.16.1", features = ["mime03"] }
|
||||||
vergen = { version = "7.2.0", default-features = false, features = ["git"] }
|
vergen = { version = "7.5.1", default-features = false, features = ["git"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
awc = "3.0.0"
|
awc = "3.1.0"
|
||||||
ructe = "0.14.0"
|
ructe = "0.16.1"
|
||||||
tempfile = "3.3.0"
|
tempfile = "3.3.0"
|
||||||
tokio = "1.18.2"
|
tokio = "1.25.0"
|
||||||
|
12
Dockerfile
12
Dockerfile
@ -1,10 +1,13 @@
|
|||||||
FROM ekidd/rust-musl-builder:stable as builder
|
# FROM ekidd/rust-musl-builder:stable as builder
|
||||||
|
FROM clux/muslrust:stable as builder
|
||||||
|
|
||||||
# create new cargo project
|
# create new cargo project
|
||||||
RUN USER=rust cargo init --lib
|
RUN cargo init --lib
|
||||||
|
# RUN USER=rust cargo init --lib
|
||||||
RUN echo 'fn main() { println!("Hello, world!"); }' >> src/main.rs
|
RUN echo 'fn main() { println!("Hello, world!"); }' >> src/main.rs
|
||||||
# copy build config
|
# copy build config
|
||||||
COPY --chown=rust ./Cargo.lock ./Cargo.lock
|
# COPY --chown=rust ./Cargo.lock ./Cargo.lock
|
||||||
|
COPY ./Cargo.lock ./Cargo.lock
|
||||||
COPY ./Cargo.toml ./Cargo.toml
|
COPY ./Cargo.toml ./Cargo.toml
|
||||||
# HACK: remove build-dependencies so we have at least some caching
|
# HACK: remove build-dependencies so we have at least some caching
|
||||||
RUN head -n $(($(grep -n "\[build-dependencies\]" Cargo.toml | cut -f1 -d:) - 1)) Cargo.toml | sed '/build.rs/d' > \
|
RUN head -n $(($(grep -n "\[build-dependencies\]" Cargo.toml | cut -f1 -d:) - 1)) Cargo.toml | sed '/build.rs/d' > \
|
||||||
@ -38,6 +41,7 @@ USER hoc
|
|||||||
# FROM scratch
|
# FROM scratch
|
||||||
# COPY --from=linuxkit/ca-certificates:v0.7 / /
|
# COPY --from=linuxkit/ca-certificates:v0.7 / /
|
||||||
|
|
||||||
COPY --from=builder /home/rust/src/target/x86_64-unknown-linux-musl/release/hoc .
|
# COPY --from=builder /home/rust/src/target/x86_64-unknown-linux-musl/release/hoc .
|
||||||
|
COPY --from=builder /volume/target/x86_64-unknown-linux-musl/release/hoc .
|
||||||
|
|
||||||
ENTRYPOINT ["/home/hoc/hoc"]
|
ENTRYPOINT ["/home/hoc/hoc"]
|
||||||
|
5
build.rs
5
build.rs
@ -8,5 +8,8 @@ fn main() -> Result<(), RucteError> {
|
|||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
*config.git_mut().sha_kind_mut() = ShaKind::Short;
|
*config.git_mut().sha_kind_mut() = ShaKind::Short;
|
||||||
vergen(config).expect("Unable to generate static repo info");
|
vergen(config).expect("Unable to generate static repo info");
|
||||||
Ructe::from_env()?.compile_templates("templates")
|
let mut ructe = Ructe::from_env()?;
|
||||||
|
let mut statics = ructe.statics()?;
|
||||||
|
statics.add_files("static")?;
|
||||||
|
ructe.compile_templates("templates")
|
||||||
}
|
}
|
||||||
|
37
src/count.rs
37
src/count.rs
@ -1,27 +1,30 @@
|
|||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
use std::{fs::read_dir, path::Path, result::Result as StdResult};
|
use std::{
|
||||||
|
fs::{read_dir, ReadDir},
|
||||||
|
iter::once,
|
||||||
|
path::Path,
|
||||||
|
result::Result as StdResult,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The on disk layout for served repos is `<service>/<user>/<repo>`
|
||||||
|
/// so to get the amount of repos, we just have to count everything
|
||||||
|
/// in `*/*/*` to get the count.
|
||||||
#[instrument]
|
#[instrument]
|
||||||
pub(crate) fn count_repositories<P>(repo_path: P) -> Result<usize>
|
pub fn count_repositories<P>(repo_path: P) -> Result<usize>
|
||||||
where
|
where
|
||||||
P: AsRef<Path> + std::fmt::Debug,
|
P: AsRef<Path> + std::fmt::Debug,
|
||||||
{
|
{
|
||||||
trace!("Counting repositories");
|
trace!("Counting repositories");
|
||||||
std::fs::create_dir_all(&repo_path)?;
|
std::fs::create_dir_all(&repo_path)?;
|
||||||
Ok(read_dir(repo_path)?
|
Ok(once(read_dir(repo_path)?)
|
||||||
.filter_map(StdResult::ok)
|
.flat_map(sub_directories)
|
||||||
.filter(|entry| entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false))
|
.flat_map(sub_directories)
|
||||||
.map(|entry| read_dir(entry.path()))
|
.flat_map(sub_directories)
|
||||||
.filter_map(StdResult::ok)
|
|
||||||
.flat_map(|dir| {
|
|
||||||
dir.filter_map(StdResult::ok)
|
|
||||||
.filter(|entry| entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false))
|
|
||||||
})
|
|
||||||
.map(|entry| read_dir(entry.path()))
|
|
||||||
.filter_map(StdResult::ok)
|
|
||||||
.flat_map(|dir| {
|
|
||||||
dir.filter_map(StdResult::ok)
|
|
||||||
.filter(|entry| entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false))
|
|
||||||
})
|
|
||||||
.count())
|
.count())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sub_directories(dir: ReadDir) -> impl Iterator<Item = ReadDir> {
|
||||||
|
dir.filter_map(StdResult::ok)
|
||||||
|
.filter(|entry| entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false))
|
||||||
|
.filter_map(|entry| read_dir(entry.path()).ok())
|
||||||
|
}
|
||||||
|
18
src/error.rs
18
src/error.rs
@ -5,7 +5,7 @@ use std::fmt;
|
|||||||
pub(crate) type Result<T> = std::result::Result<T, Error>;
|
pub(crate) type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) enum Error {
|
pub enum Error {
|
||||||
Badge(String),
|
Badge(String),
|
||||||
Client(reqwest::Error),
|
Client(reqwest::Error),
|
||||||
Git(git2::Error),
|
Git(git2::Error),
|
||||||
@ -19,13 +19,13 @@ pub(crate) enum Error {
|
|||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Error::Badge(s) => write!(fmt, "Badge({})", s),
|
Error::Badge(s) => write!(fmt, "Badge({s})"),
|
||||||
Error::Client(e) => write!(fmt, "Client({})", e),
|
Error::Client(e) => write!(fmt, "Client({e})"),
|
||||||
Error::Git(e) => write!(fmt, "Git({})", e),
|
Error::Git(e) => write!(fmt, "Git({e})"),
|
||||||
Error::Internal => write!(fmt, "Internal Error"),
|
Error::Internal => write!(fmt, "Internal Error"),
|
||||||
Error::Io(e) => write!(fmt, "Io({})", e),
|
Error::Io(e) => write!(fmt, "Io({e})"),
|
||||||
Error::Parse(e) => write!(fmt, "Parse({})", e),
|
Error::Parse(e) => write!(fmt, "Parse({e})"),
|
||||||
Error::Serial(e) => write!(fmt, "Serial({})", e),
|
Error::Serial(e) => write!(fmt, "Serial({e})"),
|
||||||
Error::BranchNotFound => write!(fmt, "Repo doesn't have master branch"),
|
Error::BranchNotFound => write!(fmt, "Repo doesn't have master branch"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -43,11 +43,11 @@ impl ResponseError for Error {
|
|||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
match self {
|
match self {
|
||||||
Error::BranchNotFound => {
|
Error::BranchNotFound => {
|
||||||
templates::p404_no_master(&mut buf, VERSION_INFO, 0).unwrap();
|
templates::p404_no_master_html(&mut buf, VERSION_INFO, 0).unwrap();
|
||||||
HttpResponse::NotFound().content_type("text/html").body(buf)
|
HttpResponse::NotFound().content_type("text/html").body(buf)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
templates::p500(&mut buf, VERSION_INFO, 0).unwrap();
|
templates::p500_html(&mut buf, VERSION_INFO, 0).unwrap();
|
||||||
HttpResponse::InternalServerError()
|
HttpResponse::InternalServerError()
|
||||||
.content_type("text/html")
|
.content_type("text/html")
|
||||||
.body(buf)
|
.body(buf)
|
||||||
|
114
src/lib.rs
114
src/lib.rs
@ -11,7 +11,7 @@ extern crate tracing;
|
|||||||
|
|
||||||
mod cache;
|
mod cache;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
mod count;
|
pub mod count;
|
||||||
mod error;
|
mod error;
|
||||||
mod service;
|
mod service;
|
||||||
mod statics;
|
mod statics;
|
||||||
@ -23,8 +23,8 @@ use crate::{
|
|||||||
config::Settings,
|
config::Settings,
|
||||||
error::{Error, Result},
|
error::{Error, Result},
|
||||||
service::{Bitbucket, FormService, GitHub, Gitlab, Service, Sourcehut},
|
service::{Bitbucket, FormService, GitHub, Gitlab, Service, Sourcehut},
|
||||||
statics::{CLIENT, CSS, FAVICON, VERSION_INFO},
|
statics::{CLIENT, VERSION_INFO},
|
||||||
template::RepoInfo,
|
template::{RepoGeneratorInfo, RepoInfo},
|
||||||
};
|
};
|
||||||
use actix_web::{
|
use actix_web::{
|
||||||
dev::Server,
|
dev::Server,
|
||||||
@ -32,7 +32,7 @@ use actix_web::{
|
|||||||
middleware::{self, TrailingSlash},
|
middleware::{self, TrailingSlash},
|
||||||
web, App, HttpResponse, HttpServer, Responder,
|
web, App, HttpResponse, HttpServer, Responder,
|
||||||
};
|
};
|
||||||
use badge::{Badge, BadgeOptions};
|
use badgers::{Badge, BadgeOptions};
|
||||||
use git2::{BranchType, Repository};
|
use git2::{BranchType, Repository};
|
||||||
use number_prefix::NumberPrefix;
|
use number_prefix::NumberPrefix;
|
||||||
use std::{
|
use std::{
|
||||||
@ -46,6 +46,7 @@ use std::{
|
|||||||
sync::atomic::Ordering,
|
sync::atomic::Ordering,
|
||||||
time::{Duration, SystemTime},
|
time::{Duration, SystemTime},
|
||||||
};
|
};
|
||||||
|
use templates::statics::{self as template_statics, StaticFile};
|
||||||
use tracing::Instrument;
|
use tracing::Instrument;
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/templates.rs"));
|
include!(concat!(env!("OUT_DIR"), "/templates.rs"));
|
||||||
@ -55,6 +56,7 @@ struct GeneratorForm<'a> {
|
|||||||
service: FormService,
|
service: FormService,
|
||||||
user: Cow<'a, str>,
|
user: Cow<'a, str>,
|
||||||
repo: Cow<'a, str>,
|
repo: Cow<'a, str>,
|
||||||
|
branch: Option<Cow<'a, str>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -81,8 +83,14 @@ struct JsonResponse<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
struct BranchQuery {
|
struct BadgeQuery {
|
||||||
branch: Option<String>,
|
branch: Option<String>,
|
||||||
|
#[serde(default = "default_label")]
|
||||||
|
label: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_label() -> String {
|
||||||
|
"Hits-of-Code".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pull(path: impl AsRef<Path>) -> Result<()> {
|
fn pull(path: impl AsRef<Path>) -> Result<()> {
|
||||||
@ -93,8 +101,8 @@ fn pull(path: impl AsRef<Path>) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn hoc(repo: &str, repo_dir: &str, cache_dir: &str, branch: &str) -> Result<(u64, String, u64)> {
|
fn hoc(repo: &str, repo_dir: &str, cache_dir: &str, branch: &str) -> Result<(u64, String, u64)> {
|
||||||
let repo_dir = format!("{}/{}", repo_dir, repo);
|
let repo_dir = format!("{repo_dir}/{repo}");
|
||||||
let cache_dir = format!("{}/{}.json", cache_dir, repo);
|
let cache_dir = format!("{cache_dir}/{repo}.json");
|
||||||
let cache_dir = Path::new(&cache_dir);
|
let cache_dir = Path::new(&cache_dir);
|
||||||
let repo = Repository::open_bare(&repo_dir)?;
|
let repo = Repository::open_bare(&repo_dir)?;
|
||||||
// TODO: do better...
|
// TODO: do better...
|
||||||
@ -116,7 +124,7 @@ fn hoc(repo: &str, repo_dir: &str, cache_dir: &str, branch: &str) -> Result<(u64
|
|||||||
"-M".to_string(),
|
"-M".to_string(),
|
||||||
"--diff-filter=ACDM".to_string(),
|
"--diff-filter=ACDM".to_string(),
|
||||||
];
|
];
|
||||||
let cache = CacheState::read_from_file(&cache_dir, branch, &head)?;
|
let cache = CacheState::read_from_file(cache_dir, branch, &head)?;
|
||||||
match &cache {
|
match &cache {
|
||||||
CacheState::Current { count, commits, .. } => {
|
CacheState::Current { count, commits, .. } => {
|
||||||
info!("Using cache");
|
info!("Using cache");
|
||||||
@ -124,8 +132,8 @@ fn hoc(repo: &str, repo_dir: &str, cache_dir: &str, branch: &str) -> Result<(u64
|
|||||||
}
|
}
|
||||||
CacheState::Old { head, .. } => {
|
CacheState::Old { head, .. } => {
|
||||||
info!("Updating cache");
|
info!("Updating cache");
|
||||||
arg.push(format!("{}..{}", head, branch));
|
arg.push(format!("{head}..{branch}"));
|
||||||
arg_commit_count.push(format!("{}..{}", head, branch));
|
arg_commit_count.push(format!("{head}..{branch}"));
|
||||||
}
|
}
|
||||||
CacheState::No | CacheState::NoneForBranch(..) => {
|
CacheState::No | CacheState::NoneForBranch(..) => {
|
||||||
info!("Creating cache");
|
info!("Creating cache");
|
||||||
@ -206,16 +214,16 @@ where
|
|||||||
data.1.to_lowercase()
|
data.1.to_lowercase()
|
||||||
);
|
);
|
||||||
info!("Deleting cache and repository");
|
info!("Deleting cache and repository");
|
||||||
let cache_dir = format!("{}/{}.json", &state.cache(), repo);
|
let cache_dir = format!("{}/{repo}.json", &state.cache());
|
||||||
let repo_dir = format!("{}/{}", &state.repos(), repo);
|
let repo_dir = format!("{}/{repo}", &state.repos());
|
||||||
std::fs::remove_file(&cache_dir).or_else(|e| {
|
std::fs::remove_file(cache_dir).or_else(|e| {
|
||||||
if e.kind() == io::ErrorKind::NotFound {
|
if e.kind() == io::ErrorKind::NotFound {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(e)
|
Err(e)
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
std::fs::remove_dir_all(&repo_dir).or_else(|e| {
|
std::fs::remove_dir_all(repo_dir).or_else(|e| {
|
||||||
if e.kind() == io::ErrorKind::NotFound {
|
if e.kind() == io::ErrorKind::NotFound {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@ -254,10 +262,10 @@ where
|
|||||||
);
|
);
|
||||||
let future = async {
|
let future = async {
|
||||||
let repo = format!("{}/{}", data.0.to_lowercase(), data.1.to_lowercase());
|
let repo = format!("{}/{}", data.0.to_lowercase(), data.1.to_lowercase());
|
||||||
let service_path = format!("{}/{}", T::url_path(), repo);
|
let service_path = format!("{}/{repo}", T::url_path());
|
||||||
let service_url = format!("{}/{}", T::domain(), repo);
|
let service_url = format!("{}/{repo}", T::domain());
|
||||||
let path = format!("{}/{}", state.repos(), service_url);
|
let path = format!("{}/{service_url}", state.repos());
|
||||||
let url = format!("https://{}", service_url);
|
let url = format!("https://{service_url}");
|
||||||
let remote_exists = remote_exists(&url).await?;
|
let remote_exists = remote_exists(&url).await?;
|
||||||
let file = Path::new(&path);
|
let file = Path::new(&path);
|
||||||
if !file.exists() {
|
if !file.exists() {
|
||||||
@ -276,7 +284,7 @@ where
|
|||||||
let (hoc, head, commits) = hoc(&service_url, &state.repos(), &state.cache(), branch)?;
|
let (hoc, head, commits) = hoc(&service_url, &state.repos(), &state.cache(), branch)?;
|
||||||
let hoc_pretty = match NumberPrefix::decimal(hoc as f64) {
|
let hoc_pretty = match NumberPrefix::decimal(hoc as f64) {
|
||||||
NumberPrefix::Standalone(hoc) => hoc.to_string(),
|
NumberPrefix::Standalone(hoc) => hoc.to_string(),
|
||||||
NumberPrefix::Prefixed(prefix, hoc) => format!("{:.1}{}", hoc, prefix),
|
NumberPrefix::Prefixed(prefix, hoc) => format!("{hoc:.1}{prefix}"),
|
||||||
};
|
};
|
||||||
let res = HocResult::Hoc {
|
let res = HocResult::Hoc {
|
||||||
hoc,
|
hoc,
|
||||||
@ -296,7 +304,7 @@ pub(crate) async fn json_hoc<T: Service>(
|
|||||||
state: web::Data<State>,
|
state: web::Data<State>,
|
||||||
repo_count: web::Data<AtomicUsize>,
|
repo_count: web::Data<AtomicUsize>,
|
||||||
data: web::Path<(String, String)>,
|
data: web::Path<(String, String)>,
|
||||||
branch: web::Query<BranchQuery>,
|
branch: web::Query<BadgeQuery>,
|
||||||
) -> Result<HttpResponse> {
|
) -> Result<HttpResponse> {
|
||||||
let branch = branch.branch.as_deref().unwrap_or("master");
|
let branch = branch.branch.as_deref().unwrap_or("master");
|
||||||
let rc_clone = repo_count.clone();
|
let rc_clone = repo_count.clone();
|
||||||
@ -332,14 +340,15 @@ pub(crate) async fn calculate_hoc<T: Service>(
|
|||||||
state: web::Data<State>,
|
state: web::Data<State>,
|
||||||
repo_count: web::Data<AtomicUsize>,
|
repo_count: web::Data<AtomicUsize>,
|
||||||
data: web::Path<(String, String)>,
|
data: web::Path<(String, String)>,
|
||||||
branch: web::Query<BranchQuery>,
|
query: web::Query<BadgeQuery>,
|
||||||
) -> HttpResponse {
|
) -> HttpResponse {
|
||||||
let rc_clone = repo_count.clone();
|
let rc_clone = repo_count.clone();
|
||||||
|
let label = query.label.clone();
|
||||||
let mapper = move |r| match r {
|
let mapper = move |r| match r {
|
||||||
HocResult::NotFound => p404(rc_clone),
|
HocResult::NotFound => p404(rc_clone),
|
||||||
HocResult::Hoc { hoc_pretty, .. } => {
|
HocResult::Hoc { hoc_pretty, .. } => {
|
||||||
let badge_opt = BadgeOptions {
|
let badge_opt = BadgeOptions {
|
||||||
subject: "Hits-of-Code".to_string(),
|
subject: label,
|
||||||
color: "#007ec6".to_string(),
|
color: "#007ec6".to_string(),
|
||||||
status: hoc_pretty,
|
status: hoc_pretty,
|
||||||
};
|
};
|
||||||
@ -350,10 +359,10 @@ pub(crate) async fn calculate_hoc<T: Service>(
|
|||||||
Ok(no_cache_response(body))
|
Ok(no_cache_response(body))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let branch = branch.branch.as_deref().unwrap_or("master");
|
let branch = query.branch.as_deref().unwrap_or("master");
|
||||||
let error_badge = |_| {
|
let error_badge = |_| {
|
||||||
let error_badge = Badge::new(BadgeOptions {
|
let error_badge = Badge::new(BadgeOptions {
|
||||||
subject: "Hits-of-Code".to_string(),
|
subject: query.label.clone(),
|
||||||
color: "#ff0000".to_string(),
|
color: "#ff0000".to_string(),
|
||||||
status: "error".to_string(),
|
status: "error".to_string(),
|
||||||
})
|
})
|
||||||
@ -370,9 +379,10 @@ async fn overview<T: Service>(
|
|||||||
state: web::Data<State>,
|
state: web::Data<State>,
|
||||||
repo_count: web::Data<AtomicUsize>,
|
repo_count: web::Data<AtomicUsize>,
|
||||||
data: web::Path<(String, String)>,
|
data: web::Path<(String, String)>,
|
||||||
branch: web::Query<BranchQuery>,
|
query: web::Query<BadgeQuery>,
|
||||||
) -> Result<HttpResponse> {
|
) -> Result<HttpResponse> {
|
||||||
let branch = branch.branch.as_deref().unwrap_or("master");
|
let branch = query.branch.as_deref().unwrap_or("master");
|
||||||
|
let label = query.label.clone();
|
||||||
let base_url = state.settings.base_url.clone();
|
let base_url = state.settings.base_url.clone();
|
||||||
let rc_clone = repo_count.clone();
|
let rc_clone = repo_count.clone();
|
||||||
let mapper = move |r| match r {
|
let mapper = move |r| match r {
|
||||||
@ -398,11 +408,12 @@ async fn overview<T: Service>(
|
|||||||
url: &url,
|
url: &url,
|
||||||
branch,
|
branch,
|
||||||
};
|
};
|
||||||
templates::overview(
|
templates::overview_html(
|
||||||
&mut buf,
|
&mut buf,
|
||||||
VERSION_INFO,
|
VERSION_INFO,
|
||||||
rc_clone.load(Ordering::Relaxed),
|
rc_clone.load(Ordering::Relaxed),
|
||||||
repo_info,
|
repo_info,
|
||||||
|
label,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().content_type("text/html").body(buf))
|
Ok(HttpResponse::Ok().content_type("text/html").body(buf))
|
||||||
@ -422,7 +433,7 @@ async fn index(
|
|||||||
repo_count: web::Data<AtomicUsize>,
|
repo_count: web::Data<AtomicUsize>,
|
||||||
) -> Result<HttpResponse> {
|
) -> Result<HttpResponse> {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
templates::index(
|
templates::index_html(
|
||||||
&mut buf,
|
&mut buf,
|
||||||
VERSION_INFO,
|
VERSION_INFO,
|
||||||
repo_count.load(Ordering::Relaxed),
|
repo_count.load(Ordering::Relaxed),
|
||||||
@ -437,16 +448,23 @@ async fn generate(
|
|||||||
state: web::Data<State>,
|
state: web::Data<State>,
|
||||||
repo_count: web::Data<AtomicUsize>,
|
repo_count: web::Data<AtomicUsize>,
|
||||||
) -> Result<HttpResponse> {
|
) -> Result<HttpResponse> {
|
||||||
let repo = format!("{}/{}", params.user, params.repo);
|
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
templates::generate(
|
let repo_info = RepoGeneratorInfo {
|
||||||
|
service: params.service,
|
||||||
|
user: ¶ms.user,
|
||||||
|
repo: ¶ms.repo,
|
||||||
|
branch: params
|
||||||
|
.branch
|
||||||
|
.as_deref()
|
||||||
|
.filter(|s| !s.is_empty())
|
||||||
|
.unwrap_or("master"),
|
||||||
|
};
|
||||||
|
templates::generate_html(
|
||||||
&mut buf,
|
&mut buf,
|
||||||
VERSION_INFO,
|
VERSION_INFO,
|
||||||
repo_count.load(Ordering::Relaxed),
|
repo_count.load(Ordering::Relaxed),
|
||||||
&state.settings.base_url,
|
&state.settings.base_url,
|
||||||
params.service.url(),
|
&repo_info,
|
||||||
params.service.service(),
|
|
||||||
&repo,
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().content_type("text/html").body(buf))
|
Ok(HttpResponse::Ok().content_type("text/html").body(buf))
|
||||||
@ -454,7 +472,7 @@ async fn generate(
|
|||||||
|
|
||||||
fn p404(repo_count: web::Data<AtomicUsize>) -> Result<HttpResponse> {
|
fn p404(repo_count: web::Data<AtomicUsize>) -> Result<HttpResponse> {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
templates::p404(&mut buf, VERSION_INFO, repo_count.load(Ordering::Relaxed))?;
|
templates::p404_html(&mut buf, VERSION_INFO, repo_count.load(Ordering::Relaxed))?;
|
||||||
Ok(HttpResponse::NotFound().content_type("text/html").body(buf))
|
Ok(HttpResponse::NotFound().content_type("text/html").body(buf))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,14 +480,32 @@ async fn async_p404(repo_count: web::Data<AtomicUsize>) -> Result<HttpResponse>
|
|||||||
p404(repo_count)
|
p404(repo_count)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/tacit-css.min.css")]
|
/// A duration to add to current time for a far expires header.
|
||||||
async fn css() -> HttpResponse {
|
static FAR: Duration = Duration::from_secs(180 * 24 * 60 * 60);
|
||||||
HttpResponse::Ok().content_type("text/css").body(CSS)
|
|
||||||
|
#[get("/static/{filename}")]
|
||||||
|
async fn static_file(
|
||||||
|
path: web::Path<String>,
|
||||||
|
repo_count: web::Data<AtomicUsize>,
|
||||||
|
) -> Result<HttpResponse> {
|
||||||
|
StaticFile::get(&path)
|
||||||
|
.map(|data| {
|
||||||
|
let far_expires = SystemTime::now() + FAR;
|
||||||
|
HttpResponse::Ok()
|
||||||
|
.insert_header(Expires(far_expires.into()))
|
||||||
|
.content_type(data.mime.clone())
|
||||||
|
.body(data.content)
|
||||||
|
})
|
||||||
|
.map(Result::Ok)
|
||||||
|
.unwrap_or_else(|| p404(repo_count))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/favicon.ico")]
|
#[get("/favicon.ico")]
|
||||||
async fn favicon32() -> HttpResponse {
|
async fn favicon32() -> HttpResponse {
|
||||||
HttpResponse::Ok().content_type("image/png").body(FAVICON)
|
let data = &template_statics::favicon32_png;
|
||||||
|
HttpResponse::Ok()
|
||||||
|
.content_type(data.mime.clone())
|
||||||
|
.body(data.content)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn start_server(listener: TcpListener, settings: Settings) -> std::io::Result<Server> {
|
async fn start_server(listener: TcpListener, settings: Settings) -> std::io::Result<Server> {
|
||||||
@ -486,7 +522,7 @@ async fn start_server(listener: TcpListener, settings: Settings) -> std::io::Res
|
|||||||
.wrap(middleware::NormalizePath::new(TrailingSlash::Trim))
|
.wrap(middleware::NormalizePath::new(TrailingSlash::Trim))
|
||||||
.service(index)
|
.service(index)
|
||||||
.service(health_check)
|
.service(health_check)
|
||||||
.service(css)
|
.service(static_file)
|
||||||
.service(favicon32)
|
.service(favicon32)
|
||||||
.service(generate)
|
.service(generate)
|
||||||
.default_service(web::to(async_p404));
|
.default_service(web::to(async_p404));
|
||||||
|
@ -3,7 +3,7 @@ use hoc::{config::Settings, telemetry};
|
|||||||
use std::net::TcpListener;
|
use std::net::TcpListener;
|
||||||
|
|
||||||
fn init() {
|
fn init() {
|
||||||
dotenv::dotenv().ok();
|
dotenvy::dotenv().ok();
|
||||||
openssl_probe::init_ssl_cert_env_vars();
|
openssl_probe::init_ssl_cert_env_vars();
|
||||||
|
|
||||||
telemetry::init_subscriber(telemetry::get_subscriber("hoc", "info"))
|
telemetry::init_subscriber(telemetry::get_subscriber("hoc", "info"))
|
||||||
|
@ -28,8 +28,8 @@ pub(crate) trait Service: Sized + 'static {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize, Clone, Copy)]
|
||||||
pub(crate) enum FormService {
|
pub enum FormService {
|
||||||
#[serde(rename = "github")]
|
#[serde(rename = "github")]
|
||||||
GitHub,
|
GitHub,
|
||||||
#[serde(rename = "gitlab")]
|
#[serde(rename = "gitlab")]
|
||||||
|
@ -7,8 +7,6 @@ pub(crate) const VERSION_INFO: VersionInfo = VersionInfo {
|
|||||||
commit: env!("VERGEN_GIT_SHA_SHORT"),
|
commit: env!("VERGEN_GIT_SHA_SHORT"),
|
||||||
version: env!("CARGO_PKG_VERSION"),
|
version: env!("CARGO_PKG_VERSION"),
|
||||||
};
|
};
|
||||||
pub(crate) const CSS: &str = include_str!("../static/tacit-css.min.css");
|
|
||||||
pub(crate) const FAVICON: &[u8] = include_bytes!("../static/favicon32.png");
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub(crate) static ref CLIENT: reqwest::Client = reqwest::Client::new();
|
pub(crate) static ref CLIENT: reqwest::Client = reqwest::Client::new();
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use crate::service::FormService;
|
||||||
|
|
||||||
pub struct RepoInfo<'a> {
|
pub struct RepoInfo<'a> {
|
||||||
pub commit_url: &'a str,
|
pub commit_url: &'a str,
|
||||||
pub commits: u64,
|
pub commits: u64,
|
||||||
@ -9,3 +11,10 @@ pub struct RepoInfo<'a> {
|
|||||||
pub url: &'a str,
|
pub url: &'a str,
|
||||||
pub branch: &'a str,
|
pub branch: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct RepoGeneratorInfo<'a> {
|
||||||
|
pub service: FormService,
|
||||||
|
pub user: &'a str,
|
||||||
|
pub repo: &'a str,
|
||||||
|
pub branch: &'a str,
|
||||||
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
@use super::statics::*;
|
||||||
@use crate::statics::VersionInfo;
|
@use crate::statics::VersionInfo;
|
||||||
|
|
||||||
@(title: &str, header: &str, content: Content, version_info: VersionInfo, repo_count: usize)
|
@(title: &str, header: &str, content: Content, version_info: VersionInfo, repo_count: usize)
|
||||||
@ -9,7 +10,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta name="keywords" content="Hits-of-Code, GitHub, Badge" />
|
<meta name="keywords" content="Hits-of-Code, GitHub, Badge" />
|
||||||
<meta name="description" content="Hits-of-Code Badges for Git repositories" />
|
<meta name="description" content="Hits-of-Code Badges for Git repositories" />
|
||||||
<link rel="stylesheet" href="/tacit-css.min.css" />
|
<link rel="stylesheet" href="/static/@tacit_css_min_css.name" />
|
||||||
<title>@title</title>
|
<title>@title</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
@use super::base;
|
@use super::base_html;
|
||||||
@use crate::statics::VersionInfo;
|
@use crate::{statics::VersionInfo, template::RepoGeneratorInfo};
|
||||||
|
|
||||||
@(version_info: VersionInfo, repo_count: usize, base_url: &str, url: &str, service: &str, path: &str)
|
@(version_info: VersionInfo, repo_count: usize, base_url: &str, repo_info: &RepoGeneratorInfo)
|
||||||
|
|
||||||
@:base("Hits-of-Code Badges", "Badge Generator", {
|
@:base_html("Hits-of-Code Badges", "Badge Generator", {
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Here is the markdown for the badge for <a href="https://@url/@path">@url/@path</a>
|
Here is the markdown for the badge for <a href="https://@repo_info.service.url()/@repo_info.user/@repo_info.repo">@repo_info.user/@repo_info.repo</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
[](@base_url/@service/@path/view)
|
[/@repo_info.user/@repo_info.repo?branch=@repo_info.branch)](@base_url/@repo_info.service.service()/@repo_info.user/@repo_info.repo/view?branch=@repo_info.branch)
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -18,6 +18,6 @@ It will be rendered like this
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<a href="@base_url/@service/@path/view"><img src="@base_url/@service/@path" alt="example badge" /></a>
|
<a href="@base_url/@repo_info.service.service()/@repo_info.user/@repo_info.repo/view?branch=@repo_info.branch"><img src="@base_url/@repo_info.service.service()/@repo_info.user/@repo_info.repo?branch=@repo_info.branch" alt="example badge" /></a>
|
||||||
</pre>
|
</pre>
|
||||||
}, version_info, repo_count)
|
}, version_info, repo_count)
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
@use super::base;
|
@use super::base_html;
|
||||||
@use crate::statics::VersionInfo;
|
@use crate::statics::VersionInfo;
|
||||||
|
|
||||||
@(version_info: VersionInfo, repo_count: usize, base_url: &str)
|
@(version_info: VersionInfo, repo_count: usize, base_url: &str)
|
||||||
|
|
||||||
@:base("Hits-of-Code Badges", "Hits-of-Code Badges", {
|
@:base_html("Hits-of-Code Badges", "Hits-of-Code Badges", {
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
This API offers badges for the Hits-of-Code metric for your repositories. This metric was proposed by
|
This API offers badges for the Hits-of-Code metric for your repositories. This metric was proposed by
|
||||||
@ -51,6 +51,10 @@ in your repository or you want a badge for another branch of your repository, ju
|
|||||||
<code>?branch=<branch-name></code> to the URL.
|
<code>?branch=<branch-name></code> to the URL.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The badge label can be customized using the <code>label=<some-label></code> query parameter. It defaults to <code>Hits-of-Code</code>.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
You can also request the HoC as JSON by appending <code>/json</code> to the request path. This will return a JSON object
|
You can also request the HoC as JSON by appending <code>/json</code> to the request path. This will return a JSON object
|
||||||
with three fields: <code>count</code> (the HoC value), <code>commits</code> (the number of commits) and
|
with three fields: <code>count</code> (the HoC value), <code>commits</code> (the number of commits) and
|
||||||
@ -80,6 +84,8 @@ the lines of
|
|||||||
<input name="user" id="user" type="text" placeholder="user" />
|
<input name="user" id="user" type="text" placeholder="user" />
|
||||||
<label>/</label>
|
<label>/</label>
|
||||||
<input name="repo" id="repo" type="text" placeholder="repository" />
|
<input name="repo" id="repo" type="text" placeholder="repository" />
|
||||||
|
<label>:</label>
|
||||||
|
<input name="branch" id="branch" type="text" placeholder="branch (defaults to `master`)" />
|
||||||
<button type="submit">Generate</button>
|
<button type="submit">Generate</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
@use super::base;
|
@use super::base_html;
|
||||||
@use crate::statics::VersionInfo;
|
@use crate::statics::VersionInfo;
|
||||||
@use crate::template::RepoInfo;
|
@use crate::template::RepoInfo;
|
||||||
|
|
||||||
@(version_info: VersionInfo, repo_count: usize, repo_info: RepoInfo)
|
@(version_info: VersionInfo, repo_count: usize, repo_info: RepoInfo, label: String)
|
||||||
|
|
||||||
@:base("Hits-of-Code Badges", "Overview", {
|
@:base_html("Hits-of-Code Badges", "Overview", {
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The project <a href="@repo_info.url">@repo_info.url</a> has
|
The project <a href="@repo_info.url">@repo_info.url</a> has
|
||||||
@ -19,7 +19,7 @@ To include the badge in your readme, use the following markdown:
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
[](@repo_info.base_url/@repo_info.path/view?branch=@repo_info.branch)
|
[](@repo_info.base_url/@repo_info.path/view?branch=@repo_info.branch&label=@label)
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
@use super::base;
|
@use super::base_html;
|
||||||
@use crate::statics::VersionInfo;
|
@use crate::statics::VersionInfo;
|
||||||
|
|
||||||
@(version_info: VersionInfo, repo_count: usize)
|
@(version_info: VersionInfo, repo_count: usize)
|
||||||
|
|
||||||
@:base("Page not Found - Hits-of-Code Badges", "404 - Page not Found", {
|
@:base_html("Page not Found - Hits-of-Code Badges", "404 - Page not Found", {
|
||||||
<p>
|
<p>
|
||||||
<big>Sorry</big>. I couldn't find the page you are looking for. Please go <a href="/">back to the homepage</a>.
|
<big>Sorry</big>. I couldn't find the page you are looking for. Please go <a href="/">back to the homepage</a>.
|
||||||
</p>
|
</p>
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
@use super::base;
|
@use super::base_html;
|
||||||
@use crate::statics::VersionInfo;
|
@use crate::statics::VersionInfo;
|
||||||
|
|
||||||
@(version_info: VersionInfo, repo_count: usize)
|
@(version_info: VersionInfo, repo_count: usize)
|
||||||
|
|
||||||
@:base("Branch not Found - Hits-of-Code Badges", "404 - Branch not Found", {
|
@:base_html("Branch not Found - Hits-of-Code Badges", "404 - Branch not Found", {
|
||||||
<p>
|
<p>
|
||||||
<big>Sorry</big>. I couldn't find the requested branch of your repositroy. Currently this service assumes the
|
<big>Sorry</big>. I couldn't find the requested branch of your repositroy. Currently this service assumes the
|
||||||
extistence of a branch named <code>master</code>. If you'd like to request a badge for another branch, you can do so by
|
extistence of a branch named <code>master</code>. If you'd like to request a badge for another branch, you can do so by
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
@use super::base;
|
@use super::base_html;
|
||||||
@use crate::statics::VersionInfo;
|
@use crate::statics::VersionInfo;
|
||||||
|
|
||||||
@(version_info: VersionInfo, repo_count: usize)
|
@(version_info: VersionInfo, repo_count: usize)
|
||||||
|
|
||||||
@:base("Internal Server Error - Hits-of-Code Badges", "500 - Internal Server Error", {
|
@:base_html("Internal Server Error - Hits-of-Code Badges", "500 - Internal Server Error", {
|
||||||
<p>
|
<p>
|
||||||
<big>Oops</big>. Looks like a made a mistake. Please go <a href="/">back to the homepage</a> and try again.
|
<big>Oops</big>. Looks like a made a mistake. Please go <a href="/">back to the homepage</a> and try again.
|
||||||
</p>
|
</p>
|
||||||
|
66
tests/count.rs
Normal file
66
tests/count.rs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
use hoc::count::count_repositories;
|
||||||
|
|
||||||
|
use tempfile::TempDir;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_repos() {
|
||||||
|
let repos = TempDir::new().unwrap();
|
||||||
|
assert_eq!(0, count_repositories(&repos).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_repos_for_provider() {
|
||||||
|
let repos = TempDir::new().unwrap();
|
||||||
|
let _provider = TempDir::new_in(&repos).unwrap();
|
||||||
|
assert_eq!(0, count_repositories(&repos).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_repos_for_owner() {
|
||||||
|
let repos = TempDir::new().unwrap();
|
||||||
|
let provider = TempDir::new_in(&repos).unwrap();
|
||||||
|
let _owner = TempDir::new_in(&provider).unwrap();
|
||||||
|
assert_eq!(0, count_repositories(&repos).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn one_repo_for_owner() {
|
||||||
|
let repos = TempDir::new().unwrap();
|
||||||
|
let provider = TempDir::new_in(&repos).unwrap();
|
||||||
|
let owner = TempDir::new_in(&provider).unwrap();
|
||||||
|
let _repo = TempDir::new_in(&owner).unwrap();
|
||||||
|
assert_eq!(1, count_repositories(&repos).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn two_repos_for_owner() {
|
||||||
|
let repos = TempDir::new().unwrap();
|
||||||
|
let provider = TempDir::new_in(&repos).unwrap();
|
||||||
|
let owner = TempDir::new_in(&provider).unwrap();
|
||||||
|
let _repo1 = TempDir::new_in(&owner).unwrap();
|
||||||
|
let _repo2 = TempDir::new_in(&owner).unwrap();
|
||||||
|
assert_eq!(2, count_repositories(&repos).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn two_repos_for_two_providers() {
|
||||||
|
let repos = TempDir::new().unwrap();
|
||||||
|
let provider1 = TempDir::new_in(&repos).unwrap();
|
||||||
|
let owner1 = TempDir::new_in(&provider1).unwrap();
|
||||||
|
let _repo1 = TempDir::new_in(&owner1).unwrap();
|
||||||
|
let provider2 = TempDir::new_in(&repos).unwrap();
|
||||||
|
let owner2 = TempDir::new_in(&provider2).unwrap();
|
||||||
|
let _repo2 = TempDir::new_in(&owner2).unwrap();
|
||||||
|
assert_eq!(2, count_repositories(&repos).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn two_subdirs_in_one_repo() {
|
||||||
|
let repos = TempDir::new().unwrap();
|
||||||
|
let provider = TempDir::new_in(&repos).unwrap();
|
||||||
|
let owner = TempDir::new_in(&provider).unwrap();
|
||||||
|
let repo = TempDir::new_in(&owner).unwrap();
|
||||||
|
let _subdir1 = TempDir::new_in(&repo).unwrap();
|
||||||
|
let _subdir2 = TempDir::new_in(&repo).unwrap();
|
||||||
|
assert_eq!(1, count_repositories(&repos).unwrap())
|
||||||
|
}
|
@ -14,18 +14,3 @@ async fn favicon() {
|
|||||||
|
|
||||||
assert!(response.status().is_success());
|
assert!(response.status().is_success());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
|
||||||
async fn tacit_css() {
|
|
||||||
let test_app = util::spawn_app().await;
|
|
||||||
|
|
||||||
let client = awc::Client::default();
|
|
||||||
|
|
||||||
let response = client
|
|
||||||
.get(&format!("{}/tacit-css.min.css", test_app.address))
|
|
||||||
.send()
|
|
||||||
.await
|
|
||||||
.expect("Failed to execute request");
|
|
||||||
|
|
||||||
assert!(response.status().is_success());
|
|
||||||
}
|
|
||||||
|
@ -14,8 +14,9 @@ lazy_static::lazy_static! {
|
|||||||
|
|
||||||
pub struct TestApp {
|
pub struct TestApp {
|
||||||
pub address: String,
|
pub address: String,
|
||||||
repo_dir: TempDir,
|
// Those are unused but are hold to be dropped and deleted after the TestApp goes out of scope
|
||||||
cache_dir: TempDir,
|
_repo_dir: TempDir,
|
||||||
|
_cache_dir: TempDir,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn spawn_app() -> TestApp {
|
pub async fn spawn_app() -> TestApp {
|
||||||
@ -26,15 +27,12 @@ pub async fn spawn_app() -> TestApp {
|
|||||||
let port = listener.local_addr().unwrap().port();
|
let port = listener.local_addr().unwrap().port();
|
||||||
let address = format!("http://127.0.0.1:{}", port);
|
let address = format!("http://127.0.0.1:{}", port);
|
||||||
|
|
||||||
let repo_dir = tempdir().expect("Cannot create repo_dir");
|
let _repo_dir = tempdir().expect("Cannot create repo_dir");
|
||||||
let cache_dir = tempdir().expect("Cannot create cache_dir");
|
let _cache_dir = tempdir().expect("Cannot create cache_dir");
|
||||||
|
|
||||||
let mut settings = Settings::load().expect("Failed to read configuration.");
|
let mut settings = Settings::load().expect("Failed to read configuration.");
|
||||||
settings.repodir = repo_dir.path().to_path_buf();
|
settings.repodir = _repo_dir.path().to_path_buf();
|
||||||
settings.cachedir = cache_dir.path().to_path_buf();
|
settings.cachedir = _cache_dir.path().to_path_buf();
|
||||||
// configuration.database.database_name = Uuid::new_v4().to_string();
|
|
||||||
|
|
||||||
// let connection_pool = configure_database(&configuration.database).await;
|
|
||||||
|
|
||||||
let server = hoc::run(listener, settings)
|
let server = hoc::run(listener, settings)
|
||||||
.await
|
.await
|
||||||
@ -44,7 +42,7 @@ pub async fn spawn_app() -> TestApp {
|
|||||||
|
|
||||||
TestApp {
|
TestApp {
|
||||||
address,
|
address,
|
||||||
repo_dir,
|
_repo_dir,
|
||||||
cache_dir,
|
_cache_dir,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user