Compare commits
45 commits
Author | SHA1 | Date | |
---|---|---|---|
|
0f78fc731a | ||
|
1784f3f28b | ||
|
b794a21dd9 | ||
|
d989da659c | ||
23de987444 | |||
|
9d6271a176 | ||
|
ddc22867b3 | ||
|
5e4e287562 | ||
|
6a0e0580dc | ||
|
7bd6347dd8 | ||
|
360b7f2cf7 | ||
f3a5b9cb4c | |||
18a537b18e | |||
ef6474ef9f | |||
dbf1a0db27 | |||
|
91c5973e31 | ||
978205b823 | |||
8359d0d7ca | |||
93cf6f83df | |||
681d85aac1 | |||
d4f16e6f5e | |||
048111202a | |||
3ea7f36c98 | |||
6c60e3fb7a | |||
313d6d79c5 | |||
189d579d33 | |||
a77c6335a6 | |||
|
82241de0dd | ||
664e424d1a | |||
df6b96fbfd | |||
566125f5c0 | |||
80af909ab0 | |||
ecd460cdfb | |||
|
35c2057f05 | ||
d2e2d00fe1 | |||
e759e495fd | |||
|
3672fd5d45 | ||
1f0b5e867c | |||
8ca7aad3c3 | |||
d923e831f0 | |||
5e0cf270dd | |||
b4a4631a1d | |||
181ec8eb0f | |||
47cbbad8e7 | |||
e793c18215 |
66 changed files with 1622 additions and 499 deletions
|
@ -22,13 +22,13 @@ jobs:
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Run release-plz release-pr
|
- name: Run release-plz release-pr
|
||||||
uses: https://git.kemitix.net/kemitix/rust@v1.80.0-2
|
uses: https://git.kemitix.net/kemitix/rust@v2.3.0
|
||||||
with:
|
with:
|
||||||
args: release-plz release-pr --backend gitea --git-token ${{ secrets.FORGEJO_TOKEN }}
|
args: release-plz release-pr --backend gitea --git-token ${{ secrets.FORGEJO_TOKEN }}
|
||||||
env:
|
env:
|
||||||
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
||||||
- name: Run release-plz release
|
- name: Run release-plz release
|
||||||
uses: https://git.kemitix.net/kemitix/rust@v1.80.0-2
|
uses: https://git.kemitix.net/kemitix/rust@v2.3.0
|
||||||
with:
|
with:
|
||||||
args: release-plz release --backend gitea --git-token ${{ secrets.FORGEJO_TOKEN }}
|
args: release-plz release --backend gitea --git-token ${{ secrets.FORGEJO_TOKEN }}
|
||||||
env:
|
env:
|
||||||
|
|
|
@ -13,26 +13,40 @@ jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: docker
|
runs-on: docker
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
toolchain:
|
||||||
|
- name: stable
|
||||||
|
- name: nightly
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Format
|
- name: Check TODOs
|
||||||
uses: https://git.kemitix.net/kemitix/rust@v1.80.1-1
|
uses: kemitix/todo-checker@v1.1.0
|
||||||
|
|
||||||
|
- name: Machete
|
||||||
|
uses: https://git.kemitix.net/kemitix/rust@v2.3.0
|
||||||
with:
|
with:
|
||||||
args: cargo fmt --all -- --check
|
args: ${{ matrix.toolchain.name }} cargo machete
|
||||||
|
|
||||||
|
- name: Format
|
||||||
|
uses: https://git.kemitix.net/kemitix/rust@v2.3.0
|
||||||
|
with:
|
||||||
|
args: ${{ matrix.toolchain.name }} cargo fmt --all -- --check
|
||||||
|
|
||||||
- name: Clippy
|
- name: Clippy
|
||||||
uses: https://git.kemitix.net/kemitix/rust@v1.80.1-1
|
uses: https://git.kemitix.net/kemitix/rust@v2.3.0
|
||||||
with:
|
with:
|
||||||
args: cargo hack --feature-powerset clippy
|
args: ${{ matrix.toolchain.name }} cargo hack --feature-powerset clippy
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
uses: https://git.kemitix.net/kemitix/rust@v1.80.1-1
|
uses: https://git.kemitix.net/kemitix/rust@v2.3.0
|
||||||
with:
|
with:
|
||||||
args: cargo hack --feature-powerset build
|
args: ${{ matrix.toolchain.name }} cargo hack --feature-powerset build
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
uses: https://git.kemitix.net/kemitix/rust@v1.80.1-1
|
uses: https://git.kemitix.net/kemitix/rust@v2.3.0
|
||||||
with:
|
with:
|
||||||
args: cargo hack --feature-powerset test
|
args: ${{ matrix.toolchain.name }} cargo hack --feature-powerset test
|
||||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,3 +1,6 @@
|
||||||
|
# git-next ui logs
|
||||||
|
.local/
|
||||||
|
|
||||||
# ---> Rust
|
# ---> Rust
|
||||||
# Generated by Cargo
|
# Generated by Cargo
|
||||||
# will have compiled files and executables
|
# will have compiled files and executables
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
steps:
|
steps:
|
||||||
todo_check:
|
docker-build:
|
||||||
# INFO: This doesn't have an equivalent yet for Forgejo Actions
|
|
||||||
# INFO: https://woodpecker-ci.org/plugins/TODO-Checker
|
|
||||||
image: codeberg.org/epsilon_02/todo-checker:1.1
|
|
||||||
when:
|
when:
|
||||||
- event: push
|
- event: push
|
||||||
branch: next
|
branch: next
|
||||||
|
# INFO: https://woodpecker-ci.org/plugins/Docker%20Buildx
|
||||||
|
image: docker.io/woodpeckerci/plugin-docker-buildx:5.0.0
|
||||||
settings:
|
settings:
|
||||||
# git-next-woodpecker-todo-checker - read:issue
|
username: kemitix
|
||||||
repository_token: "776a3b928b852472c2af727a360c85c00af64b9f"
|
repo: git.kemitix.net/kemitix/git-next
|
||||||
prefix_regex: "(#|//) (TODO|FIXME): "
|
dockerfile: Dockerfile
|
||||||
debug: false
|
auto_tag: false
|
||||||
|
dry-run: true # don't push to remote repo
|
||||||
|
|
|
@ -4,7 +4,7 @@ steps:
|
||||||
- event: tag
|
- event: tag
|
||||||
ref: refs/tags/v*
|
ref: refs/tags/v*
|
||||||
# INFO: https://woodpecker-ci.org/plugins/Docker%20Buildx
|
# INFO: https://woodpecker-ci.org/plugins/Docker%20Buildx
|
||||||
image: docker.io/woodpeckerci/plugin-docker-buildx:4.2.0
|
image: docker.io/woodpeckerci/plugin-docker-buildx:5.0.0
|
||||||
settings:
|
settings:
|
||||||
username: kemitix
|
username: kemitix
|
||||||
repo: git.kemitix.net/kemitix/git-next
|
repo: git.kemitix.net/kemitix/git-next
|
||||||
|
|
59
CHANGELOG.md
59
CHANGELOG.md
|
@ -2,6 +2,65 @@
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## `git-next-core` - [0.13.11](https://git.kemitix.net/kemitix/git-next/compare/git-next-core-v0.13.10...git-next-core-v0.13.11) - 2024-09-14
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- should fetch repo on startup when not cloning
|
||||||
|
- Remove branches when fetching from remote
|
||||||
|
|
||||||
|
### Other
|
||||||
|
- reimplement git fetch using git
|
||||||
|
|
||||||
|
## `git-next` - [0.13.11](https://git.kemitix.net/kemitix/git-next/compare/v0.13.10...v0.13.11) - 2024-09-14
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- *(tui)* add time and version in border
|
||||||
|
- should fetch repo on startup when not cloning
|
||||||
|
- Remove branches when fetching from remote
|
||||||
|
|
||||||
|
### Other
|
||||||
|
- Update TUI sooner when receiving CI status
|
||||||
|
- reimplement git fetch using git
|
||||||
|
- mark tui as complete on roadmap
|
||||||
|
- Add missing port mapping parameter for running in docker
|
||||||
|
|
||||||
|
## `git-next-forge-github` - [0.13.10](https://git.kemitix.net/kemitix/git-next/compare/git-next-forge-github-v0.13.9...git-next-forge-github-v0.13.10) - 2024-09-12
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- optionally specify max commits between dev and main
|
||||||
|
|
||||||
|
## `git-next-forge-forgejo` - [0.13.10](https://git.kemitix.net/kemitix/git-next/compare/git-next-forge-forgejo-v0.13.9...git-next-forge-forgejo-v0.13.10) - 2024-09-12
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- optionally specify max commits between dev and main
|
||||||
|
|
||||||
|
## `git-next-core` - [0.13.10](https://git.kemitix.net/kemitix/git-next/compare/git-next-core-v0.13.9...git-next-core-v0.13.10) - 2024-09-12
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- optionally specify max commits between dev and main
|
||||||
|
|
||||||
|
## `git-next` - [0.13.10](https://git.kemitix.net/kemitix/git-next/compare/v0.13.9...v0.13.10) - 2024-09-12
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- optionally specify max commits between dev and main
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- *(tui)* make tui work from docker image
|
||||||
|
- *(tui)* alerts, such as WIP aren't being reset
|
||||||
|
- *(test)* tests requiring .git pass when not present
|
||||||
|
- *(tui)* update ui when push next or main finishes
|
||||||
|
- *(tui)* don't set background for normal repo alias
|
||||||
|
|
||||||
|
## `git-next` - [0.13.9](https://git.kemitix.net/kemitix/git-next/compare/v0.13.8...v0.13.9) - 2024-09-04
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- *(tui)* alerts are cleared on next repo update
|
||||||
|
- shutdown properly on error
|
||||||
|
- shutdown properly on file parse error
|
||||||
|
|
||||||
|
### Other
|
||||||
|
- Expand docker docmentation
|
||||||
|
|
||||||
## `git-next-forge-forgejo` - [0.13.8](https://git.kemitix.net/kemitix/git-next/compare/git-next-forge-forgejo-v0.13.7...git-next-forge-forgejo-v0.13.8) - 2024-09-01
|
## `git-next-forge-forgejo` - [0.13.8](https://git.kemitix.net/kemitix/git-next/compare/git-next-forge-forgejo-v0.13.7...git-next-forge-forgejo-v0.13.8) - 2024-09-01
|
||||||
|
|
||||||
### Other
|
### Other
|
||||||
|
|
462
Cargo.lock
generated
462
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
15
Cargo.toml
15
Cargo.toml
|
@ -3,7 +3,7 @@ resolver = "2"
|
||||||
members = ["crates/*"]
|
members = ["crates/*"]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.13.8"
|
version = "0.13.11"
|
||||||
|
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
@ -27,12 +27,13 @@ git-next-forge-forgejo = { path = "crates/forge-forgejo", version = "0.13" }
|
||||||
git-next-forge-github = { path = "crates/forge-github", version = "0.13" }
|
git-next-forge-github = { path = "crates/forge-github", version = "0.13" }
|
||||||
|
|
||||||
# TUI
|
# TUI
|
||||||
ratatui = "0.28"
|
ratatui = "0.29"
|
||||||
directories = "5.0"
|
directories = "5.0"
|
||||||
lazy_static = "1.5"
|
lazy_static = "1.5"
|
||||||
color-eyre = "0.6"
|
color-eyre = "0.6"
|
||||||
tui-scrollview = "0.4"
|
tui-scrollview = "0.5"
|
||||||
regex = "1.10"
|
regex = "1.10"
|
||||||
|
chrono = "0.4"
|
||||||
|
|
||||||
# CLI parsing
|
# CLI parsing
|
||||||
clap = { version = "4.5", features = ["cargo", "derive"] }
|
clap = { version = "4.5", features = ["cargo", "derive"] }
|
||||||
|
@ -51,7 +52,7 @@ sha2 = "0.10"
|
||||||
hex = "0.4"
|
hex = "0.4"
|
||||||
|
|
||||||
# git
|
# git
|
||||||
gix = { version = "0.66", features = [
|
gix = { version = "0.67", features = [
|
||||||
"dirwalk",
|
"dirwalk",
|
||||||
"blocking-http-transport-reqwest-rust-tls",
|
"blocking-http-transport-reqwest-rust-tls",
|
||||||
] }
|
] }
|
||||||
|
@ -67,7 +68,7 @@ serde_json = "1.0"
|
||||||
toml = "0.8"
|
toml = "0.8"
|
||||||
|
|
||||||
# Secrets and Password
|
# Secrets and Password
|
||||||
secrecy = "0.8"
|
secrecy = "0.10"
|
||||||
|
|
||||||
# Conventional Commit check
|
# Conventional Commit check
|
||||||
git-conventional = "0.12"
|
git-conventional = "0.12"
|
||||||
|
@ -97,7 +98,7 @@ pike = "0.1"
|
||||||
take-until = "0.2"
|
take-until = "0.2"
|
||||||
|
|
||||||
# file watcher
|
# file watcher
|
||||||
notify = "6.1"
|
notify = "7.0"
|
||||||
|
|
||||||
# Actors
|
# Actors
|
||||||
actix = "0.13"
|
actix = "0.13"
|
||||||
|
@ -117,4 +118,4 @@ pretty_assertions = "1.4"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
mockall = "0.13"
|
mockall = "0.13"
|
||||||
test-log = "0.2"
|
test-log = "0.2"
|
||||||
rstest = { version = "0.22", features = ["async-timeout"] }
|
rstest = { version = "0.23", features = ["async-timeout"] }
|
||||||
|
|
13
Dockerfile
13
Dockerfile
|
@ -15,17 +15,16 @@ COPY . .
|
||||||
RUN cargo build --release --bin git-next --all-features && \
|
RUN cargo build --release --bin git-next --all-features && \
|
||||||
strip target/release/git-next
|
strip target/release/git-next
|
||||||
|
|
||||||
FROM docker.io/debian:stable-20240722-slim AS runtime
|
FROM docker.io/debian:stable-20240904-slim AS runtime
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install --no-install-recommends -y \
|
apt-get satisfy -y "git (>=2.39), libssl3 (>=3.0.14), libdbus-1-dev (>=1.14.10), ca-certificates (>=20230311)" \
|
||||||
git=1:2.39.2-1.1 \
|
|
||||||
libssl3=3.0.13-1~deb12u1 \
|
|
||||||
libdbus-1-dev=1.14.10-1~deb12u1 \
|
|
||||||
ca-certificates=20230311 \
|
|
||||||
&& \
|
&& \
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
USER 1000
|
USER 1000
|
||||||
COPY --from=builder /app/target/release/git-next /usr/local/bin
|
COPY --from=builder /app/target/release/git-next /usr/local/bin
|
||||||
|
|
||||||
ENTRYPOINT [ "/usr/local/bin/git-next", "server", "start" ]
|
ENV HOME=/app
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/usr/local/bin/git-next" ]
|
||||||
|
CMD [ "server", "start" ]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FROM docker.io/rust:1.80.1-bookworm
|
FROM docker.io/rust:1.82.0-bookworm
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y libdbus-1-dev && \
|
apt-get install -y libdbus-1-dev && \
|
||||||
|
|
|
@ -6,4 +6,7 @@
|
||||||
development workflows where each commit must pass CI before being included in
|
development workflows where each commit must pass CI before being included in
|
||||||
the main branch.
|
the main branch.
|
||||||
|
|
||||||
|
![Demo](./demo.gif)
|
||||||
|
|
||||||
|
|
||||||
See [README.md](https://git.kemitix.net/kemitix/git-next/src/branch/main/crates/cli/README.md) for more information.
|
See [README.md](https://git.kemitix.net/kemitix/git-next/src/branch/main/crates/cli/README.md) for more information.
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
## TLDR
|
## TLDR
|
||||||
|
|
||||||
1. Merge PR `chore: release`
|
1. Merge PR `chore: release`
|
||||||
2. Wait for `push-main` workflow to complete
|
2. Wait for [`push-main` workflow](https://git.kemitix.net/kemitix/git-next/actions?workflow=push-main.yml) to complete
|
||||||
3. Replace Release Notes body with details from CHANGELOG (remove crates and duplicates)
|
3. Replace [Release Notes](https://git.kemitix.net/kemitix/git-next/releases) body with details from [CHANGELOG](https://git.kemitix.net/kemitix/git-next/src/branch/main/CHANGELOG.md) (remove crates and duplicates)
|
||||||
4. Update thread: <https://mitra.kemitix.net/post/01907ef5-5bd9-b0b6-2b8a-e29762541d78>
|
4. Update thread: <https://mitra.kemitix.net/post/01907ef5-5bd9-b0b6-2b8a-e29762541d78>
|
||||||
|
|
||||||
## Detail
|
## Detail
|
||||||
|
|
|
@ -16,7 +16,7 @@ categories = { workspace = true }
|
||||||
default = ["forgejo", "github", "tui"]
|
default = ["forgejo", "github", "tui"]
|
||||||
forgejo = ["git-next-forge-forgejo"]
|
forgejo = ["git-next-forge-forgejo"]
|
||||||
github = ["git-next-forge-github"]
|
github = ["git-next-forge-github"]
|
||||||
tui = ["ratatui", "directories", "lazy_static", "tui-scrollview", "regex"]
|
tui = ["ratatui", "directories", "lazy_static", "tui-scrollview", "regex", "chrono"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
git-next-core = { workspace = true }
|
git-next-core = { workspace = true }
|
||||||
|
@ -30,6 +30,7 @@ lazy_static = { workspace = true, optional = true }
|
||||||
color-eyre = { workspace = true }
|
color-eyre = { workspace = true }
|
||||||
tui-scrollview = { workspace = true, optional = true }
|
tui-scrollview = { workspace = true, optional = true }
|
||||||
regex = { workspace = true, optional = true }
|
regex = { workspace = true, optional = true }
|
||||||
|
chrono = { workspace = true, optional = true }
|
||||||
|
|
||||||
# CLI parsing
|
# CLI parsing
|
||||||
clap = { workspace = true }
|
clap = { workspace = true }
|
||||||
|
@ -51,6 +52,7 @@ toml = { workspace = true }
|
||||||
# Actors
|
# Actors
|
||||||
actix = { workspace = true }
|
actix = { workspace = true }
|
||||||
actix-rt = { workspace = true }
|
actix-rt = { workspace = true }
|
||||||
|
tokio = { workspace = true }
|
||||||
|
|
||||||
# boilerplate
|
# boilerplate
|
||||||
bon = { workspace = true }
|
bon = { workspace = true }
|
||||||
|
|
|
@ -59,7 +59,7 @@ cargo install --path crates/cli
|
||||||
- [x] cli
|
- [x] cli
|
||||||
- [x] server
|
- [x] server
|
||||||
- [x] notifications - notify user when intervention required (e.g. to rebase)
|
- [x] notifications - notify user when intervention required (e.g. to rebase)
|
||||||
- [ ] tui overview
|
- [x] tui overview
|
||||||
- [ ] webui overview
|
- [ ] webui overview
|
||||||
|
|
||||||
## Branch Names
|
## Branch Names
|
||||||
|
@ -198,13 +198,14 @@ forge_type = "GitHub"
|
||||||
hostname = "github.com"
|
hostname = "github.com"
|
||||||
user = "username"
|
user = "username"
|
||||||
token = "api-key"
|
token = "api-key"
|
||||||
|
max_dev_commits = 25
|
||||||
```
|
```
|
||||||
|
|
||||||
- **forge_type** - one of: `ForgeJo` or `GitHub`
|
- **forge_type** - one of: `ForgeJo` or `GitHub`
|
||||||
- **hostname** - the hostname for the forge.
|
- **hostname** - the hostname for the forge.
|
||||||
- **user** - the user to authenticate as
|
- **user** - the user to authenticate as
|
||||||
- **token** - application token for the user. See below for the permissions
|
- **token** - application token for the user. See [Forges](#forges) below for the permissions required for each forge.
|
||||||
required for on each forge.
|
- **max_dev_commits** - [optional] the maximum number of commits allowed between `dev` and `main`. Defaults to 25.
|
||||||
|
|
||||||
Generally, the `user` will need to be able to push to `main` and to _force-push_
|
Generally, the `user` will need to be able to push to `main` and to _force-push_
|
||||||
to `next`.
|
to `next`.
|
||||||
|
@ -576,6 +577,58 @@ world = { repo = "user/world", branch = "master", main = "master", next = "upcom
|
||||||
|
|
||||||
The token is created [here](https://github.com/settings/tokens/new) and requires the `repo` and `admin:repo_hook` permissions.
|
The token is created [here](https://github.com/settings/tokens/new) and requires the `repo` and `admin:repo_hook` permissions.
|
||||||
|
|
||||||
|
## Docker
|
||||||
|
|
||||||
|
`git-next` is available as a [Docker image](https://git.kemitix.net/kemitix/-/packages/container/git-next/).
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker pull docker pull git.kemitix.net/kemitix/git-next:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker Compose
|
||||||
|
|
||||||
|
Here is an example `docker-compose.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
server:
|
||||||
|
image: git.kemitix.net/kemitix/git-next:latest
|
||||||
|
container_name: git-next-server
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
RUST_LOG: "hyper=warn,info"
|
||||||
|
ports:
|
||||||
|
- 8080:8092
|
||||||
|
volumes:
|
||||||
|
- ./:/app/
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: this assumes the `git-next-server.toml` has a `listen.http.port` of
|
||||||
|
`8092` and that you are using a reverse proxy to route traffic arriving at
|
||||||
|
`listen.url` to port `8080`.
|
||||||
|
|
||||||
|
### Docker Run
|
||||||
|
|
||||||
|
This will run with the `server start` options:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker run -it -p "8080:8092" -v .:/app/ git.kemitix.net/kemitix/git-next:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
To perform `server init`:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker run -it -v .:/app/ git.kemitix.net/kemitix/git-next:latest server init
|
||||||
|
```
|
||||||
|
|
||||||
|
To perform repo `init`:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker run -it -v .:/app/ git.kemitix.net/kemitix/git-next:latest init
|
||||||
|
```
|
||||||
|
|
||||||
|
TUI support is not available in the docker container. See [kemitix/git-next#154](https://git.kemitix.net/kemitix/git-next/issues/154).
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Contributions to `git-next` are welcome! If you find a bug or have a feature
|
Contributions to `git-next` are welcome! If you find a bug or have a feature
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
//
|
//
|
||||||
use git_next_core::{
|
use git_next_core::git::{ForgeLike, RepoDetails};
|
||||||
git::{ForgeLike, RepoDetails},
|
|
||||||
ForgeType,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(feature = "forgejo")]
|
#[cfg(feature = "forgejo")]
|
||||||
use git_next_forge_forgejo::ForgeJo;
|
use git_next_forge_forgejo::ForgeJo;
|
||||||
|
@ -19,10 +16,14 @@ impl Forge {
|
||||||
pub fn create(repo_details: RepoDetails, net: Network) -> Box<dyn ForgeLike> {
|
pub fn create(repo_details: RepoDetails, net: Network) -> Box<dyn ForgeLike> {
|
||||||
match repo_details.forge.forge_type() {
|
match repo_details.forge.forge_type() {
|
||||||
#[cfg(feature = "forgejo")]
|
#[cfg(feature = "forgejo")]
|
||||||
ForgeType::ForgeJo => Box::new(ForgeJo::new(repo_details, net)),
|
git_next_core::ForgeType::ForgeJo => Box::new(ForgeJo::new(repo_details, net)),
|
||||||
#[cfg(feature = "github")]
|
#[cfg(feature = "github")]
|
||||||
ForgeType::GitHub => Box::new(Github::new(repo_details, net)),
|
git_next_core::ForgeType::GitHub => Box::new(Github::new(repo_details, net)),
|
||||||
_ => unreachable!(),
|
_ => {
|
||||||
|
drop(repo_details);
|
||||||
|
drop(net);
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
//
|
//
|
||||||
|
#[cfg(any(feature = "forgejo", feature = "github"))]
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use git_next_core::{
|
use git_next_core::{
|
||||||
|
@ -11,7 +12,7 @@ use git_next_core::{
|
||||||
#[test]
|
#[test]
|
||||||
fn test_forgejo_name() {
|
fn test_forgejo_name() {
|
||||||
let net = Network::new_mock();
|
let net = Network::new_mock();
|
||||||
let repo_details = given_repo_details(ForgeType::ForgeJo);
|
let repo_details = given_repo_details(git_next_core::ForgeType::ForgeJo);
|
||||||
let forge = Forge::create(repo_details, net);
|
let forge = Forge::create(repo_details, net);
|
||||||
assert_eq!(forge.name(), "forgejo");
|
assert_eq!(forge.name(), "forgejo");
|
||||||
}
|
}
|
||||||
|
@ -20,20 +21,17 @@ fn test_forgejo_name() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_github_name() {
|
fn test_github_name() {
|
||||||
let net = Network::new_mock();
|
let net = Network::new_mock();
|
||||||
let repo_details = given_repo_details(ForgeType::GitHub);
|
let repo_details = given_repo_details(git_next_core::ForgeType::GitHub);
|
||||||
let forge = Forge::create(repo_details, net);
|
let forge = Forge::create(repo_details, net);
|
||||||
assert_eq!(forge.name(), "github");
|
assert_eq!(forge.name(), "github");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn given_fs() -> kxio::fs::FileSystem {
|
#[allow(dead_code)]
|
||||||
kxio::fs::temp().unwrap_or_else(|e| {
|
fn given_repo_details(forge_type: git_next_core::ForgeType) -> RepoDetails {
|
||||||
|
let fs = kxio::fs::temp().unwrap_or_else(|e| {
|
||||||
println!("{e}");
|
println!("{e}");
|
||||||
panic!("fs")
|
panic!("fs")
|
||||||
})
|
});
|
||||||
}
|
|
||||||
|
|
||||||
fn given_repo_details(forge_type: ForgeType) -> RepoDetails {
|
|
||||||
let fs = given_fs();
|
|
||||||
git::repo_details(
|
git::repo_details(
|
||||||
1,
|
1,
|
||||||
git::Generation::default(),
|
git::Generation::default(),
|
||||||
|
|
|
@ -19,7 +19,7 @@ use tracing::{info, instrument, warn};
|
||||||
pub fn advance_next(
|
pub fn advance_next(
|
||||||
commit: Option<Commit>,
|
commit: Option<Commit>,
|
||||||
force: git_next_core::git::push::Force,
|
force: git_next_core::git::push::Force,
|
||||||
repo_details: RepoDetails,
|
repo_details: &RepoDetails,
|
||||||
repo_config: RepoConfig,
|
repo_config: RepoConfig,
|
||||||
open_repository: &dyn OpenRepositoryLike,
|
open_repository: &dyn OpenRepositoryLike,
|
||||||
message_token: MessageToken,
|
message_token: MessageToken,
|
||||||
|
@ -29,7 +29,7 @@ pub fn advance_next(
|
||||||
info!("Advancing next to commit '{}'", commit);
|
info!("Advancing next to commit '{}'", commit);
|
||||||
reset(
|
reset(
|
||||||
open_repository,
|
open_repository,
|
||||||
&repo_details,
|
repo_details,
|
||||||
&repo_config.branches().next(),
|
&repo_config.branches().next(),
|
||||||
&commit.into(),
|
&commit.into(),
|
||||||
&force,
|
&force,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//
|
//
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
|
|
||||||
use git_next_core::RepoConfigSource;
|
use git_next_core::{git, RepoConfigSource};
|
||||||
|
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
|
|
||||||
|
@ -35,18 +35,25 @@ impl Handler<AdvanceMain> for RepoActor {
|
||||||
commit: commit.clone(),
|
commit: commit.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
match advance_main(commit, &repo_details, &repo_config, &**open_repository) {
|
if let Err(err) = advance_main(commit, &repo_details, &repo_config, &**open_repository) {
|
||||||
Err(err) => {
|
warn!("advance main: {err}");
|
||||||
warn!("advance main: {err}");
|
self.alert_tui(format!("advance main: {err}"));
|
||||||
|
} else {
|
||||||
|
self.update_tui(RepoUpdate::MainUpdated);
|
||||||
|
if let Some(open_repository) = &self.open_repository {
|
||||||
|
match open_repository.fetch() {
|
||||||
|
Ok(()) => self.update_tui_log(git::graph::log(&self.repo_details)),
|
||||||
|
Err(err) => self.alert_tui(format!("fetching: {err}")),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(()) => match repo_config.source() {
|
match repo_config.source() {
|
||||||
RepoConfigSource::Repo => {
|
RepoConfigSource::Repo => {
|
||||||
do_send(&addr, LoadConfigFromRepo, self.log.as_ref());
|
do_send(&addr, LoadConfigFromRepo, self.log.as_ref());
|
||||||
}
|
}
|
||||||
RepoConfigSource::Server => {
|
RepoConfigSource::Server => {
|
||||||
do_send(&addr, ValidateRepo::new(message_token), self.log.as_ref());
|
do_send(&addr, ValidateRepo::new(message_token), self.log.as_ref());
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//
|
//
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
|
|
||||||
|
use git_next_core::git;
|
||||||
use tracing::{warn, Instrument};
|
use tracing::{warn, Instrument};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -43,13 +44,18 @@ impl Handler<AdvanceNext> for RepoActor {
|
||||||
match advance_next(
|
match advance_next(
|
||||||
commit,
|
commit,
|
||||||
force,
|
force,
|
||||||
repo_details,
|
&repo_details,
|
||||||
repo_config,
|
repo_config,
|
||||||
&**open_repository,
|
&**open_repository,
|
||||||
self.message_token,
|
self.message_token,
|
||||||
) {
|
) {
|
||||||
Ok(message_token) => {
|
Ok(message_token) => {
|
||||||
// pause to allow any CI checks to be started
|
self.update_tui(RepoUpdate::NextUpdated);
|
||||||
|
match open_repository.fetch() {
|
||||||
|
Ok(()) => self.update_tui_log(git::graph::log(&self.repo_details)),
|
||||||
|
Err(err) => self.alert_tui(format!("fetching: {err}")),
|
||||||
|
}
|
||||||
|
// INFO: pause to allow any CI checks to be started
|
||||||
let sleep_duration = self.sleep_duration;
|
let sleep_duration = self.sleep_duration;
|
||||||
let log = self.log.clone();
|
let log = self.log.clone();
|
||||||
async move {
|
async move {
|
||||||
|
|
|
@ -17,21 +17,20 @@ impl Handler<ReceiveCIStatus> for RepoActor {
|
||||||
type Result = ();
|
type Result = ();
|
||||||
|
|
||||||
fn handle(&mut self, msg: ReceiveCIStatus, ctx: &mut Self::Context) -> Self::Result {
|
fn handle(&mut self, msg: ReceiveCIStatus, ctx: &mut Self::Context) -> Self::Result {
|
||||||
let log = self.log.clone();
|
logger(self.log.as_ref(), "start: ReceiveCIStatus");
|
||||||
logger(log.as_ref(), "start: ReceiveCIStatus");
|
|
||||||
let addr = ctx.address();
|
|
||||||
let (next, status) = msg.peel();
|
let (next, status) = msg.peel();
|
||||||
|
self.update_tui(RepoUpdate::ReceiveCIStatus {
|
||||||
|
status: status.clone(),
|
||||||
|
});
|
||||||
|
debug!(?status, "");
|
||||||
|
let graph_log = graph::log(&self.repo_details);
|
||||||
|
self.update_tui_log(graph_log.clone());
|
||||||
|
|
||||||
|
let addr = ctx.address();
|
||||||
let forge_alias = self.repo_details.forge.forge_alias().clone();
|
let forge_alias = self.repo_details.forge.forge_alias().clone();
|
||||||
let repo_alias = self.repo_details.repo_alias.clone();
|
let repo_alias = self.repo_details.repo_alias.clone();
|
||||||
let message_token = self.message_token;
|
let message_token = self.message_token;
|
||||||
let sleep_duration = self.sleep_duration;
|
let sleep_duration = self.sleep_duration;
|
||||||
let graph_log = graph::log(&self.repo_details);
|
|
||||||
self.update_tui_log(graph_log.clone());
|
|
||||||
self.update_tui(RepoUpdate::ReceiveCIStatus {
|
|
||||||
status: status.clone(),
|
|
||||||
});
|
|
||||||
|
|
||||||
debug!(?status, "");
|
|
||||||
match status {
|
match status {
|
||||||
Status::Pass => {
|
Status::Pass => {
|
||||||
do_send(&addr, AdvanceMain::new(next), self.log.as_ref());
|
do_send(&addr, AdvanceMain::new(next), self.log.as_ref());
|
||||||
|
@ -57,8 +56,9 @@ impl Handler<ReceiveCIStatus> for RepoActor {
|
||||||
commit: next,
|
commit: next,
|
||||||
log: graph_log,
|
log: graph_log,
|
||||||
},
|
},
|
||||||
log.as_ref(),
|
self.log.as_ref(),
|
||||||
);
|
);
|
||||||
|
let log = self.log.clone();
|
||||||
async move {
|
async move {
|
||||||
debug!("sleeping before retrying...");
|
debug!("sleeping before retrying...");
|
||||||
logger(log.as_ref(), "before sleep");
|
logger(log.as_ref(), "before sleep");
|
||||||
|
|
|
@ -79,7 +79,6 @@ impl Handler<ValidateRepo> for RepoActor {
|
||||||
self.update_tui_log(git_log);
|
self.update_tui_log(git_log);
|
||||||
if next_is_valid && next != main {
|
if next_is_valid && next != main {
|
||||||
info!("Checking CI");
|
info!("Checking CI");
|
||||||
self.update_tui(RepoUpdate::CheckingCI);
|
|
||||||
do_send(&ctx.address(), CheckCIStatus::new(next), self.log.as_ref());
|
do_send(&ctx.address(), CheckCIStatus::new(next), self.log.as_ref());
|
||||||
} else if next != dev {
|
} else if next != dev {
|
||||||
info!("Advance next");
|
info!("Advance next");
|
||||||
|
|
|
@ -99,8 +99,7 @@ impl RepoActor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_tui_branches(&self) {
|
fn update_tui_branches(&self) {
|
||||||
#[cfg(feature = "tui")]
|
if cfg!(feature = "tui") {
|
||||||
{
|
|
||||||
use crate::server::actor::messages::RepoUpdate;
|
use crate::server::actor::messages::RepoUpdate;
|
||||||
let Some(repo_config) = &self.repo_details.repo_config else {
|
let Some(repo_config) = &self.repo_details.repo_config else {
|
||||||
return;
|
return;
|
||||||
|
@ -112,16 +111,14 @@ impl RepoActor {
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn update_tui_log(&self, log: git::graph::Log) {
|
fn update_tui_log(&self, log: git::graph::Log) {
|
||||||
#[cfg(feature = "tui")]
|
if cfg!(feature = "tui") {
|
||||||
{
|
|
||||||
self.update_tui(RepoUpdate::Log { log });
|
self.update_tui(RepoUpdate::Log { log });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn alert_tui(&self, alert: impl Into<String>) {
|
fn alert_tui(&self, alert: impl Into<String>) {
|
||||||
#[cfg(feature = "tui")]
|
if cfg!(feature = "tui") {
|
||||||
{
|
|
||||||
self.update_tui(RepoUpdate::Alert {
|
self.update_tui(RepoUpdate::Alert {
|
||||||
alert: alert.into(),
|
alert: alert.into(),
|
||||||
});
|
});
|
||||||
|
@ -130,8 +127,7 @@ impl RepoActor {
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn update_tui(&self, repo_update: RepoUpdate) {
|
fn update_tui(&self, repo_update: RepoUpdate) {
|
||||||
#[cfg(feature = "tui")]
|
if cfg!(feature = "tui") {
|
||||||
{
|
|
||||||
let Some(server_addr) = &self.server_addr else {
|
let Some(server_addr) = &self.server_addr else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,7 @@ fn advance_next_sut(
|
||||||
next: &Commit,
|
next: &Commit,
|
||||||
main: &Commit,
|
main: &Commit,
|
||||||
dev_commit_history: &[Commit],
|
dev_commit_history: &[Commit],
|
||||||
repo_details: RepoDetails,
|
repo_details: &RepoDetails,
|
||||||
repo_config: RepoConfig,
|
repo_config: RepoConfig,
|
||||||
open_repository: &dyn OpenRepositoryLike,
|
open_repository: &dyn OpenRepositoryLike,
|
||||||
message_token: MessageToken,
|
message_token: MessageToken,
|
||||||
|
@ -42,7 +42,7 @@ mod when_at_dev {
|
||||||
&next,
|
&next,
|
||||||
main,
|
main,
|
||||||
dev_commit_history,
|
dev_commit_history,
|
||||||
repo_details,
|
&repo_details,
|
||||||
repo_config,
|
repo_config,
|
||||||
&open_repository,
|
&open_repository,
|
||||||
message_token,
|
message_token,
|
||||||
|
@ -77,7 +77,7 @@ mod can_advance {
|
||||||
&next,
|
&next,
|
||||||
main,
|
main,
|
||||||
dev_commit_history,
|
dev_commit_history,
|
||||||
repo_details,
|
&repo_details,
|
||||||
repo_config,
|
repo_config,
|
||||||
&open_repository,
|
&open_repository,
|
||||||
message_token,
|
message_token,
|
||||||
|
@ -108,7 +108,7 @@ mod can_advance {
|
||||||
&next,
|
&next,
|
||||||
main,
|
main,
|
||||||
dev_commit_history,
|
dev_commit_history,
|
||||||
repo_details,
|
&repo_details,
|
||||||
repo_config,
|
repo_config,
|
||||||
&open_repository,
|
&open_repository,
|
||||||
message_token,
|
message_token,
|
||||||
|
@ -148,7 +148,7 @@ mod can_advance {
|
||||||
&next,
|
&next,
|
||||||
main,
|
main,
|
||||||
dev_commit_history,
|
dev_commit_history,
|
||||||
repo_details,
|
&repo_details,
|
||||||
repo_config,
|
repo_config,
|
||||||
&open_repository,
|
&open_repository,
|
||||||
message_token,
|
message_token,
|
||||||
|
@ -180,7 +180,7 @@ mod can_advance {
|
||||||
&next,
|
&next,
|
||||||
main,
|
main,
|
||||||
dev_commit_history,
|
dev_commit_history,
|
||||||
repo_details,
|
&repo_details,
|
||||||
repo_config,
|
repo_config,
|
||||||
&open_repository,
|
&open_repository,
|
||||||
message_token,
|
message_token,
|
||||||
|
|
|
@ -69,6 +69,22 @@ pub fn a_name() -> String {
|
||||||
generate(5)
|
generate(5)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn maybe_a_number() -> Option<u32> {
|
||||||
|
use rand::Rng;
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
if Rng::gen_ratio(&mut rng, 1, 2) {
|
||||||
|
Some(a_number())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn a_number() -> u32 {
|
||||||
|
use rand::Rng;
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
rng.gen_range(0..100)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn a_webhook_id() -> WebhookId {
|
pub fn a_webhook_id() -> WebhookId {
|
||||||
WebhookId::new(a_name())
|
WebhookId::new(a_name())
|
||||||
}
|
}
|
||||||
|
@ -89,6 +105,7 @@ pub fn a_forge_config() -> ForgeConfig {
|
||||||
a_name(),
|
a_name(),
|
||||||
a_name(),
|
a_name(),
|
||||||
a_name(),
|
a_name(),
|
||||||
|
maybe_a_number(),
|
||||||
BTreeMap::default(), // no repos
|
BTreeMap::default(), // no repos
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,11 @@ async fn when_repo_config_should_fetch_then_push_then_revalidate() -> TestResult
|
||||||
.times(1)
|
.times(1)
|
||||||
.in_sequence(&mut seq)
|
.in_sequence(&mut seq)
|
||||||
.return_once(|_, _, _, _| Ok(()));
|
.return_once(|_, _, _, _| Ok(()));
|
||||||
|
open_repository
|
||||||
|
.expect_fetch()
|
||||||
|
.times(1)
|
||||||
|
.in_sequence(&mut seq)
|
||||||
|
.return_once(|| Ok(()));
|
||||||
|
|
||||||
//when
|
//when
|
||||||
let (addr, log) = when::start_actor_with_open_repository(
|
let (addr, log) = when::start_actor_with_open_repository(
|
||||||
|
@ -70,6 +75,11 @@ async fn when_app_config_should_fetch_then_push_then_revalidate() -> TestResult
|
||||||
.times(1)
|
.times(1)
|
||||||
.in_sequence(&mut seq)
|
.in_sequence(&mut seq)
|
||||||
.return_once(|_, _, _, _| Ok(()));
|
.return_once(|_, _, _, _| Ok(()));
|
||||||
|
open_repository
|
||||||
|
.expect_fetch()
|
||||||
|
.times(1)
|
||||||
|
.in_sequence(&mut seq)
|
||||||
|
.return_once(|| Ok(()));
|
||||||
|
|
||||||
//when
|
//when
|
||||||
let (addr, log) = when::start_actor_with_open_repository(
|
let (addr, log) = when::start_actor_with_open_repository(
|
||||||
|
@ -83,10 +93,6 @@ async fn when_app_config_should_fetch_then_push_then_revalidate() -> TestResult
|
||||||
|
|
||||||
//then
|
//then
|
||||||
tracing::debug!(?log, "");
|
tracing::debug!(?log, "");
|
||||||
log.read().map_err(|e| e.to_string()).map(|l| {
|
log.require_message_containing("send: ValidateRepo")?;
|
||||||
assert!(l
|
|
||||||
.iter()
|
|
||||||
.any(|message| message.contains("send: ValidateRepo")));
|
|
||||||
})?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,11 @@ async fn should_fetch_then_push_then_revalidate() -> TestResult {
|
||||||
.times(1)
|
.times(1)
|
||||||
.in_sequence(&mut seq)
|
.in_sequence(&mut seq)
|
||||||
.return_once(|_, _, _, _| Ok(()));
|
.return_once(|_, _, _, _| Ok(()));
|
||||||
|
open_repository
|
||||||
|
.expect_fetch()
|
||||||
|
.times(1)
|
||||||
|
.in_sequence(&mut seq)
|
||||||
|
.return_once(|| Ok(()));
|
||||||
|
|
||||||
//when
|
//when
|
||||||
let (addr, log) = when::start_actor_with_open_repository(
|
let (addr, log) = when::start_actor_with_open_repository(
|
||||||
|
|
|
@ -43,6 +43,10 @@ async fn should_open() -> TestResult {
|
||||||
//given
|
//given
|
||||||
let fs = given::a_filesystem();
|
let fs = given::a_filesystem();
|
||||||
let (mut open_repository, repo_details) = given::an_open_repository(&fs);
|
let (mut open_repository, repo_details) = given::an_open_repository(&fs);
|
||||||
|
open_repository
|
||||||
|
.expect_fetch()
|
||||||
|
.times(1)
|
||||||
|
.return_once(|| Ok(()));
|
||||||
given::has_all_valid_remote_defaults(&mut open_repository, &repo_details);
|
given::has_all_valid_remote_defaults(&mut open_repository, &repo_details);
|
||||||
// factory opens a repository
|
// factory opens a repository
|
||||||
let mut repository_factory = MockRepositoryFactory::new();
|
let mut repository_factory = MockRepositoryFactory::new();
|
||||||
|
@ -79,6 +83,10 @@ async fn when_server_has_no_repo_config_should_send_load_from_repo() -> TestResu
|
||||||
//given
|
//given
|
||||||
let fs = given::a_filesystem();
|
let fs = given::a_filesystem();
|
||||||
let (mut open_repository, mut repo_details) = given::an_open_repository(&fs);
|
let (mut open_repository, mut repo_details) = given::an_open_repository(&fs);
|
||||||
|
open_repository
|
||||||
|
.expect_fetch()
|
||||||
|
.times(1)
|
||||||
|
.return_once(|| Ok(()));
|
||||||
#[allow(clippy::unwrap_used)]
|
#[allow(clippy::unwrap_used)]
|
||||||
let _repo_config = repo_details.repo_config.take().unwrap();
|
let _repo_config = repo_details.repo_config.take().unwrap();
|
||||||
|
|
||||||
|
@ -106,6 +114,10 @@ async fn when_server_has_repo_config_should_send_register_webhook() -> TestResul
|
||||||
//given
|
//given
|
||||||
let fs = given::a_filesystem();
|
let fs = given::a_filesystem();
|
||||||
let (mut open_repository, repo_details) = given::an_open_repository(&fs);
|
let (mut open_repository, repo_details) = given::an_open_repository(&fs);
|
||||||
|
open_repository
|
||||||
|
.expect_fetch()
|
||||||
|
.times(1)
|
||||||
|
.return_once(|| Ok(()));
|
||||||
#[allow(clippy::unwrap_used)]
|
#[allow(clippy::unwrap_used)]
|
||||||
given::has_all_valid_remote_defaults(&mut open_repository, &repo_details);
|
given::has_all_valid_remote_defaults(&mut open_repository, &repo_details);
|
||||||
|
|
||||||
|
@ -129,6 +141,10 @@ async fn opened_repo_with_no_default_push_should_not_proceed() -> TestResult {
|
||||||
//given
|
//given
|
||||||
let fs = given::a_filesystem();
|
let fs = given::a_filesystem();
|
||||||
let (mut open_repository, repo_details) = given::an_open_repository(&fs);
|
let (mut open_repository, repo_details) = given::an_open_repository(&fs);
|
||||||
|
open_repository
|
||||||
|
.expect_fetch()
|
||||||
|
.times(1)
|
||||||
|
.return_once(|| Ok(()));
|
||||||
|
|
||||||
given::has_remote_defaults(
|
given::has_remote_defaults(
|
||||||
&mut open_repository,
|
&mut open_repository,
|
||||||
|
@ -158,15 +174,10 @@ async fn opened_repo_with_no_default_fetch_should_not_proceed() -> TestResult {
|
||||||
//given
|
//given
|
||||||
let fs = given::a_filesystem();
|
let fs = given::a_filesystem();
|
||||||
let (mut open_repository, repo_details) = given::an_open_repository(&fs);
|
let (mut open_repository, repo_details) = given::an_open_repository(&fs);
|
||||||
|
open_repository
|
||||||
given::has_remote_defaults(
|
.expect_fetch()
|
||||||
&mut open_repository,
|
.times(1)
|
||||||
HashMap::from([
|
.return_once(|| Err(git::fetch::Error::NoFetchRemoteFound));
|
||||||
(Direction::Push, repo_details.remote_url()),
|
|
||||||
(Direction::Fetch, None),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut repository_factory = MockRepositoryFactory::new();
|
let mut repository_factory = MockRepositoryFactory::new();
|
||||||
expect::open_repository(&mut repository_factory, open_repository);
|
expect::open_repository(&mut repository_factory, open_repository);
|
||||||
fs.dir_create(&repo_details.gitdir)?;
|
fs.dir_create(&repo_details.gitdir)?;
|
||||||
|
|
|
@ -3,4 +3,5 @@ mod receive_app_config;
|
||||||
mod receive_valid_app_config;
|
mod receive_valid_app_config;
|
||||||
mod server_update;
|
mod server_update;
|
||||||
mod shutdown;
|
mod shutdown;
|
||||||
|
mod shutdown_trigger;
|
||||||
mod subscribe_updates;
|
mod subscribe_updates;
|
||||||
|
|
12
crates/cli/src/server/actor/handlers/shutdown_trigger.rs
Normal file
12
crates/cli/src/server/actor/handlers/shutdown_trigger.rs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
//
|
||||||
|
use actix::Handler;
|
||||||
|
|
||||||
|
use crate::server::{actor::messages::ShutdownTrigger, ServerActor};
|
||||||
|
|
||||||
|
impl Handler<ShutdownTrigger> for ServerActor {
|
||||||
|
type Result = ();
|
||||||
|
|
||||||
|
fn handle(&mut self, msg: ShutdownTrigger, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
self.shutdown_trigger.replace(msg.peel());
|
||||||
|
}
|
||||||
|
}
|
|
@ -92,6 +92,8 @@ pub enum RepoUpdate {
|
||||||
},
|
},
|
||||||
RegisteredWebhook,
|
RegisteredWebhook,
|
||||||
Opened,
|
Opened,
|
||||||
|
NextUpdated,
|
||||||
|
MainUpdated,
|
||||||
}
|
}
|
||||||
|
|
||||||
message!(
|
message!(
|
||||||
|
@ -99,3 +101,13 @@ message!(
|
||||||
Recipient<ServerUpdate>,
|
Recipient<ServerUpdate>,
|
||||||
"Subscribe to receive updates from the server"
|
"Subscribe to receive updates from the server"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// Sends a channel to be used to shutdown the server
|
||||||
|
#[derive(Message, Constructor)]
|
||||||
|
#[rtype(result = "()")]
|
||||||
|
pub struct ShutdownTrigger(std::sync::mpsc::Sender<String>);
|
||||||
|
impl ShutdownTrigger {
|
||||||
|
pub fn peel(self) -> std::sync::mpsc::Sender<String> {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
use messages::{ReceiveAppConfig, ServerUpdate};
|
use messages::{ReceiveAppConfig, ServerUpdate, Shutdown};
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -58,6 +58,7 @@ pub struct ServerActor {
|
||||||
sleep_duration: std::time::Duration,
|
sleep_duration: std::time::Duration,
|
||||||
repo_actors: BTreeMap<(ForgeAlias, RepoAlias), Addr<RepoActor>>,
|
repo_actors: BTreeMap<(ForgeAlias, RepoAlias), Addr<RepoActor>>,
|
||||||
|
|
||||||
|
shutdown_trigger: Option<std::sync::mpsc::Sender<String>>,
|
||||||
subscribers: Vec<Recipient<ServerUpdate>>,
|
subscribers: Vec<Recipient<ServerUpdate>>,
|
||||||
|
|
||||||
// testing
|
// testing
|
||||||
|
@ -84,6 +85,7 @@ impl ServerActor {
|
||||||
net,
|
net,
|
||||||
alerts,
|
alerts,
|
||||||
repository_factory: repo,
|
repository_factory: repo,
|
||||||
|
shutdown_trigger: None,
|
||||||
subscribers: Vec::default(),
|
subscribers: Vec::default(),
|
||||||
sleep_duration,
|
sleep_duration,
|
||||||
repo_actors: BTreeMap::new(),
|
repo_actors: BTreeMap::new(),
|
||||||
|
@ -228,10 +230,15 @@ impl ServerActor {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to gracefully shutdown the server before stopping the system.
|
/// Attempts to gracefully shutdown the server before stopping the system.
|
||||||
fn abort(&self, ctx: &<Self as actix::Actor>::Context, message: impl Into<String>) {
|
fn abort(&mut self, ctx: &<Self as actix::Actor>::Context, message: impl Into<String>) {
|
||||||
tracing::error!("Aborting: {}", message.into());
|
|
||||||
self.do_send(crate::server::actor::messages::Shutdown, ctx);
|
self.do_send(crate::server::actor::messages::Shutdown, ctx);
|
||||||
System::current().stop_with_code(1);
|
if let Some(t) = self.shutdown_trigger.take() {
|
||||||
|
let _ = t.send(message.into());
|
||||||
|
} else {
|
||||||
|
error!("{}", message.into());
|
||||||
|
self.do_send(Shutdown, ctx);
|
||||||
|
// System::current().stop_with_code(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_send<M>(&self, msg: M, ctx: &<Self as actix::Actor>::Context)
|
fn do_send<M>(&self, msg: M, ctx: &<Self as actix::Actor>::Context)
|
||||||
|
|
|
@ -6,6 +6,7 @@ mod tests;
|
||||||
|
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
use actix_rt::signal;
|
use actix_rt::signal;
|
||||||
|
use actor::messages::ShutdownTrigger;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
alerts::{AlertsActor, History},
|
alerts::{AlertsActor, History},
|
||||||
|
@ -19,11 +20,11 @@ use git_next_core::git::RepositoryFactory;
|
||||||
|
|
||||||
use color_eyre::{eyre::Context, Result};
|
use color_eyre::{eyre::Context, Result};
|
||||||
use kxio::{fs::FileSystem, network::Network};
|
use kxio::{fs::FileSystem, network::Network};
|
||||||
use tracing::{error, info};
|
use tracing::info;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
sync::{atomic::Ordering, Arc, RwLock},
|
sync::{atomic::Ordering, mpsc::channel, Arc, RwLock},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -45,6 +46,7 @@ pub fn init(fs: &FileSystem) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_lines)]
|
||||||
pub fn start(
|
pub fn start(
|
||||||
ui: bool,
|
ui: bool,
|
||||||
fs: FileSystem,
|
fs: FileSystem,
|
||||||
|
@ -61,8 +63,10 @@ pub fn start(
|
||||||
init_logging();
|
init_logging();
|
||||||
}
|
}
|
||||||
|
|
||||||
let file_watcher_err_channel: Arc<RwLock<Option<anyhow::Error>>> = Arc::new(RwLock::new(None));
|
let shutdown_message_holder: Arc<RwLock<Option<String>>> = Arc::new(RwLock::new(None));
|
||||||
let file_watcher_err_channel_exec = file_watcher_err_channel.clone();
|
let shutdown_message_holder_exec = shutdown_message_holder.clone();
|
||||||
|
let file_watcher_err_holder: Arc<RwLock<Option<anyhow::Error>>> = Arc::new(RwLock::new(None));
|
||||||
|
let file_watcher_err_holder_exec = file_watcher_err_holder.clone();
|
||||||
let execution = async move {
|
let execution = async move {
|
||||||
info!("Starting Alert Dispatcher...");
|
info!("Starting Alert Dispatcher...");
|
||||||
let alerts_addr = AlertsActor::new(None, History::new(A_DAY), net.clone()).start();
|
let alerts_addr = AlertsActor::new(None, History::new(A_DAY), net.clone()).start();
|
||||||
|
@ -80,37 +84,58 @@ pub fn start(
|
||||||
server.do_send(crate::server::actor::messages::Shutdown);
|
server.do_send(crate::server::actor::messages::Shutdown);
|
||||||
actix_rt::time::sleep(std::time::Duration::from_millis(10)).await;
|
actix_rt::time::sleep(std::time::Duration::from_millis(10)).await;
|
||||||
System::current().stop();
|
System::current().stop();
|
||||||
let _ = file_watcher_err_channel_exec
|
let _ = file_watcher_err_holder_exec
|
||||||
.write()
|
.write()
|
||||||
.map(|mut o| o.replace(err));
|
.map(|mut o| o.replace(err));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let (tx_shutdown, rx_shutdown) = channel::<String>();
|
||||||
if ui {
|
if ui {
|
||||||
#[cfg(feature = "tui")]
|
#[cfg(feature = "tui")]
|
||||||
{
|
{
|
||||||
use crate::server::actor::messages::SubscribeToUpdates;
|
use crate::server::actor::messages::SubscribeToUpdates;
|
||||||
use crate::tui;
|
use crate::tui;
|
||||||
use std::sync::mpsc::channel;
|
|
||||||
|
|
||||||
let (tx_shutdown, rx_shutdown) = channel::<()>();
|
let tui_addr = tui::Tui::new(tx_shutdown.clone()).start();
|
||||||
let tui_addr = tui::Tui::new(tx_shutdown).start();
|
|
||||||
server.do_send(SubscribeToUpdates::new(tui_addr.clone().recipient()));
|
server.do_send(SubscribeToUpdates::new(tui_addr.clone().recipient()));
|
||||||
|
server.do_send(ShutdownTrigger::new(tx_shutdown));
|
||||||
server.do_send(FileUpdated); // update file after ui subscription in place
|
server.do_send(FileUpdated); // update file after ui subscription in place
|
||||||
loop {
|
loop {
|
||||||
let _ = tui_addr.send(tui::Tick).await;
|
let _ = tui_addr.send(tui::Tick).await;
|
||||||
if rx_shutdown.try_recv().is_ok() {
|
if let Ok(message) = rx_shutdown.try_recv() {
|
||||||
|
let _ = shutdown_message_holder_exec
|
||||||
|
.write()
|
||||||
|
.map(|mut o| o.replace(message));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
actix_rt::time::sleep(Duration::from_millis(16)).await;
|
actix_rt::time::sleep(Duration::from_millis(16)).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
server.do_send(ShutdownTrigger::new(tx_shutdown.clone()));
|
||||||
server.do_send(FileUpdated);
|
server.do_send(FileUpdated);
|
||||||
|
|
||||||
info!("Server running - Press Ctrl-C to stop...");
|
info!("Server running - Press Ctrl-C to stop...");
|
||||||
let _ = signal::ctrl_c().await;
|
tokio::select! {
|
||||||
info!("Ctrl-C received, shutting down...");
|
_r = signal::ctrl_c() => {
|
||||||
|
info!("Ctrl-C received, shutting down...");
|
||||||
|
}
|
||||||
|
_x = async move {
|
||||||
|
loop{
|
||||||
|
if let Ok(message) = rx_shutdown.try_recv() {
|
||||||
|
let _ = shutdown_message_holder_exec
|
||||||
|
.write()
|
||||||
|
.map(|mut o| o.replace(message));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
actix_rt::task::yield_now().await;
|
||||||
|
}
|
||||||
|
} => {
|
||||||
|
info!("signaled shutdown");
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// shutdown
|
// shutdown
|
||||||
|
@ -124,13 +149,25 @@ pub fn start(
|
||||||
Arbiter::current().spawn(execution);
|
Arbiter::current().spawn(execution);
|
||||||
system.run()?;
|
system.run()?;
|
||||||
|
|
||||||
|
// check for error from server thread
|
||||||
|
#[allow(clippy::unwrap_used)]
|
||||||
|
if let Some(err) = &*shutdown_message_holder.read().unwrap() {
|
||||||
|
#[cfg(feature = "tui")]
|
||||||
|
if ui {
|
||||||
|
ratatui::restore();
|
||||||
|
}
|
||||||
|
if !err.is_empty() {
|
||||||
|
return Err(color_eyre::eyre::eyre!(format!("{err}")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check for error from file watcher thread
|
// check for error from file watcher thread
|
||||||
#[allow(clippy::unwrap_used)]
|
#[allow(clippy::unwrap_used)]
|
||||||
if let Some(err) = &*file_watcher_err_channel.read().unwrap() {
|
if let Some(err) = &*file_watcher_err_holder.read().unwrap() {
|
||||||
|
#[cfg(feature = "tui")]
|
||||||
if ui {
|
if ui {
|
||||||
eprintln!("File Watcher: {err:?}");
|
ratatui::restore();
|
||||||
}
|
}
|
||||||
error!(?err, "file watcher");
|
|
||||||
return Err(color_eyre::eyre::eyre!(format!("{err}")));
|
return Err(color_eyre::eyre::eyre!(format!("{err}")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ use git_next_core::{
|
||||||
ApiToken, ForgeType, GitDir, Hostname, RepoBranches, RepoConfig, RepoConfigSource, RepoPath,
|
ApiToken, ForgeType, GitDir, Hostname, RepoBranches, RepoConfig, RepoConfigSource, RepoPath,
|
||||||
StoragePathType, User,
|
StoragePathType, User,
|
||||||
};
|
};
|
||||||
use secrecy::Secret;
|
use secrecy::SecretString;
|
||||||
|
|
||||||
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
||||||
|
|
||||||
|
@ -59,10 +59,13 @@ fn repo_details_find_default_push_remote_finds_correct_remote() -> Result<()> {
|
||||||
repo_details.forge = repo_details
|
repo_details.forge = repo_details
|
||||||
.forge
|
.forge
|
||||||
.with_user(User::new("git".to_string()))
|
.with_user(User::new("git".to_string()))
|
||||||
.with_token(ApiToken::new(Secret::new(String::new())))
|
.with_token(ApiToken::new(SecretString::from(String::new())))
|
||||||
.with_hostname(Hostname::new("git.kemitix.net"));
|
.with_hostname(Hostname::new("git.kemitix.net"));
|
||||||
repo_details.repo_path = RepoPath::new("kemitix/git-next".to_string());
|
repo_details.repo_path = RepoPath::new("kemitix/git-next".to_string());
|
||||||
let open_repository = git::repository::factory::real().open(&repo_details)?;
|
let Ok(open_repository) = git::repository::factory::real().open(&repo_details) else {
|
||||||
|
// .git directory may not be present on dev environment
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
let_assert!(
|
let_assert!(
|
||||||
Some(found_git_remote) = open_repository.find_default_remote(Direction::Push),
|
Some(found_git_remote) = open_repository.find_default_remote(Direction::Push),
|
||||||
"Default Push Remote not found"
|
"Default Push Remote not found"
|
||||||
|
@ -92,13 +95,13 @@ fn gitdir_validate_should_pass_a_valid_git_repo() -> Result<()> {
|
||||||
repo_details.forge = repo_details
|
repo_details.forge = repo_details
|
||||||
.forge
|
.forge
|
||||||
.with_user(User::new("git".to_string()))
|
.with_user(User::new("git".to_string()))
|
||||||
.with_token(ApiToken::new(Secret::new(String::new())))
|
.with_token(ApiToken::new(SecretString::from(String::new())))
|
||||||
.with_hostname(Hostname::new("git.kemitix.net"));
|
.with_hostname(Hostname::new("git.kemitix.net"));
|
||||||
tracing::debug!("opening...");
|
tracing::debug!("opening...");
|
||||||
let_assert!(
|
let Ok(repository) = git::repository::factory::real().open(&repo_details) else {
|
||||||
Ok(repository) = git::repository::factory::real().open(&repo_details),
|
// .git directory may not be present on dev environment
|
||||||
"open repository"
|
return Ok(());
|
||||||
);
|
};
|
||||||
tracing::debug!("open okay");
|
tracing::debug!("open okay");
|
||||||
tracing::info!(?repository, "FOO");
|
tracing::info!(?repository, "FOO");
|
||||||
tracing::info!(?repo_details, "BAR");
|
tracing::info!(?repo_details, "BAR");
|
||||||
|
@ -108,11 +111,13 @@ fn gitdir_validate_should_pass_a_valid_git_repo() -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn gitdir_validate_should_fail_a_git_repo_with_wrong_remote() -> Result<()> {
|
fn gitdir_validate_should_fail_a_git_repo_with_wrong_remote() {
|
||||||
let_assert!(
|
let_assert!(
|
||||||
Ok(cli_crate_dir) = std::env::current_dir().map_err(git::validation::remotes::Error::Io)
|
Ok(cli_crate_dir) = std::env::current_dir().map_err(git::validation::remotes::Error::Io)
|
||||||
);
|
);
|
||||||
|
eprintln!("cli_crate_dir: {cli_crate_dir:?}");
|
||||||
let_assert!(Some(Some(root)) = cli_crate_dir.parent().map(|p| p.parent()));
|
let_assert!(Some(Some(root)) = cli_crate_dir.parent().map(|p| p.parent()));
|
||||||
|
eprintln!("root: {root:?}");
|
||||||
let mut repo_details = git::repo_details(
|
let mut repo_details = git::repo_details(
|
||||||
1,
|
1,
|
||||||
git::Generation::default(),
|
git::Generation::default(),
|
||||||
|
@ -124,16 +129,17 @@ fn gitdir_validate_should_fail_a_git_repo_with_wrong_remote() -> Result<()> {
|
||||||
repo_details.forge = repo_details
|
repo_details.forge = repo_details
|
||||||
.forge
|
.forge
|
||||||
.with_user(User::new("git".to_string()))
|
.with_user(User::new("git".to_string()))
|
||||||
.with_token(ApiToken::new(Secret::new(String::new())))
|
.with_token(ApiToken::new(SecretString::from(String::new())))
|
||||||
.with_hostname(Hostname::new("git.kemitix.net"));
|
.with_hostname(Hostname::new("git.kemitix.net"));
|
||||||
let repository = git::repository::factory::real().open(&repo_details)?;
|
let Ok(repository) = git::repository::factory::real().open(&repo_details) else {
|
||||||
|
// .git directory may not be present on dev environment
|
||||||
|
return;
|
||||||
|
};
|
||||||
let mut repo_details = repo_details.clone();
|
let mut repo_details = repo_details.clone();
|
||||||
repo_details.forge = repo_details
|
repo_details.forge = repo_details
|
||||||
.forge
|
.forge
|
||||||
.with_hostname(Hostname::new("code.kemitix.net"));
|
.with_hostname(Hostname::new("code.kemitix.net"));
|
||||||
let_assert!(Err(_) = validate_default_remotes(&*repository, &repo_details));
|
let_assert!(Err(_) = validate_default_remotes(&*repository, &repo_details));
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -8,6 +8,19 @@ The build `git-next` with the Terminal UI use: `cargo install git-next --feature
|
||||||
|
|
||||||
To run `git-next` with the Terminal UI use: `git-next server start --ui`
|
To run `git-next` with the Terminal UI use: `git-next server start --ui`
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
|
||||||
|
If using the docker image you will need to create a directory to mount that contains the
|
||||||
|
`git-next-server.toml` file. Mount this directory as `/app`. In the example below we use
|
||||||
|
the current directory for this.
|
||||||
|
|
||||||
|
If you want to persist the clones of your monitored repos then point `storage.path` in
|
||||||
|
`git-next-server.toml` to the the directory `/app`, (e.g. `path = "/app/data"`).
|
||||||
|
|
||||||
|
Map the port your webhook notifications are arriving on to the port specified in `listen.http.port`.
|
||||||
|
|
||||||
|
`docker run -it -p "8080:8092" -v .:/app/ git.kemitix.net/kemitix/git-next:latest server start --ui`
|
||||||
|
|
||||||
## logs
|
## logs
|
||||||
|
|
||||||
When the Terminal UI is enabled via the `--ui` parameter, logs are written to the file:
|
When the Terminal UI is enabled via the `--ui` parameter, logs are written to the file:
|
||||||
|
|
|
@ -34,6 +34,7 @@ impl Handler<ServerUpdate> for Tui {
|
||||||
let Some(repo_state) = forge_state.repos.get_mut(&repo_alias) else {
|
let Some(repo_state) = forge_state.repos.get_mut(&repo_alias) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
repo_state.clear_alert();
|
||||||
match repo_update {
|
match repo_update {
|
||||||
RepoUpdate::Branches { branches } => {
|
RepoUpdate::Branches { branches } => {
|
||||||
repo_state.update_branches(branches);
|
repo_state.update_branches(branches);
|
||||||
|
@ -57,10 +58,16 @@ impl Handler<ServerUpdate> for Tui {
|
||||||
repo_state
|
repo_state
|
||||||
.update_message(format!("advancing next to {commit}"), ACTING);
|
.update_message(format!("advancing next to {commit}"), ACTING);
|
||||||
}
|
}
|
||||||
|
RepoUpdate::NextUpdated => {
|
||||||
|
repo_state.update_message("next updated - pause while CI starts", OKAY);
|
||||||
|
}
|
||||||
RepoUpdate::AdvancingMain { commit } => {
|
RepoUpdate::AdvancingMain { commit } => {
|
||||||
repo_state
|
repo_state
|
||||||
.update_message(format!("advancing main to {commit}"), ACTING);
|
.update_message(format!("advancing main to {commit}"), ACTING);
|
||||||
}
|
}
|
||||||
|
RepoUpdate::MainUpdated => {
|
||||||
|
repo_state.update_message("main updated", OKAY);
|
||||||
|
}
|
||||||
RepoUpdate::Opening => {
|
RepoUpdate::Opening => {
|
||||||
repo_state.update_message("opening...", PREP);
|
repo_state.update_message("opening...", PREP);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,9 @@ mod handlers;
|
||||||
pub mod messages;
|
pub mod messages;
|
||||||
mod model;
|
mod model;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
|
|
||||||
use actix::{Actor, ActorContext as _, Context};
|
use actix::{Actor, ActorContext as _, Context};
|
||||||
|
@ -18,7 +21,7 @@ use tui_scrollview::ScrollViewState;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Tui {
|
pub struct Tui {
|
||||||
terminal: Option<DefaultTerminal>,
|
terminal: Option<DefaultTerminal>,
|
||||||
signal_shutdown: Sender<()>,
|
signal_shutdown: Sender<String>,
|
||||||
pub state: State,
|
pub state: State,
|
||||||
scroll_view_state: ScrollViewState,
|
scroll_view_state: ScrollViewState,
|
||||||
}
|
}
|
||||||
|
@ -33,7 +36,7 @@ impl Actor for Tui {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Tui {
|
impl Tui {
|
||||||
pub fn new(signal_shutdown: Sender<()>) -> Self {
|
pub fn new(signal_shutdown: Sender<String>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
terminal: None,
|
terminal: None,
|
||||||
signal_shutdown,
|
signal_shutdown,
|
||||||
|
@ -68,7 +71,7 @@ impl Tui {
|
||||||
match key.code {
|
match key.code {
|
||||||
KeyCode::Char('q') => {
|
KeyCode::Char('q') => {
|
||||||
ctx.stop();
|
ctx.stop();
|
||||||
if let Err(err) = self.signal_shutdown.send(()) {
|
if let Err(err) = self.signal_shutdown.send(String::new()) {
|
||||||
tracing::error!(?err, "Failed to signal shutdown");
|
tracing::error!(?err, "Failed to signal shutdown");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use ratatui::{
|
||||||
style::{Color, Style, Stylize as _},
|
style::{Color, Style, Stylize as _},
|
||||||
symbols::border,
|
symbols::border,
|
||||||
text::{Line, Span},
|
text::{Line, Span},
|
||||||
widgets::{block::Title, Block, Paragraph, StatefulWidget, Widget},
|
widgets::{Block, Paragraph, StatefulWidget, Widget},
|
||||||
};
|
};
|
||||||
|
|
||||||
use git_next_core::{
|
use git_next_core::{
|
||||||
|
@ -51,6 +51,10 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn time() -> String {
|
||||||
|
chrono::Local::now().format("%H:%M").to_string()
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum ServerState {
|
pub enum ServerState {
|
||||||
/// UI has started but has no information on the state of the server
|
/// UI has started but has no information on the state of the server
|
||||||
|
@ -278,8 +282,11 @@ impl RepoState {
|
||||||
#[tracing::instrument]
|
#[tracing::instrument]
|
||||||
pub fn clear_alert(&mut self) {
|
pub fn clear_alert(&mut self) {
|
||||||
match self {
|
match self {
|
||||||
Self::Identified { .. } | Self::Configured { .. } => (),
|
Self::Identified { alert, .. }
|
||||||
Self::Ready { alert, .. } => *alert = None,
|
| Self::Configured { alert, .. }
|
||||||
|
| Self::Ready { alert, .. } => {
|
||||||
|
*alert = None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,16 +360,19 @@ impl StatefulWidget for &State {
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
let block = Block::bordered()
|
let block = Block::bordered()
|
||||||
.title(Title::from(" Git-Next ".bold()).alignment(Alignment::Center))
|
.title_top(
|
||||||
.title(
|
Line::from(format!(" Git-Next v{} ", clap::crate_version!()).bold())
|
||||||
Title::from(Line::from(vec![
|
.alignment(Alignment::Center),
|
||||||
|
)
|
||||||
|
.title_bottom(
|
||||||
|
Line::from(vec![
|
||||||
" [q]uit ".into(),
|
" [q]uit ".into(),
|
||||||
self.beating_heart().into(),
|
self.beating_heart().into(),
|
||||||
" ".into(),
|
" ".into(),
|
||||||
]))
|
])
|
||||||
.alignment(Alignment::Center)
|
.alignment(Alignment::Center),
|
||||||
.position(ratatui::widgets::block::Position::Bottom),
|
|
||||||
)
|
)
|
||||||
|
.title_bottom(Line::from(format!(" {} ", time())).alignment(Alignment::Right))
|
||||||
.border_set(border::THICK);
|
.border_set(border::THICK);
|
||||||
let interior = block.inner(area);
|
let interior = block.inner(area);
|
||||||
block.render(area, buf);
|
block.render(area, buf);
|
||||||
|
|
99
crates/cli/src/tui/actor/tests.rs
Normal file
99
crates/cli/src/tui/actor/tests.rs
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
//
|
||||||
|
mod model {
|
||||||
|
mod repo_state {
|
||||||
|
use git_next_core::{git::graph::Log, RepoBranches};
|
||||||
|
use ratatui::style::Style;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
repo::tests::given,
|
||||||
|
tui::actor::{RepoMessage, RepoState, ViewState},
|
||||||
|
};
|
||||||
|
type Alert = Option<String>;
|
||||||
|
|
||||||
|
fn identified_with_alert(alert: Alert) -> RepoState {
|
||||||
|
RepoState::Identified {
|
||||||
|
repo_alias: given::a_repo_alias(),
|
||||||
|
message: RepoMessage::builder()
|
||||||
|
.text(given::a_name())
|
||||||
|
.style(Style::default())
|
||||||
|
.build(),
|
||||||
|
alert,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn configured_with_alert(alert: Alert) -> RepoState {
|
||||||
|
RepoState::Configured {
|
||||||
|
repo_alias: given::a_repo_alias(),
|
||||||
|
message: RepoMessage::builder()
|
||||||
|
.text(given::a_name())
|
||||||
|
.style(Style::default())
|
||||||
|
.build(),
|
||||||
|
alert,
|
||||||
|
branches: RepoBranches::new(String::new(), String::new(), String::new()),
|
||||||
|
log: Log::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn ready_with_alert(alert: Alert) -> RepoState {
|
||||||
|
RepoState::Ready {
|
||||||
|
repo_alias: given::a_repo_alias(),
|
||||||
|
message: RepoMessage::builder()
|
||||||
|
.text(given::a_name())
|
||||||
|
.style(Style::default())
|
||||||
|
.build(),
|
||||||
|
alert,
|
||||||
|
branches: RepoBranches::new(String::new(), String::new(), String::new()),
|
||||||
|
log: Log::default(),
|
||||||
|
view_state: ViewState::default(),
|
||||||
|
main: given::a_commit(),
|
||||||
|
next: given::a_commit(),
|
||||||
|
dev: given::a_commit(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest::rstest]
|
||||||
|
#[case(identified_with_alert(None))]
|
||||||
|
#[case(configured_with_alert(None))]
|
||||||
|
#[case(ready_with_alert(None))]
|
||||||
|
fn none_alert_remains_none(#[case] mut repo_state: RepoState) {
|
||||||
|
// given
|
||||||
|
match &repo_state {
|
||||||
|
RepoState::Identified { alert, .. }
|
||||||
|
| RepoState::Configured { alert, .. }
|
||||||
|
| RepoState::Ready { alert, .. } => {
|
||||||
|
assert!(alert.is_none(), "should be none at start");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// when
|
||||||
|
repo_state.clear_alert();
|
||||||
|
// then
|
||||||
|
match &repo_state {
|
||||||
|
RepoState::Identified { alert, .. }
|
||||||
|
| RepoState::Configured { alert, .. }
|
||||||
|
| RepoState::Ready { alert, .. } => assert!(alert.is_none(), "should remain none"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest::rstest]
|
||||||
|
#[case(identified_with_alert(Some(String::new())))]
|
||||||
|
#[case(configured_with_alert(Some(String::new())))]
|
||||||
|
#[case(ready_with_alert(Some(String::new())))]
|
||||||
|
fn some_alert_becomes_none(#[case] mut repo_state: RepoState) {
|
||||||
|
// given
|
||||||
|
match &repo_state {
|
||||||
|
RepoState::Identified { alert, .. }
|
||||||
|
| RepoState::Configured { alert, .. }
|
||||||
|
| RepoState::Ready { alert, .. } => {
|
||||||
|
assert!(alert.is_some(), "should be some at start");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// when
|
||||||
|
repo_state.clear_alert();
|
||||||
|
// then
|
||||||
|
match &repo_state {
|
||||||
|
RepoState::Identified { alert, .. }
|
||||||
|
| RepoState::Configured { alert, .. }
|
||||||
|
| RepoState::Ready { alert, .. } => assert!(alert.is_none(), "should become none"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,8 @@ use git_next_core::{ForgeAlias, RepoAlias};
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
buffer::Buffer,
|
buffer::Buffer,
|
||||||
layout::{Alignment, Direction, Layout, Rect},
|
layout::{Alignment, Direction, Layout, Rect},
|
||||||
widgets::{block::Title, Block, Widget},
|
text::Line,
|
||||||
|
widgets::{Block, Widget},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::tui::{
|
use crate::tui::{
|
||||||
|
@ -31,8 +32,8 @@ impl<'a> Widget for ExpandedForgeWidget<'a> {
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
let block = Block::default().title(
|
let block = Block::default().title_top(
|
||||||
Title::from(format!(" forge: {} ", self.forge_alias)).alignment(Alignment::Left),
|
Line::from(format!(" forge: {} ", self.forge_alias)).alignment(Alignment::Left),
|
||||||
);
|
);
|
||||||
let children = self.children();
|
let children = self.children();
|
||||||
let layout = Layout::default()
|
let layout = Layout::default()
|
||||||
|
|
|
@ -54,8 +54,7 @@ impl<'a> Identity<'a> {
|
||||||
let mut spans = vec![" ".into()];
|
let mut spans = vec![" ".into()];
|
||||||
match alert {
|
match alert {
|
||||||
None => spans.push(
|
None => spans.push(
|
||||||
Span::from(self.repo_alias.to_string())
|
Span::from(self.repo_alias.to_string()).style(Style::default().fg(Color::Cyan)),
|
||||||
.style(Style::default().fg(Color::Cyan).bg(Color::Black)),
|
|
||||||
),
|
),
|
||||||
Some(alert) => {
|
Some(alert) => {
|
||||||
spans.push(
|
spans.push(
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
/// `ForgeJo`: <https://{hostname}/user/settings/applications>
|
/// `ForgeJo`: <https://{hostname}/user/settings/applications>
|
||||||
/// `Github`: <https://github.com/settings/tokens>
|
/// `Github`: <https://github.com/settings/tokens>
|
||||||
#[derive(Clone, Debug, derive_more::Constructor)]
|
#[derive(Clone, Debug, derive_more::Constructor)]
|
||||||
pub struct ApiToken(secrecy::Secret<String>);
|
pub struct ApiToken(secrecy::SecretString);
|
||||||
/// The API Token is in effect a password, so it must be explicitly exposed to access its value
|
/// The API Token is in effect a password, so it must be explicitly exposed to access its value
|
||||||
impl secrecy::ExposeSecret<String> for ApiToken {
|
impl secrecy::ExposeSecret<str> for ApiToken {
|
||||||
fn expose_secret(&self) -> &String {
|
fn expose_secret(&self) -> &str {
|
||||||
self.0.expose_secret()
|
self.0.expose_secret()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
4
crates/core/src/config/commit_count.rs
Normal file
4
crates/core/src/config/commit_count.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
//
|
||||||
|
use crate::newtype;
|
||||||
|
|
||||||
|
newtype!(CommitCount, u32, Default, "A number of commits");
|
|
@ -11,6 +11,7 @@ pub fn forge_details(n: u32, forge_type: ForgeType) -> ForgeDetails {
|
||||||
hostname(n),
|
hostname(n),
|
||||||
user(n),
|
user(n),
|
||||||
api_token(n),
|
api_token(n),
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@ use std::collections::BTreeMap;
|
||||||
|
|
||||||
use crate::config::{ApiToken, ForgeType, Hostname, RepoAlias, ServerRepoConfig, User};
|
use crate::config::{ApiToken, ForgeType, Hostname, RepoAlias, ServerRepoConfig, User};
|
||||||
|
|
||||||
|
use super::CommitCount;
|
||||||
|
|
||||||
/// Defines a Forge to connect to
|
/// Defines a Forge to connect to
|
||||||
/// Maps from `git-next-server.toml` at `forge.{forge}`
|
/// Maps from `git-next-server.toml` at `forge.{forge}`
|
||||||
#[derive(
|
#[derive(
|
||||||
|
@ -22,6 +24,7 @@ pub struct ForgeConfig {
|
||||||
hostname: String,
|
hostname: String,
|
||||||
user: String,
|
user: String,
|
||||||
token: String,
|
token: String,
|
||||||
|
max_dev_commits: Option<u32>,
|
||||||
repos: BTreeMap<String, ServerRepoConfig>,
|
repos: BTreeMap<String, ServerRepoConfig>,
|
||||||
}
|
}
|
||||||
impl ForgeConfig {
|
impl ForgeConfig {
|
||||||
|
@ -41,6 +44,10 @@ impl ForgeConfig {
|
||||||
ApiToken::new(self.token.clone().into())
|
ApiToken::new(self.token.clone().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn max_dev_commits(&self) -> Option<CommitCount> {
|
||||||
|
self.max_dev_commits.map(CommitCount::from)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn repos(&self) -> impl Iterator<Item = (RepoAlias, &ServerRepoConfig)> {
|
pub fn repos(&self) -> impl Iterator<Item = (RepoAlias, &ServerRepoConfig)> {
|
||||||
self.repos
|
self.repos
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use crate::config::{ApiToken, ForgeAlias, ForgeConfig, ForgeType, Hostname, User};
|
use crate::config::{ApiToken, ForgeAlias, ForgeConfig, ForgeType, Hostname, User};
|
||||||
|
|
||||||
|
use super::CommitCount;
|
||||||
|
|
||||||
/// The derived information about a Forge, used to create interactions with it
|
/// The derived information about a Forge, used to create interactions with it
|
||||||
#[derive(Clone, Default, Debug, derive_more::Constructor, derive_with::With)]
|
#[derive(Clone, Default, Debug, derive_more::Constructor, derive_with::With)]
|
||||||
pub struct ForgeDetails {
|
pub struct ForgeDetails {
|
||||||
|
@ -8,8 +10,7 @@ pub struct ForgeDetails {
|
||||||
hostname: Hostname,
|
hostname: Hostname,
|
||||||
user: User,
|
user: User,
|
||||||
token: ApiToken,
|
token: ApiToken,
|
||||||
// API Token
|
max_dev_commits: Option<CommitCount>,
|
||||||
// Private SSH Key Path
|
|
||||||
}
|
}
|
||||||
impl ForgeDetails {
|
impl ForgeDetails {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -35,15 +36,21 @@ impl ForgeDetails {
|
||||||
pub const fn token(&self) -> &ApiToken {
|
pub const fn token(&self) -> &ApiToken {
|
||||||
&self.token
|
&self.token
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub const fn max_dev_commits(&self) -> Option<&CommitCount> {
|
||||||
|
self.max_dev_commits.as_ref()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl From<(&ForgeAlias, &ForgeConfig)> for ForgeDetails {
|
impl From<(&ForgeAlias, &ForgeConfig)> for ForgeDetails {
|
||||||
fn from(forge: (&ForgeAlias, &ForgeConfig)) -> Self {
|
fn from((forge_alias, forge_config): (&ForgeAlias, &ForgeConfig)) -> Self {
|
||||||
Self {
|
Self {
|
||||||
forge_alias: forge.0.clone(),
|
forge_alias: forge_alias.clone(),
|
||||||
forge_type: forge.1.forge_type(),
|
forge_type: forge_config.forge_type(),
|
||||||
hostname: forge.1.hostname(),
|
hostname: forge_config.hostname(),
|
||||||
user: forge.1.user(),
|
user: forge_config.user(),
|
||||||
token: forge.1.token(),
|
token: forge_config.token(),
|
||||||
|
max_dev_commits: forge_config.max_dev_commits(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//
|
//
|
||||||
mod api_token;
|
mod api_token;
|
||||||
mod branch_name;
|
mod branch_name;
|
||||||
|
mod commit_count;
|
||||||
pub mod common;
|
pub mod common;
|
||||||
mod forge_alias;
|
mod forge_alias;
|
||||||
mod forge_config;
|
mod forge_config;
|
||||||
|
@ -26,6 +27,7 @@ mod tests;
|
||||||
|
|
||||||
pub use api_token::ApiToken;
|
pub use api_token::ApiToken;
|
||||||
pub use branch_name::BranchName;
|
pub use branch_name::BranchName;
|
||||||
|
pub use commit_count::CommitCount;
|
||||||
pub use forge_alias::ForgeAlias;
|
pub use forge_alias::ForgeAlias;
|
||||||
#[allow(clippy::module_name_repetitions)]
|
#[allow(clippy::module_name_repetitions)]
|
||||||
pub use forge_config::ForgeConfig;
|
pub use forge_config::ForgeConfig;
|
||||||
|
|
|
@ -10,7 +10,7 @@ use std::{
|
||||||
|
|
||||||
use derive_more::{Constructor, Display};
|
use derive_more::{Constructor, Display};
|
||||||
use kxio::fs::FileSystem;
|
use kxio::fs::FileSystem;
|
||||||
use secrecy::Secret;
|
use secrecy::SecretString;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
|
@ -242,8 +242,11 @@ impl Shout {
|
||||||
self.webhook.clone().map(|x| x.url)
|
self.webhook.clone().map(|x| x.url)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn webhook_secret(&self) -> Option<Secret<String>> {
|
pub fn webhook_secret(&self) -> Option<SecretString> {
|
||||||
self.webhook.clone().map(|x| x.secret).map(Secret::new)
|
self.webhook
|
||||||
|
.clone()
|
||||||
|
.map(|x| x.secret)
|
||||||
|
.map(SecretString::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -278,8 +281,8 @@ impl OutboundWebhook {
|
||||||
self.url.as_ref()
|
self.url.as_ref()
|
||||||
}
|
}
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn secret(&self) -> Secret<String> {
|
pub fn secret(&self) -> SecretString {
|
||||||
Secret::new(self.secret.clone())
|
SecretString::from(self.secret.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,8 @@ mod repo_config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mod forge_config {
|
mod forge_config {
|
||||||
|
use given::maybe_a_number;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -166,7 +168,7 @@ mod forge_config {
|
||||||
let mut repos = BTreeMap::new();
|
let mut repos = BTreeMap::new();
|
||||||
repos.insert(red_name.clone(), red.clone());
|
repos.insert(red_name.clone(), red.clone());
|
||||||
repos.insert(blue_name.clone(), blue.clone());
|
repos.insert(blue_name.clone(), blue.clone());
|
||||||
let fc = ForgeConfig::new(forge_type, hostname, user, token, repos);
|
let fc = ForgeConfig::new(forge_type, hostname, user, token, maybe_a_number(), repos);
|
||||||
|
|
||||||
let returned_repos = fc.repos().collect::<Vec<_>>();
|
let returned_repos = fc.repos().collect::<Vec<_>>();
|
||||||
|
|
||||||
|
@ -186,7 +188,7 @@ mod forge_config {
|
||||||
let user = given::a_name();
|
let user = given::a_name();
|
||||||
let token = given::a_name();
|
let token = given::a_name();
|
||||||
let repos = BTreeMap::new();
|
let repos = BTreeMap::new();
|
||||||
let fc = ForgeConfig::new(forge_type, hostname, user, token, repos);
|
let fc = ForgeConfig::new(forge_type, hostname, user, token, maybe_a_number(), repos);
|
||||||
|
|
||||||
assert_eq!(fc.forge_type(), ForgeType::MockForge);
|
assert_eq!(fc.forge_type(), ForgeType::MockForge);
|
||||||
}
|
}
|
||||||
|
@ -197,7 +199,14 @@ mod forge_config {
|
||||||
let user = given::a_name();
|
let user = given::a_name();
|
||||||
let token = given::a_name();
|
let token = given::a_name();
|
||||||
let repos = BTreeMap::new();
|
let repos = BTreeMap::new();
|
||||||
let fc = ForgeConfig::new(forge_type, hostname.clone(), user, token, repos);
|
let fc = ForgeConfig::new(
|
||||||
|
forge_type,
|
||||||
|
hostname.clone(),
|
||||||
|
user,
|
||||||
|
token,
|
||||||
|
maybe_a_number(),
|
||||||
|
repos,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(fc.hostname(), Hostname::new(hostname));
|
assert_eq!(fc.hostname(), Hostname::new(hostname));
|
||||||
}
|
}
|
||||||
|
@ -208,7 +217,14 @@ mod forge_config {
|
||||||
let user = given::a_name();
|
let user = given::a_name();
|
||||||
let token = given::a_name();
|
let token = given::a_name();
|
||||||
let repos = BTreeMap::new();
|
let repos = BTreeMap::new();
|
||||||
let fc = ForgeConfig::new(forge_type, hostname, user.clone(), token, repos);
|
let fc = ForgeConfig::new(
|
||||||
|
forge_type,
|
||||||
|
hostname,
|
||||||
|
user.clone(),
|
||||||
|
token,
|
||||||
|
maybe_a_number(),
|
||||||
|
repos,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(fc.user(), User::new(user));
|
assert_eq!(fc.user(), User::new(user));
|
||||||
}
|
}
|
||||||
|
@ -219,7 +235,14 @@ mod forge_config {
|
||||||
let user = given::a_name();
|
let user = given::a_name();
|
||||||
let token = given::a_name();
|
let token = given::a_name();
|
||||||
let repos = BTreeMap::new();
|
let repos = BTreeMap::new();
|
||||||
let fc = ForgeConfig::new(forge_type, hostname, user, token.clone(), repos);
|
let fc = ForgeConfig::new(
|
||||||
|
forge_type,
|
||||||
|
hostname,
|
||||||
|
user,
|
||||||
|
token.clone(),
|
||||||
|
maybe_a_number(),
|
||||||
|
repos,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(fc.token().expose_secret(), token.as_str());
|
assert_eq!(fc.token().expose_secret(), token.as_str());
|
||||||
}
|
}
|
||||||
|
@ -237,7 +260,7 @@ mod forge_config {
|
||||||
let mut repos = BTreeMap::new();
|
let mut repos = BTreeMap::new();
|
||||||
repos.insert(red_name.clone(), red.clone());
|
repos.insert(red_name.clone(), red.clone());
|
||||||
repos.insert(blue_name, blue);
|
repos.insert(blue_name, blue);
|
||||||
let fc = ForgeConfig::new(forge_type, hostname, user, token, repos);
|
let fc = ForgeConfig::new(forge_type, hostname, user, token, maybe_a_number(), repos);
|
||||||
|
|
||||||
let returned_repo = fc.get_repo(red_name.as_str());
|
let returned_repo = fc.get_repo(red_name.as_str());
|
||||||
|
|
||||||
|
@ -255,8 +278,14 @@ mod forge_details {
|
||||||
let user = User::new(given::a_name());
|
let user = User::new(given::a_name());
|
||||||
let token = ApiToken::new(given::a_name().into());
|
let token = ApiToken::new(given::a_name().into());
|
||||||
let forge_alias = ForgeAlias::new(given::a_name());
|
let forge_alias = ForgeAlias::new(given::a_name());
|
||||||
let forge_details =
|
let forge_details = ForgeDetails::new(
|
||||||
ForgeDetails::new(forge_alias.clone(), forge_type, hostname, user, token);
|
forge_alias.clone(),
|
||||||
|
forge_type,
|
||||||
|
hostname,
|
||||||
|
user,
|
||||||
|
token,
|
||||||
|
given::maybe_a_number().map(CommitCount::from),
|
||||||
|
);
|
||||||
|
|
||||||
let result = forge_details.forge_alias();
|
let result = forge_details.forge_alias();
|
||||||
|
|
||||||
|
@ -269,7 +298,14 @@ mod forge_details {
|
||||||
let user = User::new(given::a_name());
|
let user = User::new(given::a_name());
|
||||||
let token = ApiToken::new(given::a_name().into());
|
let token = ApiToken::new(given::a_name().into());
|
||||||
let forge_name = ForgeAlias::new(given::a_name());
|
let forge_name = ForgeAlias::new(given::a_name());
|
||||||
let forge_details = ForgeDetails::new(forge_name, forge_type, hostname, user, token);
|
let forge_details = ForgeDetails::new(
|
||||||
|
forge_name,
|
||||||
|
forge_type,
|
||||||
|
hostname,
|
||||||
|
user,
|
||||||
|
token,
|
||||||
|
given::maybe_a_number().map(CommitCount::from),
|
||||||
|
);
|
||||||
|
|
||||||
let result = forge_details.forge_type();
|
let result = forge_details.forge_type();
|
||||||
|
|
||||||
|
@ -282,8 +318,14 @@ mod forge_details {
|
||||||
let user = User::new(given::a_name());
|
let user = User::new(given::a_name());
|
||||||
let token = ApiToken::new(given::a_name().into());
|
let token = ApiToken::new(given::a_name().into());
|
||||||
let forge_name = ForgeAlias::new(given::a_name());
|
let forge_name = ForgeAlias::new(given::a_name());
|
||||||
let forge_details =
|
let forge_details = ForgeDetails::new(
|
||||||
ForgeDetails::new(forge_name, forge_type, hostname.clone(), user, token);
|
forge_name,
|
||||||
|
forge_type,
|
||||||
|
hostname.clone(),
|
||||||
|
user,
|
||||||
|
token,
|
||||||
|
given::maybe_a_number().map(CommitCount::from),
|
||||||
|
);
|
||||||
|
|
||||||
let result = forge_details.hostname();
|
let result = forge_details.hostname();
|
||||||
|
|
||||||
|
@ -296,8 +338,14 @@ mod forge_details {
|
||||||
let user = User::new(given::a_name());
|
let user = User::new(given::a_name());
|
||||||
let token = ApiToken::new(given::a_name().into());
|
let token = ApiToken::new(given::a_name().into());
|
||||||
let forge_name = ForgeAlias::new(given::a_name());
|
let forge_name = ForgeAlias::new(given::a_name());
|
||||||
let forge_details =
|
let forge_details = ForgeDetails::new(
|
||||||
ForgeDetails::new(forge_name, forge_type, hostname, user.clone(), token);
|
forge_name,
|
||||||
|
forge_type,
|
||||||
|
hostname,
|
||||||
|
user.clone(),
|
||||||
|
token,
|
||||||
|
given::maybe_a_number().map(CommitCount::from),
|
||||||
|
);
|
||||||
|
|
||||||
let result = forge_details.user();
|
let result = forge_details.user();
|
||||||
|
|
||||||
|
@ -310,8 +358,14 @@ mod forge_details {
|
||||||
let user = User::new(given::a_name());
|
let user = User::new(given::a_name());
|
||||||
let token = ApiToken::new(given::a_name().into());
|
let token = ApiToken::new(given::a_name().into());
|
||||||
let forge_name = ForgeAlias::new(given::a_name());
|
let forge_name = ForgeAlias::new(given::a_name());
|
||||||
let forge_details =
|
let forge_details = ForgeDetails::new(
|
||||||
ForgeDetails::new(forge_name, forge_type, hostname, user, token.clone());
|
forge_name,
|
||||||
|
forge_type,
|
||||||
|
hostname,
|
||||||
|
user,
|
||||||
|
token.clone(),
|
||||||
|
given::maybe_a_number().map(CommitCount::from),
|
||||||
|
);
|
||||||
|
|
||||||
let result = forge_details.token();
|
let result = forge_details.token();
|
||||||
|
|
||||||
|
@ -325,7 +379,14 @@ mod forge_details {
|
||||||
let user = User::new(given::a_name());
|
let user = User::new(given::a_name());
|
||||||
let token = ApiToken::new(given::a_name().into());
|
let token = ApiToken::new(given::a_name().into());
|
||||||
let forge_name = ForgeAlias::new(given::a_name());
|
let forge_name = ForgeAlias::new(given::a_name());
|
||||||
let forge_details = ForgeDetails::new(forge_name, forge_type, hostname, user, token);
|
let forge_details = ForgeDetails::new(
|
||||||
|
forge_name,
|
||||||
|
forge_type,
|
||||||
|
hostname,
|
||||||
|
user,
|
||||||
|
token,
|
||||||
|
given::maybe_a_number().map(CommitCount::from),
|
||||||
|
);
|
||||||
|
|
||||||
let result = forge_details.with_hostname(other_hostname.clone());
|
let result = forge_details.with_hostname(other_hostname.clone());
|
||||||
|
|
||||||
|
@ -340,12 +401,14 @@ mod forge_details {
|
||||||
let user = User::new(user_value.clone());
|
let user = User::new(user_value.clone());
|
||||||
let token_value = given::a_name();
|
let token_value = given::a_name();
|
||||||
let token = ApiToken::new(token_value.clone().into());
|
let token = ApiToken::new(token_value.clone().into());
|
||||||
|
let max_dev_commits = given::maybe_a_number();
|
||||||
let forge_alias = ForgeAlias::new(given::a_name());
|
let forge_alias = ForgeAlias::new(given::a_name());
|
||||||
let forge_config = ForgeConfig::new(
|
let forge_config = ForgeConfig::new(
|
||||||
forge_type,
|
forge_type,
|
||||||
hostname_value,
|
hostname_value,
|
||||||
user_value,
|
user_value,
|
||||||
token_value,
|
token_value,
|
||||||
|
max_dev_commits,
|
||||||
BTreeMap::new(),
|
BTreeMap::new(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -355,6 +418,12 @@ mod forge_details {
|
||||||
assert_eq!(forge_details.hostname(), &hostname);
|
assert_eq!(forge_details.hostname(), &hostname);
|
||||||
assert_eq!(forge_details.user(), &user);
|
assert_eq!(forge_details.user(), &user);
|
||||||
assert_eq!(forge_details.token().expose_secret(), token.expose_secret());
|
assert_eq!(forge_details.token().expose_secret(), token.expose_secret());
|
||||||
|
assert_eq!(
|
||||||
|
forge_details
|
||||||
|
.max_dev_commits()
|
||||||
|
.map(|commit_count| commit_count.clone().peel()),
|
||||||
|
max_dev_commits
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mod forge_name {
|
mod forge_name {
|
||||||
|
@ -470,7 +539,7 @@ mod server {
|
||||||
let shout_webhook_url = shout.webhook_url().unwrap_or_default();
|
let shout_webhook_url = shout.webhook_url().unwrap_or_default();
|
||||||
let shout_webhook_secret = shout
|
let shout_webhook_secret = shout
|
||||||
.webhook_secret()
|
.webhook_secret()
|
||||||
.map(|secret| secret.expose_secret().clone())
|
.map(|secret| secret.expose_secret().to_string())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let_assert!(Some(shout_email) = shout.email());
|
let_assert!(Some(shout_email) = shout.email());
|
||||||
let shout_email_from = shout_email.from();
|
let shout_email_from = shout_email.from();
|
||||||
|
@ -492,6 +561,12 @@ mod server {
|
||||||
let forge_hostname = forge_default.hostname();
|
let forge_hostname = forge_default.hostname();
|
||||||
let forge_user = forge_default.user();
|
let forge_user = forge_default.user();
|
||||||
let forge_token = forge_default.token().expose_secret().to_string();
|
let forge_token = forge_default.token().expose_secret().to_string();
|
||||||
|
let optional_max_dev_commits = forge_default
|
||||||
|
.max_dev_commits()
|
||||||
|
.map(CommitCount::peel)
|
||||||
|
.map_or_else(String::new, |max_dev_commits| {
|
||||||
|
format!("max_dev_commits = {max_dev_commits}")
|
||||||
|
});
|
||||||
let mut repos: Vec<String> = vec![];
|
let mut repos: Vec<String> = vec![];
|
||||||
for (repo_alias, server_repo_config) in forge_default.repos() {
|
for (repo_alias, server_repo_config) in forge_default.repos() {
|
||||||
let repo_path = server_repo_config.repo();
|
let repo_path = server_repo_config.repo();
|
||||||
|
@ -542,6 +617,7 @@ forge_type = "{forge_type}"
|
||||||
hostname = "{forge_hostname}"
|
hostname = "{forge_hostname}"
|
||||||
user = "{forge_user}"
|
user = "{forge_user}"
|
||||||
token = "{forge_token}"
|
token = "{forge_token}"
|
||||||
|
{optional_max_dev_commits}
|
||||||
|
|
||||||
[forge.{forge_alias}.repos]
|
[forge.{forge_alias}.repos]
|
||||||
{repos}
|
{repos}
|
||||||
|
@ -726,6 +802,23 @@ mod given {
|
||||||
}
|
}
|
||||||
generate(5)
|
generate(5)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn a_number() -> u32 {
|
||||||
|
use rand::Rng;
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
rng.gen_range(0..100)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn maybe_a_number() -> Option<u32> {
|
||||||
|
use rand::Rng;
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
if Rng::gen_ratio(&mut rng, 1, 2) {
|
||||||
|
Some(a_number())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn an_app_config() -> AppConfig {
|
pub fn an_app_config() -> AppConfig {
|
||||||
AppConfig::new(
|
AppConfig::new(
|
||||||
a_listen(),
|
a_listen(),
|
||||||
|
@ -785,6 +878,7 @@ mod given {
|
||||||
a_name(), // hostname
|
a_name(), // hostname
|
||||||
a_name(), // user
|
a_name(), // user
|
||||||
a_name(), // token
|
a_name(), // token
|
||||||
|
maybe_a_number(),
|
||||||
some_server_repo_configs(),
|
some_server_repo_configs(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,9 @@ pub type Result<T> = core::result::Result<T, Error>;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
#[error("io")]
|
||||||
|
Io(#[from] std::io::Error),
|
||||||
|
|
||||||
#[error("unable to open repo: {0}")]
|
#[error("unable to open repo: {0}")]
|
||||||
UnableToOpenRepo(String),
|
UnableToOpenRepo(String),
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::{
|
||||||
|
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
use secrecy::{ExposeSecret, Secret};
|
use secrecy::{ExposeSecret, SecretString};
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
/// The derived information about a repo, used to interact with it
|
/// The derived information about a repo, used to interact with it
|
||||||
|
@ -49,10 +49,11 @@ impl RepoDetails {
|
||||||
forge_config.hostname(),
|
forge_config.hostname(),
|
||||||
forge_config.user(),
|
forge_config.user(),
|
||||||
forge_config.token(),
|
forge_config.token(),
|
||||||
|
forge_config.max_dev_commits(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn origin(&self) -> secrecy::Secret<String> {
|
pub(crate) fn origin(&self) -> secrecy::SecretString {
|
||||||
let repo_details = self;
|
let repo_details = self;
|
||||||
let user = &repo_details.forge.user();
|
let user = &repo_details.forge.user();
|
||||||
let hostname = &repo_details.forge.hostname();
|
let hostname = &repo_details.forge.hostname();
|
||||||
|
@ -77,7 +78,7 @@ impl RepoDetails {
|
||||||
}
|
}
|
||||||
|
|
||||||
// url is a secret as it contains auth token
|
// url is a secret as it contains auth token
|
||||||
pub(crate) fn url(&self) -> Secret<String> {
|
pub(crate) fn url(&self) -> SecretString {
|
||||||
let user = self.forge.user();
|
let user = self.forge.user();
|
||||||
let token = self.forge.token().expose_secret();
|
let token = self.forge.token().expose_secret();
|
||||||
let auth_delim = if token.is_empty() { "" } else { ":" };
|
let auth_delim = if token.is_empty() { "" } else { ":" };
|
||||||
|
@ -94,12 +95,7 @@ impl RepoDetails {
|
||||||
|> GitDir::pathbuf
|
|> GitDir::pathbuf
|
||||||
|> gix::ThreadSafeRepository::open
|
|> gix::ThreadSafeRepository::open
|
||||||
}?;
|
}?;
|
||||||
let repo = pike! {
|
let repo = RealOpenRepository::new(Arc::new(RwLock::new(gix_repo)), self.forge.clone());
|
||||||
gix_repo
|
|
||||||
|> RwLock::new
|
|
||||||
|> Arc::new
|
|
||||||
|> RealOpenRepository::new
|
|
||||||
};
|
|
||||||
Ok(repo)
|
Ok(repo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,13 +60,14 @@ impl RepositoryFactory for RealRepositoryFactory {
|
||||||
|
|
||||||
fn git_clone(&self, repo_details: &RepoDetails) -> Result<Box<dyn OpenRepositoryLike>> {
|
fn git_clone(&self, repo_details: &RepoDetails) -> Result<Box<dyn OpenRepositoryLike>> {
|
||||||
tracing::info!("creating");
|
tracing::info!("creating");
|
||||||
let (gix_repo, _outcome) = gix::prepare_clone_bare(
|
let (gix_repo, _outcome) =
|
||||||
repo_details.origin().expose_secret().as_str(),
|
gix::prepare_clone_bare(repo_details.origin().expose_secret(), &*repo_details.gitdir)?
|
||||||
&*repo_details.gitdir,
|
.fetch_only(gix::progress::Discard, &AtomicBool::new(false))?;
|
||||||
)?
|
|
||||||
.fetch_only(gix::progress::Discard, &AtomicBool::new(false))?;
|
|
||||||
tracing::info!("created");
|
tracing::info!("created");
|
||||||
let repo = RealOpenRepository::new(Arc::new(RwLock::new(gix_repo.into())));
|
let repo = RealOpenRepository::new(
|
||||||
|
Arc::new(RwLock::new(gix_repo.into())),
|
||||||
|
repo_details.forge.clone(),
|
||||||
|
);
|
||||||
Ok(Box::new(repo))
|
Ok(Box::new(repo))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//
|
//
|
||||||
use crate::{
|
use crate::{
|
||||||
git::{
|
git::{
|
||||||
|
self,
|
||||||
repository::{
|
repository::{
|
||||||
open::{OpenRepository, OpenRepositoryLike},
|
open::{OpenRepository, OpenRepositoryLike},
|
||||||
test::TestRepository,
|
test::TestRepository,
|
||||||
|
@ -31,8 +32,11 @@ pub enum Repository {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) const fn test(fs: kxio::fs::FileSystem) -> TestRepository {
|
pub(crate) const fn test(
|
||||||
TestRepository::new(fs, vec![], vec![])
|
fs: kxio::fs::FileSystem,
|
||||||
|
forge_details: crate::ForgeDetails,
|
||||||
|
) -> TestRepository {
|
||||||
|
TestRepository::new(fs, vec![], vec![], forge_details)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Opens a repository, cloning if necessary
|
/// Opens a repository, cloning if necessary
|
||||||
|
@ -44,7 +48,9 @@ pub fn open(
|
||||||
) -> Result<Box<dyn OpenRepositoryLike>> {
|
) -> Result<Box<dyn OpenRepositoryLike>> {
|
||||||
let open_repository = if repo_details.gitdir.exists() {
|
let open_repository = if repo_details.gitdir.exists() {
|
||||||
info!("Local copy found - opening...");
|
info!("Local copy found - opening...");
|
||||||
repository_factory.open(repo_details)?
|
let repo = repository_factory.open(repo_details)?;
|
||||||
|
repo.fetch()?;
|
||||||
|
repo
|
||||||
} else {
|
} else {
|
||||||
info!("Local copy not found - cloning...");
|
info!("Local copy not found - cloning...");
|
||||||
repository_factory.git_clone(repo_details)?
|
repository_factory.git_clone(repo_details)?
|
||||||
|
@ -114,6 +120,9 @@ pub enum Error {
|
||||||
#[error("git clone: {0}")]
|
#[error("git clone: {0}")]
|
||||||
Clone(String),
|
Clone(String),
|
||||||
|
|
||||||
|
#[error("git fetch: {0}")]
|
||||||
|
FetchError(#[from] git::fetch::Error),
|
||||||
|
|
||||||
#[error("open: {0}")]
|
#[error("open: {0}")]
|
||||||
Open(String),
|
Open(String),
|
||||||
|
|
||||||
|
|
|
@ -37,10 +37,11 @@ pub enum OpenRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(tarpaulin_include))]
|
#[cfg(not(tarpaulin_include))]
|
||||||
pub fn real(gix_repo: gix::Repository) -> OpenRepository {
|
pub fn real(gix_repo: gix::Repository, forge_details: crate::ForgeDetails) -> OpenRepository {
|
||||||
OpenRepository::Real(oreal::RealOpenRepository::new(Arc::new(RwLock::new(
|
OpenRepository::Real(oreal::RealOpenRepository::new(
|
||||||
gix_repo.into(),
|
Arc::new(RwLock::new(gix_repo.into())),
|
||||||
))))
|
forge_details,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(tarpaulin_include))] // don't test mocks
|
#[cfg(not(tarpaulin_include))] // don't test mocks
|
||||||
|
@ -49,8 +50,15 @@ pub(crate) fn test(
|
||||||
fs: &kxio::fs::FileSystem,
|
fs: &kxio::fs::FileSystem,
|
||||||
on_fetch: Vec<otest::OnFetch>,
|
on_fetch: Vec<otest::OnFetch>,
|
||||||
on_push: Vec<otest::OnPush>,
|
on_push: Vec<otest::OnPush>,
|
||||||
|
forge_details: crate::ForgeDetails,
|
||||||
) -> OpenRepository {
|
) -> OpenRepository {
|
||||||
OpenRepository::Test(TestOpenRepository::new(gitdir, fs, on_fetch, on_push))
|
OpenRepository::Test(TestOpenRepository::new(
|
||||||
|
gitdir,
|
||||||
|
fs,
|
||||||
|
on_fetch,
|
||||||
|
on_push,
|
||||||
|
forge_details,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::module_name_repetitions)]
|
#[allow(clippy::module_name_repetitions)]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//
|
//
|
||||||
use crate::{
|
use crate::{
|
||||||
git::{self, repository::OpenRepositoryLike},
|
git::{self, repository::OpenRepositoryLike},
|
||||||
BranchName, Hostname, RemoteUrl, RepoPath,
|
BranchName, ForgeDetails, Hostname, RemoteUrl, RepoPath,
|
||||||
};
|
};
|
||||||
|
|
||||||
use derive_more::Constructor;
|
use derive_more::Constructor;
|
||||||
|
@ -16,11 +16,14 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Constructor)]
|
#[derive(Clone, Debug, Constructor)]
|
||||||
pub struct RealOpenRepository(Arc<RwLock<gix::ThreadSafeRepository>>);
|
pub struct RealOpenRepository {
|
||||||
|
inner: Arc<RwLock<gix::ThreadSafeRepository>>,
|
||||||
|
forge_details: ForgeDetails,
|
||||||
|
}
|
||||||
impl super::OpenRepositoryLike for RealOpenRepository {
|
impl super::OpenRepositoryLike for RealOpenRepository {
|
||||||
fn remote_branches(&self) -> git::push::Result<Vec<BranchName>> {
|
fn remote_branches(&self) -> git::push::Result<Vec<BranchName>> {
|
||||||
let refs = self
|
let refs = self
|
||||||
.0
|
.inner
|
||||||
.read()
|
.read()
|
||||||
.map_err(|_| git::push::Error::Lock)
|
.map_err(|_| git::push::Error::Lock)
|
||||||
.and_then(|repo| {
|
.and_then(|repo| {
|
||||||
|
@ -44,7 +47,7 @@ impl super::OpenRepositoryLike for RealOpenRepository {
|
||||||
|
|
||||||
#[tracing::instrument]
|
#[tracing::instrument]
|
||||||
fn find_default_remote(&self, direction: git::repository::Direction) -> Option<RemoteUrl> {
|
fn find_default_remote(&self, direction: git::repository::Direction) -> Option<RemoteUrl> {
|
||||||
let Ok(repository) = self.0.read() else {
|
let Ok(repository) = self.inner.read() else {
|
||||||
#[cfg(not(tarpaulin_include))] // don't test mutex lock failure
|
#[cfg(not(tarpaulin_include))] // don't test mutex lock failure
|
||||||
tracing::debug!("no repository");
|
tracing::debug!("no repository");
|
||||||
return None;
|
return None;
|
||||||
|
@ -64,34 +67,32 @@ impl super::OpenRepositoryLike for RealOpenRepository {
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
#[cfg(not(tarpaulin_include))] // would require writing to external service
|
#[cfg(not(tarpaulin_include))] // would require writing to external service
|
||||||
fn fetch(&self) -> Result<(), git::fetch::Error> {
|
fn fetch(&self) -> Result<(), git::fetch::Error> {
|
||||||
use std::sync::atomic::AtomicBool;
|
if self
|
||||||
|
.find_default_remote(git::repository::Direction::Fetch)
|
||||||
let Ok(repository) = self.0.read() else {
|
.is_none()
|
||||||
#[cfg(not(tarpaulin_include))] // don't test mutex lock failure
|
{
|
||||||
return Err(git::fetch::Error::Lock);
|
|
||||||
};
|
|
||||||
let thread_local = repository.to_thread_local();
|
|
||||||
let Some(Ok(remote)) =
|
|
||||||
thread_local.find_default_remote(git::repository::Direction::Fetch.into())
|
|
||||||
else {
|
|
||||||
#[cfg(not(tarpaulin_include))] // test is on local repo - should always have remotes
|
|
||||||
return Err(git::fetch::Error::NoFetchRemoteFound);
|
return Err(git::fetch::Error::NoFetchRemoteFound);
|
||||||
};
|
}
|
||||||
remote
|
info!("Fetching");
|
||||||
.connect(gix::remote::Direction::Fetch)
|
gix::command::prepare("/usr/bin/git fetch --prune")
|
||||||
.map_err(|gix| git::fetch::Error::Connect(gix.to_string()))?
|
.with_context(gix::diff::command::Context {
|
||||||
.prepare_fetch(
|
git_dir: Some(
|
||||||
gix::progress::Discard,
|
self.inner
|
||||||
gix::remote::ref_map::Options::default(),
|
.read()
|
||||||
)
|
.map_err(|_| git::fetch::Error::Lock)
|
||||||
.map_err(|gix| git::fetch::Error::Prepare(gix.to_string()))?
|
.map(|r| r.git_dir().to_path_buf())?,
|
||||||
.receive(gix::progress::Discard, &AtomicBool::default())
|
),
|
||||||
.map_err(|gix| git::fetch::Error::Receive(gix.to_string()))?;
|
..Default::default()
|
||||||
|
})
|
||||||
|
.with_shell_allow_argument_splitting()
|
||||||
|
.stdout(std::process::Stdio::null())
|
||||||
|
.stderr(std::process::Stdio::null())
|
||||||
|
.spawn()?
|
||||||
|
.wait()?;
|
||||||
info!("Fetch okay");
|
info!("Fetch okay");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: (#72) reimplement using `gix`
|
|
||||||
#[cfg(not(tarpaulin_include))] // would require writing to external service
|
#[cfg(not(tarpaulin_include))] // would require writing to external service
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
fn push(
|
fn push(
|
||||||
|
@ -111,13 +112,13 @@ impl super::OpenRepositoryLike for RealOpenRepository {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// INFO: never log the command as it contains the API token within the 'origin'
|
// INFO: never log the command as it contains the API token within the 'origin'
|
||||||
let command: secrecy::Secret<String> = format!(
|
let command: secrecy::SecretString = format!(
|
||||||
"/usr/bin/git push {} {to_commit}:{branch_name} {force}",
|
"/usr/bin/git push {} {to_commit}:{branch_name} {force}",
|
||||||
origin.expose_secret()
|
origin.expose_secret()
|
||||||
)
|
)
|
||||||
.into();
|
.into();
|
||||||
let git_dir = self
|
let git_dir = self
|
||||||
.0
|
.inner
|
||||||
.read()
|
.read()
|
||||||
.map_err(|_| git::push::Error::Lock)
|
.map_err(|_| git::push::Error::Lock)
|
||||||
.map(|r| r.git_dir().to_path_buf())?;
|
.map(|r| r.git_dir().to_path_buf())?;
|
||||||
|
@ -140,8 +141,14 @@ impl super::OpenRepositoryLike for RealOpenRepository {
|
||||||
branch_name: &BranchName,
|
branch_name: &BranchName,
|
||||||
find_commits: &[git::Commit],
|
find_commits: &[git::Commit],
|
||||||
) -> Result<Vec<git::Commit>, git::commit::log::Error> {
|
) -> Result<Vec<git::Commit>, git::commit::log::Error> {
|
||||||
let limit = if find_commits.is_empty() { 1 } else { 25 };
|
let limit: usize = if find_commits.is_empty() {
|
||||||
self.0
|
1
|
||||||
|
} else {
|
||||||
|
self.forge_details
|
||||||
|
.max_dev_commits()
|
||||||
|
.map_or(25, |commit_count| commit_count.clone().peel() as usize)
|
||||||
|
};
|
||||||
|
self.inner
|
||||||
.read()
|
.read()
|
||||||
.map_err(|_| git::commit::log::Error::Lock)
|
.map_err(|_| git::commit::log::Error::Lock)
|
||||||
.map(|repo| {
|
.map(|repo| {
|
||||||
|
@ -196,7 +203,7 @@ impl super::OpenRepositoryLike for RealOpenRepository {
|
||||||
|
|
||||||
#[tracing::instrument(skip_all, fields(%branch_name, ?file_name))]
|
#[tracing::instrument(skip_all, fields(%branch_name, ?file_name))]
|
||||||
fn read_file(&self, branch_name: &BranchName, file_name: &Path) -> git::file::Result<String> {
|
fn read_file(&self, branch_name: &BranchName, file_name: &Path) -> git::file::Result<String> {
|
||||||
self.0
|
self.inner
|
||||||
.read()
|
.read()
|
||||||
.map_err(|_| git::file::Error::Lock)
|
.map_err(|_| git::file::Error::Lock)
|
||||||
.and_then(|repo| {
|
.and_then(|repo| {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::{
|
||||||
self,
|
self,
|
||||||
repository::open::{OpenRepositoryLike, RealOpenRepository},
|
repository::open::{OpenRepositoryLike, RealOpenRepository},
|
||||||
},
|
},
|
||||||
BranchName, GitDir, RemoteUrl, RepoBranches,
|
BranchName, ForgeDetails, GitDir, RemoteUrl, RepoBranches,
|
||||||
};
|
};
|
||||||
|
|
||||||
use derive_more::Constructor;
|
use derive_more::Constructor;
|
||||||
|
@ -155,6 +155,7 @@ impl TestOpenRepository {
|
||||||
fs: &kxio::fs::FileSystem,
|
fs: &kxio::fs::FileSystem,
|
||||||
on_fetch: Vec<OnFetch>,
|
on_fetch: Vec<OnFetch>,
|
||||||
on_push: Vec<OnPush>,
|
on_push: Vec<OnPush>,
|
||||||
|
forge_details: ForgeDetails,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let pathbuf = fs.base().join(gitdir.to_path_buf());
|
let pathbuf = fs.base().join(gitdir.to_path_buf());
|
||||||
#[allow(clippy::expect_used)]
|
#[allow(clippy::expect_used)]
|
||||||
|
@ -165,7 +166,7 @@ impl TestOpenRepository {
|
||||||
fetch_counter: Arc::new(RwLock::new(0)),
|
fetch_counter: Arc::new(RwLock::new(0)),
|
||||||
on_push,
|
on_push,
|
||||||
push_counter: Arc::new(RwLock::new(0)),
|
push_counter: Arc::new(RwLock::new(0)),
|
||||||
real: RealOpenRepository::new(Arc::new(RwLock::new(gix.into()))),
|
real: RealOpenRepository::new(Arc::new(RwLock::new(gix.into())), forge_details),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use crate::CommitCount;
|
||||||
|
|
||||||
//
|
//
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -6,7 +8,8 @@ use super::*;
|
||||||
fn should_return_single_item_in_commit_log_when_not_searching() -> TestResult {
|
fn should_return_single_item_in_commit_log_when_not_searching() -> TestResult {
|
||||||
let_assert!(Ok(fs) = kxio::fs::temp());
|
let_assert!(Ok(fs) = kxio::fs::temp());
|
||||||
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
||||||
let test_repository = git::repository::test(fs.clone());
|
let forge_details = given::forge_details();
|
||||||
|
let test_repository = git::repository::test(fs.clone(), forge_details);
|
||||||
let_assert!(Ok(open_repository) = test_repository.open(&gitdir));
|
let_assert!(Ok(open_repository) = test_repository.open(&gitdir));
|
||||||
let repo_config = &given::a_repo_config();
|
let repo_config = &given::a_repo_config();
|
||||||
let branches = repo_config.branches();
|
let branches = repo_config.branches();
|
||||||
|
@ -23,7 +26,10 @@ fn should_return_capacity_25_in_commit_log_when_searching_for_garbage() -> TestR
|
||||||
let_assert!(Ok(fs) = kxio::fs::temp());
|
let_assert!(Ok(fs) = kxio::fs::temp());
|
||||||
let branch_name = given::a_branch_name();
|
let branch_name = given::a_branch_name();
|
||||||
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
||||||
let test_repository = git::repository::test(fs.clone());
|
let forge_details = given::forge_details().with_max_dev_commits(Some(CommitCount::from(25)));
|
||||||
|
let_assert!(Some(max_dev_commits) = forge_details.max_dev_commits());
|
||||||
|
assert!(**max_dev_commits >= 25);
|
||||||
|
let test_repository = git::repository::test(fs.clone(), forge_details);
|
||||||
let_assert!(Ok(open_repository) = test_repository.open(&gitdir));
|
let_assert!(Ok(open_repository) = test_repository.open(&gitdir));
|
||||||
for _ in [0; 25] {
|
for _ in [0; 25] {
|
||||||
then::create_a_commit_on_branch(&fs, &gitdir, &branch_name)?;
|
then::create_a_commit_on_branch(&fs, &gitdir, &branch_name)?;
|
||||||
|
@ -39,7 +45,10 @@ fn should_return_5_in_commit_log_when_searching_for_5th_item() -> TestResult {
|
||||||
let_assert!(Ok(fs) = kxio::fs::temp(), "create temp directory");
|
let_assert!(Ok(fs) = kxio::fs::temp(), "create temp directory");
|
||||||
let branch_name = given::a_branch_name();
|
let branch_name = given::a_branch_name();
|
||||||
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
||||||
let test_repository = git::repository::test(fs.clone());
|
let forge_details = given::forge_details().with_max_dev_commits(Some(CommitCount::from(10)));
|
||||||
|
let_assert!(Some(max_dev_commits) = forge_details.max_dev_commits());
|
||||||
|
assert!(**max_dev_commits > 5);
|
||||||
|
let test_repository = git::repository::test(fs.clone(), forge_details);
|
||||||
let_assert!(
|
let_assert!(
|
||||||
Ok(open_repository) = test_repository.open(&gitdir),
|
Ok(open_repository) = test_repository.open(&gitdir),
|
||||||
"open repository"
|
"open repository"
|
||||||
|
|
|
@ -14,7 +14,14 @@ fn should_return_repos() {
|
||||||
let mut repos = BTreeMap::new();
|
let mut repos = BTreeMap::new();
|
||||||
repos.insert(red_name.clone(), red.clone());
|
repos.insert(red_name.clone(), red.clone());
|
||||||
repos.insert(blue_name.clone(), blue.clone());
|
repos.insert(blue_name.clone(), blue.clone());
|
||||||
let fc = ForgeConfig::new(forge_type, hostname, user, token, repos);
|
let fc = ForgeConfig::new(
|
||||||
|
forge_type,
|
||||||
|
hostname,
|
||||||
|
user,
|
||||||
|
token,
|
||||||
|
given::maybe_a_number(),
|
||||||
|
repos,
|
||||||
|
);
|
||||||
|
|
||||||
let returned_repos = fc.repos().collect::<Vec<_>>();
|
let returned_repos = fc.repos().collect::<Vec<_>>();
|
||||||
|
|
||||||
|
@ -35,7 +42,14 @@ fn should_return_forge_type() {
|
||||||
let user = given::a_name();
|
let user = given::a_name();
|
||||||
let token = given::a_name();
|
let token = given::a_name();
|
||||||
let repos = BTreeMap::new();
|
let repos = BTreeMap::new();
|
||||||
let fc = ForgeConfig::new(forge_type, hostname, user, token, repos);
|
let fc = ForgeConfig::new(
|
||||||
|
forge_type,
|
||||||
|
hostname,
|
||||||
|
user,
|
||||||
|
token,
|
||||||
|
given::maybe_a_number(),
|
||||||
|
repos,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(fc.forge_type(), ForgeType::MockForge);
|
assert_eq!(fc.forge_type(), ForgeType::MockForge);
|
||||||
}
|
}
|
||||||
|
@ -47,7 +61,14 @@ fn should_return_hostname() {
|
||||||
let user = given::a_name();
|
let user = given::a_name();
|
||||||
let token = given::a_name();
|
let token = given::a_name();
|
||||||
let repos = BTreeMap::new();
|
let repos = BTreeMap::new();
|
||||||
let fc = ForgeConfig::new(forge_type, hostname.clone(), user, token, repos);
|
let fc = ForgeConfig::new(
|
||||||
|
forge_type,
|
||||||
|
hostname.clone(),
|
||||||
|
user,
|
||||||
|
token,
|
||||||
|
given::maybe_a_number(),
|
||||||
|
repos,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(fc.hostname(), Hostname::new(hostname));
|
assert_eq!(fc.hostname(), Hostname::new(hostname));
|
||||||
}
|
}
|
||||||
|
@ -59,7 +80,14 @@ fn should_return_user() {
|
||||||
let user = given::a_name();
|
let user = given::a_name();
|
||||||
let token = given::a_name();
|
let token = given::a_name();
|
||||||
let repos = BTreeMap::new();
|
let repos = BTreeMap::new();
|
||||||
let fc = ForgeConfig::new(forge_type, hostname, user.clone(), token, repos);
|
let fc = ForgeConfig::new(
|
||||||
|
forge_type,
|
||||||
|
hostname,
|
||||||
|
user.clone(),
|
||||||
|
token,
|
||||||
|
given::maybe_a_number(),
|
||||||
|
repos,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(fc.user(), User::new(user));
|
assert_eq!(fc.user(), User::new(user));
|
||||||
}
|
}
|
||||||
|
@ -71,7 +99,14 @@ fn should_return_token() {
|
||||||
let user = given::a_name();
|
let user = given::a_name();
|
||||||
let token = given::a_name();
|
let token = given::a_name();
|
||||||
let repos = BTreeMap::new();
|
let repos = BTreeMap::new();
|
||||||
let fc = ForgeConfig::new(forge_type, hostname, user, token.clone(), repos);
|
let fc = ForgeConfig::new(
|
||||||
|
forge_type,
|
||||||
|
hostname,
|
||||||
|
user,
|
||||||
|
token.clone(),
|
||||||
|
given::maybe_a_number(),
|
||||||
|
repos,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(fc.token().expose_secret(), token.as_str());
|
assert_eq!(fc.token().expose_secret(), token.as_str());
|
||||||
}
|
}
|
||||||
|
@ -90,7 +125,14 @@ fn should_return_repo() {
|
||||||
let mut repos = BTreeMap::new();
|
let mut repos = BTreeMap::new();
|
||||||
repos.insert(red_name.clone(), red.clone());
|
repos.insert(red_name.clone(), red.clone());
|
||||||
repos.insert(blue_name, blue);
|
repos.insert(blue_name, blue);
|
||||||
let fc = ForgeConfig::new(forge_type, hostname, user, token, repos);
|
let fc = ForgeConfig::new(
|
||||||
|
forge_type,
|
||||||
|
hostname,
|
||||||
|
user,
|
||||||
|
token,
|
||||||
|
given::maybe_a_number(),
|
||||||
|
repos,
|
||||||
|
);
|
||||||
|
|
||||||
let returned_repo = fc.get_repo(red_name.as_str());
|
let returned_repo = fc.get_repo(red_name.as_str());
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,9 @@ fn should_return_file() -> TestResult {
|
||||||
let file_name = given::a_pathbuf();
|
let file_name = given::a_pathbuf();
|
||||||
let contents = given::a_name();
|
let contents = given::a_name();
|
||||||
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
||||||
|
let forge_details = given::forge_details();
|
||||||
|
|
||||||
let test_repository = git::repository::test(fs.clone());
|
let test_repository = git::repository::test(fs.clone(), forge_details);
|
||||||
let_assert!(Ok(open_repository) = test_repository.open(&gitdir));
|
let_assert!(Ok(open_repository) = test_repository.open(&gitdir));
|
||||||
then::commit_named_file_to_branch(
|
then::commit_named_file_to_branch(
|
||||||
&file_name,
|
&file_name,
|
||||||
|
@ -33,7 +34,8 @@ fn should_return_file() -> TestResult {
|
||||||
fn should_error_on_missing_file() -> TestResult {
|
fn should_error_on_missing_file() -> TestResult {
|
||||||
let_assert!(Ok(fs) = kxio::fs::temp());
|
let_assert!(Ok(fs) = kxio::fs::temp());
|
||||||
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
||||||
let test_repository = git::repository::test(fs.clone());
|
let forge_details = given::forge_details();
|
||||||
|
let test_repository = git::repository::test(fs.clone(), forge_details);
|
||||||
let_assert!(Ok(open_repository) = test_repository.open(&gitdir));
|
let_assert!(Ok(open_repository) = test_repository.open(&gitdir));
|
||||||
let repo_config = &given::a_repo_config();
|
let repo_config = &given::a_repo_config();
|
||||||
let branches = repo_config.branches();
|
let branches = repo_config.branches();
|
||||||
|
|
|
@ -13,7 +13,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
RepoDetails,
|
RepoDetails,
|
||||||
},
|
},
|
||||||
GitDir,
|
ForgeDetails, GitDir,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[allow(clippy::module_name_repetitions)]
|
#[allow(clippy::module_name_repetitions)]
|
||||||
|
@ -22,6 +22,7 @@ pub struct TestRepository {
|
||||||
fs: kxio::fs::FileSystem,
|
fs: kxio::fs::FileSystem,
|
||||||
on_fetch: Vec<git::repository::open::otest::OnFetch>,
|
on_fetch: Vec<git::repository::open::otest::OnFetch>,
|
||||||
on_push: Vec<git::repository::open::otest::OnPush>,
|
on_push: Vec<git::repository::open::otest::OnPush>,
|
||||||
|
forge_details: ForgeDetails,
|
||||||
}
|
}
|
||||||
impl TestRepository {
|
impl TestRepository {
|
||||||
pub fn on_fetch(&mut self, on_fetch: OnFetch) {
|
pub fn on_fetch(&mut self, on_fetch: OnFetch) {
|
||||||
|
@ -39,6 +40,7 @@ impl RepositoryLike for TestRepository {
|
||||||
&self.fs,
|
&self.fs,
|
||||||
self.on_fetch.clone(),
|
self.on_fetch.clone(),
|
||||||
self.on_push.clone(),
|
self.on_push.clone(),
|
||||||
|
self.forge_details.clone(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -172,6 +172,7 @@ mod repo_details {
|
||||||
"host".to_string(),
|
"host".to_string(),
|
||||||
"user".to_string(),
|
"user".to_string(),
|
||||||
"token".to_string(),
|
"token".to_string(),
|
||||||
|
given::maybe_a_number(), // max dev commits
|
||||||
BTreeMap::new(),
|
BTreeMap::new(),
|
||||||
),
|
),
|
||||||
GitDir::new(PathBuf::default().join("foo"), StoragePathType::Internal),
|
GitDir::new(PathBuf::default().join("foo"), StoragePathType::Internal),
|
||||||
|
@ -184,6 +185,8 @@ mod repo_details {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub mod given {
|
pub mod given {
|
||||||
|
use crate::ForgeDetails;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub fn repo_branches() -> RepoBranches {
|
pub fn repo_branches() -> RepoBranches {
|
||||||
|
@ -219,6 +222,22 @@ pub mod given {
|
||||||
generate(5)
|
generate(5)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn maybe_a_number() -> Option<u32> {
|
||||||
|
use rand::Rng;
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
if Rng::gen_ratio(&mut rng, 1, 2) {
|
||||||
|
Some(a_number())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn a_number() -> u32 {
|
||||||
|
use rand::Rng;
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
rng.gen_range(5..100)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn a_branch_name() -> BranchName {
|
pub fn a_branch_name() -> BranchName {
|
||||||
BranchName::new(a_name())
|
BranchName::new(a_name())
|
||||||
}
|
}
|
||||||
|
@ -235,10 +254,15 @@ pub mod given {
|
||||||
format!("hostname-{}", a_name()),
|
format!("hostname-{}", a_name()),
|
||||||
format!("user-{}", a_name()),
|
format!("user-{}", a_name()),
|
||||||
format!("token-{}", a_name()),
|
format!("token-{}", a_name()),
|
||||||
BTreeMap::default(), // no repos
|
given::maybe_a_number(), // max dev commits
|
||||||
|
BTreeMap::default(), // no repos
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn forge_details() -> ForgeDetails {
|
||||||
|
(&a_forge_alias(), &a_forge_config()).into()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn a_server_repo_config() -> ServerRepoConfig {
|
pub fn a_server_repo_config() -> ServerRepoConfig {
|
||||||
let main = a_branch_name().peel();
|
let main = a_branch_name().peel();
|
||||||
let next = a_branch_name().peel();
|
let next = a_branch_name().peel();
|
||||||
|
|
|
@ -207,7 +207,8 @@ mod positions {
|
||||||
//given
|
//given
|
||||||
let fs = given::a_filesystem();
|
let fs = given::a_filesystem();
|
||||||
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
||||||
let mut test_repository = git::repository::test(fs.clone());
|
let forge_details = given::forge_details();
|
||||||
|
let mut test_repository = git::repository::test(fs.clone(), forge_details);
|
||||||
let repo_config = given::a_repo_config();
|
let repo_config = given::a_repo_config();
|
||||||
test_repository.on_fetch(OnFetch::new(
|
test_repository.on_fetch(OnFetch::new(
|
||||||
repo_config.branches().clone(),
|
repo_config.branches().clone(),
|
||||||
|
@ -257,7 +258,8 @@ mod positions {
|
||||||
//given
|
//given
|
||||||
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
|
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
|
||||||
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
||||||
let mut test_repository = git::repository::test(fs.clone());
|
let forge_details = given::forge_details();
|
||||||
|
let mut test_repository = git::repository::test(fs.clone(), forge_details);
|
||||||
let repo_config = given::a_repo_config();
|
let repo_config = given::a_repo_config();
|
||||||
test_repository.on_fetch(OnFetch::new(
|
test_repository.on_fetch(OnFetch::new(
|
||||||
repo_config.branches().clone(),
|
repo_config.branches().clone(),
|
||||||
|
@ -343,7 +345,8 @@ mod positions {
|
||||||
//given
|
//given
|
||||||
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
|
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
|
||||||
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
||||||
let mut test_repository = git::repository::test(fs.clone());
|
let forge_details = given::forge_details();
|
||||||
|
let mut test_repository = git::repository::test(fs.clone(), forge_details);
|
||||||
let repo_config = given::a_repo_config();
|
let repo_config = given::a_repo_config();
|
||||||
test_repository.on_fetch(OnFetch::new(
|
test_repository.on_fetch(OnFetch::new(
|
||||||
repo_config.branches().clone(),
|
repo_config.branches().clone(),
|
||||||
|
@ -416,7 +419,8 @@ mod positions {
|
||||||
//given
|
//given
|
||||||
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
|
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
|
||||||
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
||||||
let mut test_repository = git::repository::test(fs.clone());
|
let forge_details = given::forge_details();
|
||||||
|
let mut test_repository = git::repository::test(fs.clone(), forge_details);
|
||||||
let repo_config = given::a_repo_config();
|
let repo_config = given::a_repo_config();
|
||||||
test_repository.on_fetch(OnFetch::new(
|
test_repository.on_fetch(OnFetch::new(
|
||||||
repo_config.branches().clone(),
|
repo_config.branches().clone(),
|
||||||
|
@ -501,7 +505,8 @@ mod positions {
|
||||||
//given
|
//given
|
||||||
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
|
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
|
||||||
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
||||||
let mut test_repository = git::repository::test(fs.clone());
|
let forge_details = given::forge_details();
|
||||||
|
let mut test_repository = git::repository::test(fs.clone(), forge_details);
|
||||||
let repo_config = given::a_repo_config();
|
let repo_config = given::a_repo_config();
|
||||||
test_repository.on_fetch(OnFetch::new(
|
test_repository.on_fetch(OnFetch::new(
|
||||||
repo_config.branches().clone(),
|
repo_config.branches().clone(),
|
||||||
|
@ -598,7 +603,8 @@ mod positions {
|
||||||
//given
|
//given
|
||||||
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
|
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
|
||||||
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
||||||
let mut test_repository = git::repository::test(fs.clone());
|
let forge_details = given::forge_details();
|
||||||
|
let mut test_repository = git::repository::test(fs.clone(), forge_details);
|
||||||
let repo_config = given::a_repo_config();
|
let repo_config = given::a_repo_config();
|
||||||
test_repository.on_fetch(OnFetch::new(
|
test_repository.on_fetch(OnFetch::new(
|
||||||
repo_config.branches().clone(),
|
repo_config.branches().clone(),
|
||||||
|
|
|
@ -691,6 +691,22 @@ mod forgejo {
|
||||||
generate(5)
|
generate(5)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn maybe_a_number() -> Option<u32> {
|
||||||
|
use rand::Rng;
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
if Rng::gen_ratio(&mut rng, 1, 2) {
|
||||||
|
Some(a_number())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn a_number() -> u32 {
|
||||||
|
use rand::Rng;
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
rng.gen_range(0..100)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn a_webhook_id() -> WebhookId {
|
pub fn a_webhook_id() -> WebhookId {
|
||||||
WebhookId::new(a_name())
|
WebhookId::new(a_name())
|
||||||
}
|
}
|
||||||
|
@ -711,6 +727,7 @@ mod forgejo {
|
||||||
a_name(),
|
a_name(),
|
||||||
a_name(),
|
a_name(),
|
||||||
a_name(),
|
a_name(),
|
||||||
|
maybe_a_number(),
|
||||||
BTreeMap::default(), // no repos
|
BTreeMap::default(), // no repos
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -600,6 +600,7 @@ mod github {
|
||||||
a_name(),
|
a_name(),
|
||||||
a_name(),
|
a_name(),
|
||||||
a_name(),
|
a_name(),
|
||||||
|
maybe_a_number(),
|
||||||
BTreeMap::default(),
|
BTreeMap::default(),
|
||||||
),
|
),
|
||||||
GitDir::new(PathBuf::default(), StoragePathType::External),
|
GitDir::new(PathBuf::default(), StoragePathType::External),
|
||||||
|
@ -641,6 +642,22 @@ mod github {
|
||||||
generate(5)
|
generate(5)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn maybe_a_number() -> Option<u32> {
|
||||||
|
use rand::Rng;
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
if Rng::gen_ratio(&mut rng, 1, 2) {
|
||||||
|
Some(a_number())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn a_number() -> u32 {
|
||||||
|
use rand::Rng;
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
rng.gen_range(0..100)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn a_webhook_id() -> WebhookId {
|
pub fn a_webhook_id() -> WebhookId {
|
||||||
WebhookId::new(given::a_name())
|
WebhookId::new(given::a_name())
|
||||||
}
|
}
|
||||||
|
|
447
demo.cast
Normal file
447
demo.cast
Normal file
|
@ -0,0 +1,447 @@
|
||||||
|
{"version": 2, "width": 80, "height": 24, "timestamp": 1726490135, "env": {"SHELL": "/opt/homebrew/bin/bash", "TERM": "xterm-256color"}}
|
||||||
|
[0.029531, "o", "\u001b[?1049h"]
|
||||||
|
[0.030008, "o", "\u001b[1;1H┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[1m Git-Next v0.13.11 \u001b[22m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\u001b[2;1H┃\u001b[2;36HLoading...1\u001b[2;80H┃\u001b[3;1H┃\u001b[3;80H┃\u001b[4;1H┃\u001b[4;80H┃\u001b[5;1H┃\u001b[5;80H┃\u001b[6;1H┃\u001b[6;80H┃\u001b[7;1H┃\u001b[7;80H┃\u001b[8;1H┃\u001b[8;80H┃\u001b[9;1H┃\u001b[9;80H┃\u001b[10;1H┃\u001b[10;80H┃\u001b[11;1H┃\u001b[11;80H┃\u001b[12;1H┃\u001b[12;80H┃\u001b[13;1H┃\u001b[13;80H┃\u001b[14;1H┃\u001b[14;80H┃\u001b[15;1H┃\u001b[15;80H┃\u001b[16;1H┃\u001b[16;80H┃\u001b[17;1H┃\u001b[17;80H┃\u001b[18;1H┃\u001b[18;80H┃\u001b[19;1H┃\u001b[19;80H┃\u001b[20;1H┃\u001b[20;80H┃\u001b[21;1H┃\u001b[21;80H┃\u001b[22;1H┃\u001b[22;80H┃\u001b[23;1H┃\u001b[23;80H┃\u001b[24;1H┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[24;36H[q]uit\u001b[24;43H💚\u001b[24;47H━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[24;74H13:35\u001b[24;80H┛\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[2.552043, "o", "\u001b[2;3Hforge:\u001b[2;10Hjo\u001b[2;36H \u001b[3;3H\u001b[38;5;6;49mgit-next\u001b[3;12H\u001b[39;49m(main\u001b[3;18H->\u001b[3;21Hnext\u001b[3;26H->\u001b[3;29Hdev)\u001b[3;34H\u001b[38;5;7;49mregistering webhook...\u001b[3;57H\u001b[39;49m──────────────────────\u001b[5;3H\u001b[38;5;6;49mkxio\u001b[5;8H\u001b[39;49m(main\u001b[5;14H->\u001b[5;17Hnext\u001b[5;22H->\u001b[5;25Hdev)\u001b[5;30H\u001b[38;5;7;49mregistering webhook...\u001b[5;53H\u001b[39;49m──────────────────────────\u001b[7;3H\u001b[38;5;6;49mpodal\u001b[7;9H\u001b[39;49m(main\u001b[7;15H->\u001b[7;18Hnext\u001b[7;23H->\u001b[7;26Hdev)\u001b[7;31H\u001b[38;5;7;49mregistering webhook...\u001b[7;54H\u001b[39;49m─────────────────────────\u001b[9;3H\u001b[38;5;6;49mrefile-m4b\u001b[9;14H\u001b[39;49m(main\u001b[9;20H->\u001b[9;23Hnext\u001b[9;28H->\u001b[9;31Hdev)\u001b[9;36H\u001b[38;5;7;49mregistering webhook...\u001b[9;59H\u001b[39;49m────────────────────\u001b[11;3H\u001b[38;5;6;49mrust-action\u001b[11;15H\u001b[39;49m(main\u001b[11;21H->\u001b[11;24Hnext\u001b[11;29H->\u001b[11;32Hdev)\u001b[11;37H\u001b[38;5;7;49mregistering webhook...\u001b[11;60H"]
|
||||||
|
[2.552123, "o", "\u001b[39;49m───────────────────\u001b[13;3H\u001b[38;5;6;49mskip\u001b[13;8H\u001b[39;49m(main\u001b[13;14H->\u001b[13;17Hnext\u001b[13;22H->\u001b[13;25Hdev)\u001b[13;30H\u001b[38;5;7;49mregistering webhook...\u001b[13;53H\u001b[39;49m──────────────────────────\u001b[15;3H\u001b[38;5;6;49mtasyn\u001b[15;9H\u001b[39;49m(main\u001b[15;15H->\u001b[15;18Hnext\u001b[15;23H->\u001b[15;26Hdev)\u001b[15;31H\u001b[38;5;7;49mregistering webhook...\u001b[15;54H\u001b[39;49m─────────────────────────\u001b[17;3H\u001b[38;5;6;49mtest\u001b[17;8H\u001b[39;49m(main\u001b[17;14H->\u001b[17;17Hnext\u001b[17;22H->\u001b[17;25Hdev)\u001b[17;30H\u001b[38;5;7;49mregistering webhook...\u001b[17;53H\u001b[39;49m──────────────────────────\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[2.614517, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[2.649175, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[2.684709, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[2.71967, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[2.75525, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[2.789211, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[2.826615, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[3.673281, "o", "\u001b[7;31H\u001b[38;5;2;49mokay\u001b[39;49m ──────────────────\u001b[8;2H*\u001b[8;4H249b943\u001b[8;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[8;30H\u001b[39;49mfix(deps):\u001b[8;41Hupdate\u001b[8;48Hrust\u001b[8;53Hcrate\u001b[8;59Hscraper\u001b[8;67Hto\u001b[8;70H0.20\u001b[9;3H \u001b[9;14H \u001b[9;20H \u001b[9;23H \u001b[9;28H \u001b[9;31H \u001b[9;36H \u001b[9;59H \u001b[10;3H\u001b[38;5;6;49mrefile-m4b\u001b[10;14H\u001b[39;49m(main\u001b[10;20H->\u001b[10;23Hnext\u001b[10;28H->\u001b[10;31Hdev)\u001b[10;36H\u001b[38;5;7;49mregistering webhook...\u001b[10;59H\u001b[39;49m────────────────────\u001b[11;3H \u001b[11;15H \u001b[11;21H \u001b[11;24H \u001b[11;29H \u001b[11;32H \u001b[11;37H \u001b[11;60H \u001b[12;3H\u001b[38;5;6;49mrust-action\u001b[12;15H\u001b[39;49m(main\u001b[12;21H->\u001b[12;24Hnext\u001b[12;29H->\u001b[12;32Hdev)\u001b[12;37H\u001b[38;5;7;49mregistering webhook...\u001b[12;60H\u001b[39;49m───────────────────\u001b[13;3H \u001b[13;8H \u001b[13;14H \u001b[13;17H \u001b[13;22H \u001b[13;25H \u001b[13;30H \u001b[13;53"]
|
||||||
|
[3.673319, "o", "H \u001b[14;3H\u001b[38;5;6;49mskip\u001b[14;8H\u001b[39;49m(main\u001b[14;14H->\u001b[14;17Hnext\u001b[14;22H->\u001b[14;25Hdev)\u001b[14;30H\u001b[38;5;2;49mokay\u001b[14;35H\u001b[39;49m────────────────────────────────────────────\u001b[15;2H* fc7fbca \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m chore(deps): update docker.io/rust docker tag to \u001b[17;4H\u001b[38;5;6;49ma\u001b[17;6Hyn\u001b[39;49m (main -> next -> dev) \u001b[38;5;7;49mregistering webh\u001b[17;48Hok\u001b[17;52H.\u001b[39;49m \u001b[19;3H\u001b[38;5;6;49mtest\u001b[19;8H\u001b[39;49m(main\u001b[19;14H->\u001b[19;17Hnext\u001b[19;22H->\u001b[19;25Hdev)\u001b[19;30H\u001b[38;5;7;49mregistering webhook...\u001b[19;53H\u001b[39;49m──────────────────────────\u001b[24;43H 💚\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[4.567297, "o", "\u001b[2;79H▲\u001b[3;34H\u001b[38;5;2;49mokay\u001b[39;49m ──────────────────\u001b[3;79H█\u001b[4;2H*\u001b[4;4H91c5973\u001b[4;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[4;30H\u001b[39;49mchore:\u001b[4;37Hrelease\u001b[4;79H█\u001b[5;3H \u001b[5;8H \u001b[5;14H \u001b[5;17H \u001b[5;22H \u001b[5;25H \u001b[5;30H \u001b[5;53H █\u001b[6;3H\u001b[38;5;6;49mkxio\u001b[6;8H\u001b[39;49m(main\u001b[6;14H->\u001b[6;17Hnext\u001b[6;22H->\u001b[6;25Hdev)\u001b[6;30H\u001b[38;5;7;49mregistering webhook...\u001b[6;53H\u001b[39;49m──────────────────────────█\u001b[7;3H \u001b[7;9H \u001b[7;15H \u001b[7;18H \u001b[7;23H \u001b[7;26H \u001b[7;31H \u001b[7;36H █\u001b[8;2H \u001b[38;5;6;49mpodal\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ───────────────────────────────────────────█\u001b[9;2H*\u001b[9;4H249b943\u001b[9;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[9;30H\u001b[39;49mfix(deps):\u001b[9;41Hupdate\u001b[9;48Hrust\u001b[9;53Hcrate\u001b[9;59Hs"]
|
||||||
|
[4.567379, "o", "craper\u001b[9;67Hto\u001b[9;70H0.20\u001b[9;79H█\u001b[10;3H \u001b[10;14H \u001b[10;20H \u001b[10;23H \u001b[10;28H \u001b[10;31H \u001b[10;36H \u001b[10;59H █\u001b[11;3H\u001b[38;5;6;49mrefile-m4b\u001b[11;14H\u001b[39;49m(main\u001b[11;20H->\u001b[11;23Hnext\u001b[11;28H->\u001b[11;31Hdev)\u001b[11;36H\u001b[38;5;7;49mregistering webhook...\u001b[11;59H\u001b[39;49m────────────────────█\u001b[12;3H \u001b[12;15H \u001b[12;21H \u001b[12;24H \u001b[12;29H \u001b[12;32H \u001b[12;37H \u001b[12;60H █\u001b[13;3H\u001b[38;5;6;49mrust-action\u001b[13;15H\u001b[39;49m(main\u001b[13;21H->\u001b[13;24Hnext\u001b[13;29H->\u001b[13;32Hdev)\u001b[13;37H\u001b[38;5;2;49mokay\u001b[13;42H\u001b[39;49m─────────────────────────────────────║\u001b[14;2H* de4785c \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[14;30H\u001b[39;49mfeat: ensure toolchains are up-to-date ║\u001b[15;2H \u001b[15;4H \u001b[15;12H \u001b[15;30H \u001b[15;43H \u001b[15;50H \u001b[15;65H \u001b[15;72H \u001b[15;76"]
|
||||||
|
[4.567437, "o", "H \u001b[15;79H║\u001b[16;3H\u001b[38;5;6;49mskip\u001b[16;8H\u001b[39;49m(main\u001b[16;14H->\u001b[16;17Hnext\u001b[16;22H->\u001b[16;25Hdev)\u001b[16;30H\u001b[38;5;2;49mokay\u001b[16;35H\u001b[39;49m────────────────────────────────────────────║\u001b[17;2H* fc7fbca \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m chore(deps): update docker.io/rust docker tag to ║\u001b[18;79H║\u001b[19;4H\u001b[38;5;6;49ma\u001b[19;6Hyn\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ─────────────────\u001b[19;79H║\u001b[20;2H*\u001b[20;4H24fe845\u001b[20;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[20;30H\u001b[39;49mchore(deps):\u001b[20;43Hupdate\u001b[20;50Hdocker.io/postgres:16.4-alpin║\u001b[21;79H║\u001b[22;3H\u001b[38;5;6;49mtest\u001b[22;8H\u001b[39;49m(main\u001b[22;14H->\u001b[22;17Hnext\u001b[22;22H->\u001b[22;25Hdev)\u001b[22;30H\u001b[38;5;7;49mregistering webhook...\u001b[22;53H\u001b[39;49m──────────────────────────║\u001b[23;79H▼\u001b[24;43H💚\u001b[24;45H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[4.603024, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[4.636433, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[5.373579, "o", "\u001b[11;36H\u001b[38;5;2;49mokay\u001b[39;49m ──────────────────\u001b[12;2H*\u001b[12;4H7fba5fb\u001b[12;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[12;30H\u001b[39;49mSupport\u001b[12;38H--version,\u001b[12;49H--help\u001b[12;56Hand\u001b[12;60H--directory\u001b[12;72Hcli\u001b[12;76Harg\u001b[13;3H \u001b[13;15H \u001b[13;21H \u001b[13;24H \u001b[13;29H \u001b[13;32H \u001b[13;37H \u001b[13;42H \u001b[14;2H \u001b[38;5;6;49mrust-action\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ─────────────────────────────────────\u001b[15;2H*\u001b[15;4Hde4785c\u001b[15;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[15;30H\u001b[39;49mfeat:\u001b[15;36Hensure\u001b[15;43Htoolchains\u001b[15;54Hare\u001b[15;58Hup-to-date\u001b[16;3H \u001b[16;8H \u001b[16;14H \u001b[16;17H \u001b[16;22H \u001b[16;25H \u001b[16;30H \u001b[16;35H \u001b[17;2H \u001b[38;5;6;49mskip\u001b[39;49m (m\u001b[17;11Hin -> next -> dev)\u001b[17;30H\u001b[38;5;2;49mokay\u001b[39;49m ─────────────────────"]
|
||||||
|
[5.373661, "o", "───────────────────────\u001b[18;2H*\u001b[18;4Hfc7fbca\u001b[18;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[18;30H\u001b[39;49mchore(deps):\u001b[18;43Hupdate\u001b[18;50Hdocker.io/rust\u001b[18;65Hdocker\u001b[18;72Htag\u001b[18;76Hto\u001b[19;3H \u001b[19;9H \u001b[19;15H \u001b[19;18H \u001b[19;23H \u001b[19;26H \u001b[19;31H \u001b[19;36H \u001b[20;2H \u001b[38;5;6;49mtasyn\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ───────────────────────────────────────────\u001b[21;2H*\u001b[21;4H24fe845\u001b[21;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[21;30H\u001b[39;49mchore(deps):\u001b[21;43Hupdate\u001b[21;50Hdocker.io/postgres:16.4-alpin\u001b[22;3H \u001b[22;8H \u001b[22;14H \u001b[22;17H \u001b[22;22H \u001b[22;25H \u001b[22;30H \u001b[22;53H \u001b[23;3H\u001b[38;5;6;49mtest\u001b[23;8H\u001b[39;49m(main\u001b[23;14H->\u001b[23;17Hnext\u001b[23;22H->\u001b[23;25Hdev)\u001b[23;30H\u001b[38;5;2;49mokay\u001b[23;35H\u001b[39;49m─────────────────"]
|
||||||
|
[5.373769, "o", "───────────────────────────\u001b[24;43H 💚\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[5.667499, "o", "\u001b[6;3H\u001b[38;5;15;48;5;1mkxio\u001b[6;8Hcommit is a Work-in-progress\u001b[39;49m (main -> next -> dev) \u001b[38;5;1;49mALERT\u001b[39;49m \u001b[7;2H*\u001b[7;4H805d0b3\u001b[7;12H\u001b[38;5;15;48;5;4m(dev)\u001b[7;18H\u001b[39;49mWIP:\u001b[7;23Hdocs(fs):\u001b[7;33Hadd\u001b[7;37Hsome\u001b[7;42Hdocumentation\u001b[8;2H* 9943a0f \u001b[38;5;15;48;5;4m(main)(next)\u001b[39;49m chore(deps): update docker.io/rust docker tag to v1.81\u001b[9;2H \u001b[9;4H \u001b[9;12H \u001b[9;30H \u001b[9;41H \u001b[9;48H \u001b[9;53H \u001b[9;59H \u001b[9;67H \u001b[9;70H \u001b[10;3H\u001b[38;5;6;49mpodal\u001b[10;9H\u001b[39;49m(main\u001b[10;15H->\u001b[10;18Hnext\u001b[10;23H->\u001b[10;26Hdev)\u001b[10;31H\u001b[38;5;2;49mokay\u001b[10;36H\u001b[39;49m───────────────────────────────────────────\u001b[11;2H* 249b943 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m fix(deps):\u001b[11;41Hupdate rust crate scraper to 0.20 \u001b[12;2H \u001b[12;4H \u001b[12;12H \u001b[12;30H \u001b[12;38H \u001b[12;49H \u001b[12;56H \u001b[12;60H \u001b[12;72H \u001b[12;76H ║\u001b[13;3H\u001b[38;5;6;49mr"]
|
||||||
|
[5.667549, "o", "efile-m4b\u001b[13;14H\u001b[39;49m(main\u001b[13;20H->\u001b[13;23Hnext\u001b[13;28H->\u001b[13;31Hdev)\u001b[13;36H\u001b[38;5;2;49mokay\u001b[13;41H\u001b[39;49m──────────────────────────────────────\u001b[14;2H* 7fba5fb \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m Support --version, --help and --directory cli arg\u001b[15;2H \u001b[15;4H \u001b[15;12H \u001b[15;30H \u001b[15;36H \u001b[15;43H \u001b[15;54H \u001b[15;58H \u001b[16;3H\u001b[38;5;6;49mrust-action\u001b[16;15H\u001b[39;49m(main\u001b[16;21H->\u001b[16;24Hnext\u001b[16;29H->\u001b[16;32Hdev)\u001b[16;37H\u001b[38;5;2;49mokay\u001b[16;42H\u001b[39;49m─────────────────────────────────────\u001b[17;2H* de4785c \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[17;30H\u001b[39;49mfeat: ensure toolchains are up-to-date \u001b[18;2H \u001b[18;4H \u001b[18;12H \u001b[18;30H \u001b[18;43H \u001b[18;50H \u001b[18;65H \u001b[18;72H \u001b[18;76H \u001b[19;3H\u001b[38;5;6;49mskip\u001b[19;8H\u001b[39;49m(main\u001b[19;14H->\u001b[19;17Hnext\u001b"]
|
||||||
|
[5.667635, "o", "[19;22H->\u001b[19;25Hdev)\u001b[19;30H\u001b[38;5;2;49mokay\u001b[19;35H\u001b[39;49m────────────────────────────────────────────\u001b[20;2H* fc7fbca \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m chore(deps): update docker.io/rust docker tag to \u001b[21;2H \u001b[21;4H \u001b[21;12H \u001b[21;30H \u001b[21;43H \u001b[21;50H \u001b[22;3H\u001b[38;5;6;49mtasyn\u001b[22;9H\u001b[39;49m(main\u001b[22;15H->\u001b[22;18Hnext\u001b[22;23H->\u001b[22;26Hdev)\u001b[22;31H\u001b[38;5;2;49mokay\u001b[22;36H\u001b[39;49m───────────────────────────────────────────\u001b[23;2H* 24fe845 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[23;30H\u001b[39;49mchore(deps): update docker.io/postgres:16.4-alpin\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[5.703032, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[5.738998, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[5.774205, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[5.808972, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[5.844592, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[5.881476, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[5.91946, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[5.956562, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[5.993522, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.031996, "o", "\u001b[24;43H💚\u001b[24;45H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.069336, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.109029, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.1469, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.184289, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.220107, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.256197, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.293358, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.331134, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.366742, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.402568, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.439465, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.478813, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.517268, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.560687, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.594301, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.629263, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.669428, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.706761, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.742165, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.78203, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.822172, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.859887, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.897026, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.938296, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[6.975571, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.01065, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.047644, "o", "\u001b[24;43H 💚\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.08457, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.121364, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.157513, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.195418, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.228658, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.264878, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.305593, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.3437, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.381122, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.418853, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.454425, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.492184, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.540907, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.578132, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.614231, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.65196, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.69186, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.731624, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.767836, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.804511, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.840577, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.877375, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.913764, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.952312, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[7.989869, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.031084, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.068302, "o", "\u001b[24;43H💚\u001b[24;45H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.104549, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.140569, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.177935, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.21429, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.251383, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.289527, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.329826, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.367669, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.404116, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.441232, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.479153, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.516467, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.554111, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.590533, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.631784, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.672414, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.708258, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.745135, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.78123, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.82166, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.861283, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.898503, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.934001, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[8.971135, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.008281, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.045177, "o", "\u001b[24;43H 💚\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.082668, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.119739, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.156767, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.194149, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.23081, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.2488, "o", "\u001b[2;3H\u001b[38;5;6;49mgit-next\u001b[39;49m (main\u001b[2;18H->\u001b[2;21Hnext\u001b[2;26H->\u001b[2;29Hdev)\u001b[2;34H\u001b[38;5;2;49mokay\u001b[2;39H\u001b[39;49m────────────────────────────────────────\u001b[3;2H* 91c5973\u001b[3;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m chore: release \u001b[4;2H \u001b[4;4H \u001b[4;12H \u001b[4;30H \u001b[4;37H \u001b[5;3H\u001b[38;5;15;48;5;1mkxio\u001b[5;8Hcommit is a Work-in-progress\u001b[5;37H\u001b[39;49m(main\u001b[5;43H->\u001b[5;46Hnext\u001b[5;51H->\u001b[5;54Hdev)\u001b[5;59H\u001b[38;5;1;49mALERT\u001b[5;65H\u001b[39;49m──────────────\u001b[6;2H* 805d0b3 \u001b[38;5;15;48;5;4m(dev)\u001b[39;49m WIP: docs(fs): add\u001b[6;37Hsome docum\u001b[6;48Hn\u001b[6;50Hation \u001b[6;59H \u001b[6;65H \u001b[7;4H9943a0f\u001b[7;13H\u001b[38;5;15;48;5;4mmain)(next)\u001b[39;49m \u001b[7;26Hhore(deps): update docker.\u001b[7;54H/rust\u001b[7;60Hdocker\u001b[7;67Htag\u001b[7;71Hto\u001b[7;74Hv1.81\u001b[8;2H \u001b[8;4H \u001b[8;12H \u001b[8;25H \u001b[8;38H \u001b[8;45H \u001b[8;60H \u001b[8;67H "]
|
||||||
|
[9.248957, "o", "\u001b[8;71H \u001b[8;74H \u001b[9;3H\u001b[38;5;6;49mpodal\u001b[9;9H\u001b[39;49m(main\u001b[9;15H->\u001b[9;18Hnext\u001b[9;23H->\u001b[9;26Hdev)\u001b[9;31H\u001b[38;5;2;49mokay\u001b[9;36H\u001b[39;49m───────────────────────────────────────────\u001b[10;2H* 249b943 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m fix(deps): update rust crate scraper to 0.20 \u001b[11;2H \u001b[11;4H \u001b[11;12H \u001b[11;30H \u001b[11;41H \u001b[11;48H \u001b[11;53H \u001b[11;59H \u001b[11;67H \u001b[11;70H \u001b[12;3H\u001b[38;5;6;49mrefile-m4b\u001b[12;14H\u001b[39;49m(main\u001b[12;20H->\u001b[12;23Hnext\u001b[12;28H->\u001b[12;31Hdev)\u001b[12;36H\u001b[38;5;2;49mokay\u001b[12;41H\u001b[39;49m──────────────────────────────────────█\u001b[13;2H* 7fba5fb \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m Support --version, --help and --directory cli arg\u001b[14;2H \u001b[14;4H \u001b[14;12H \u001b[14;30H \u001b[14;38H \u001b[14;49H \u001b[14;56H \u001b[14;60H \u001b[14;72H \u001b[14;76H "]
|
||||||
|
[9.249109, "o", " \u001b[15;3H\u001b[38;5;6;49mrust-action\u001b[15;15H\u001b[39;49m(main\u001b[15;21H->\u001b[15;24Hnext\u001b[15;29H->\u001b[15;32Hdev)\u001b[15;37H\u001b[38;5;2;49mokay\u001b[15;42H\u001b[39;49m─────────────────────────────────────\u001b[16;2H* de4785c \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m feat: ensure toolchains are up-to-date \u001b[17;2H \u001b[17;4H \u001b[17;12H \u001b[17;30H \u001b[17;36H \u001b[17;43H \u001b[17;54H \u001b[17;58H \u001b[18;3H\u001b[38;5;6;49mskip\u001b[18;8H\u001b[39;49m(main\u001b[18;14H->\u001b[18;17Hnext\u001b[18;22H->\u001b[18;25Hdev)\u001b[18;30H\u001b[38;5;2;49mokay\u001b[18;35H\u001b[39;49m────────────────────────────────────────────\u001b[19;2H* fc7fbc\u001b[19;11H \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[19;30H\u001b[39;49mchore(deps): update docker.io/rust docker tag to \u001b[20;2H \u001b[20;4H \u001b[20;12H \u001b[20;30H \u001b[20;43H \u001b[20;50H \u001b[20;65H \u001b[20;72H \u001b[20;76H \u001b[21;3H\u001b[38;5;6;49mtasyn\u001b["]
|
||||||
|
[9.249125, "o", "21;9H\u001b[39;49m(main\u001b[21;15H->\u001b[21;18Hnext\u001b[21;23H->\u001b[21;26Hdev)\u001b[21;31H\u001b[38;5;2;49mokay\u001b[21;36H\u001b[39;49m───────────────────────────────────────────\u001b[22;2H* 24fe845 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m chore(deps): update docker.io/postgres:16.4-alpin\u001b[23;2H \u001b[23;4H \u001b[23;12H \u001b[23;30H \u001b[23;43H \u001b[23;50H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.269683, "o", "\u001b[2;2H* 91c5973\u001b[2;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m chore: release \u001b[3;2H \u001b[3;4H \u001b[3;12H \u001b[3;30H \u001b[3;37H \u001b[3;79H║\u001b[4;3H\u001b[38;5;15;48;5;1mkxio\u001b[4;8Hcommit is a Work-in-progress\u001b[4;37H\u001b[39;49m(main\u001b[4;43H->\u001b[4;46Hnext\u001b[4;51H->\u001b[4;54Hdev)\u001b[4;59H\u001b[38;5;1;49mALERT\u001b[4;65H\u001b[39;49m──────────────\u001b[5;2H* 805d0b3 \u001b[38;5;15;48;5;4m(dev)\u001b[39;49m WIP: docs(fs): add\u001b[5;37Hsome docum\u001b[5;48Hn\u001b[5;50Hation \u001b[5;59H \u001b[5;65H \u001b[6;4H9943a0f\u001b[6;13H\u001b[38;5;15;48;5;4mmain)(next)\u001b[39;49m \u001b[6;26Hhore(deps): update docker.\u001b[6;54H/rust\u001b[6;60Hdocker\u001b[6;67Htag\u001b[6;71Hto\u001b[6;74Hv1.81\u001b[7;2H \u001b[7;4H \u001b[7;12H \u001b[7;25H \u001b[7;38H \u001b[7;45H \u001b[7;60H \u001b[7;67H \u001b[7;71H \u001b[7;74H \u001b[8;3H\u001b[38;5;6;49mpodal\u001b[8;9H\u001b[39;49m(main\u001b[8;15H->\u001b[8;18Hnext\u001b[8;23H->\u001b[8;26Hdev)\u001b[8;31H\u001b[38;5;2;49mokay\u001b[8;36H\u001b[39;49m─────────────────────────────"]
|
||||||
|
[9.271446, "o", "──────────────\u001b[9;2H* 249b943 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m fix(deps): update rust crate scraper to 0.20 \u001b[10;2H \u001b[10;4H \u001b[10;12H \u001b[10;30H \u001b[10;41H \u001b[10;48H \u001b[10;53H \u001b[10;59H \u001b[10;67H \u001b[10;70H \u001b[11;3H\u001b[38;5;6;49mrefile-m4b\u001b[11;14H\u001b[39;49m(main\u001b[11;20H->\u001b[11;23Hnext\u001b[11;28H->\u001b[11;31Hdev)\u001b[11;36H\u001b[38;5;2;49mokay\u001b[11;41H\u001b[39;49m──────────────────────────────────────\u001b[12;2H* 7fba5fb \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m Support --version, --help and --directory cli arg\u001b[13;2H \u001b[13;4H \u001b[13;12H \u001b[13;30H \u001b[13;38H \u001b[13;49H \u001b[13;56H \u001b[13;60H \u001b[13;72H \u001b[13;76H \u001b[14;3H\u001b[38;5;6;49mrust-action\u001b[14;15H\u001b[39;49m(main\u001b[14;21H->\u001b[14;24Hnext\u001b[14;29H->\u001b[14;32Hdev)\u001b[14;37H\u001b[38;5;2;49mokay\u001b[14;42H\u001b[39;49m───────────────────────────────"]
|
||||||
|
[9.271582, "o", "──────\u001b[15;2H* de4785c \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m feat: ensure toolchains are up-to-date \u001b[16;2H \u001b[16;4H \u001b[16;12H \u001b[16;30H \u001b[16;36H \u001b[16;43H \u001b[16;54H \u001b[16;58H \u001b[17;3H\u001b[38;5;6;49mskip\u001b[17;8H\u001b[39;49m(main\u001b[17;14H->\u001b[17;17Hnext\u001b[17;22H->\u001b[17;25Hdev)\u001b[17;30H\u001b[38;5;2;49mokay\u001b[17;35H\u001b[39;49m────────────────────────────────────────────\u001b[18;2H* fc7fbc\u001b[18;11H \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[18;30H\u001b[39;49mchore(deps): update docker.io/rust docker tag to \u001b[19;2H \u001b[19;4H \u001b[19;12H \u001b[19;30H \u001b[19;43H \u001b[19;50H \u001b[19;65H \u001b[19;72H \u001b[19;76H \u001b[20;3H\u001b[38;5;6;49mtasyn\u001b[20;9H\u001b[39;49m(main\u001b[20;15H->\u001b[20;18Hnext\u001b[20;23H->\u001b[20;26Hdev)\u001b[20;31H\u001b[38;5;2;49mokay\u001b[20;36H\u001b[39;49m──────────────────────────────────────────"]
|
||||||
|
[9.271711, "o", "─\u001b[21;2H* 24fe845 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m chore(deps): update docker.io/postgres:16.4-alpin\u001b[22;2H \u001b[22;4H \u001b[22;12H \u001b[22;30H \u001b[22;43H \u001b[22;50H \u001b[23;3H\u001b[38;5;6;49mtest\u001b[23;8H\u001b[39;49m(main\u001b[23;14H->\u001b[23;17Hnext\u001b[23;22H->\u001b[23;25Hdev)\u001b[23;30H\u001b[38;5;2;49mokay\u001b[23;35H\u001b[39;49m────────────────────────────────────────────\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.291758, "o", "\u001b[2;2H \u001b[2;4H \u001b[2;12H \u001b[2;30H \u001b[2;37H \u001b[3;3H\u001b[38;5;15;48;5;1mkxio\u001b[3;8Hcommit is a Work-in-progress\u001b[3;37H\u001b[39;49m(main\u001b[3;43H->\u001b[3;46Hnext\u001b[3;51H->\u001b[3;54Hdev)\u001b[3;59H\u001b[38;5;1;49mALERT\u001b[3;65H\u001b[39;49m──────────────\u001b[4;2H* 805d0b3 \u001b[38;5;15;48;5;4m(dev)\u001b[39;49m WIP: docs(fs): add\u001b[4;37Hsome docum\u001b[4;48Hn\u001b[4;50Hation \u001b[4;59H \u001b[4;65H \u001b[5;4H9943a0f\u001b[5;13H\u001b[38;5;15;48;5;4mmain)(next)\u001b[39;49m \u001b[5;26Hhore(deps): update docker.\u001b[5;54H/rust\u001b[5;60Hdocker\u001b[5;67Htag\u001b[5;71Hto\u001b[5;74Hv1.81\u001b[6;2H \u001b[6;4H \u001b[6;12H \u001b[6;25H \u001b[6;38H \u001b[6;45H \u001b[6;60H \u001b[6;67H \u001b[6;71H \u001b[6;74H \u001b[7;3H\u001b[38;5;6;49mpodal\u001b[7;9H\u001b[39;49m(main\u001b[7;15H->\u001b[7;18Hnext\u001b[7;23H->\u001b[7;26Hdev)\u001b[7;31H\u001b[38;5;2;49mokay\u001b[7;36H\u001b[39;49m───────────────────────────────────────────\u001b[8;2H* 249b943 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m fix(deps): update rust "]
|
||||||
|
[9.292005, "o", "crate scraper to 0.20 \u001b[9;2H \u001b[9;4H \u001b[9;12H \u001b[9;30H \u001b[9;41H \u001b[9;48H \u001b[9;53H \u001b[9;59H \u001b[9;67H \u001b[9;70H \u001b[10;3H\u001b[38;5;6;49mrefile-m4b\u001b[10;14H\u001b[39;49m(main\u001b[10;20H->\u001b[10;23Hnext\u001b[10;28H->\u001b[10;31Hdev)\u001b[10;36H\u001b[38;5;2;49mokay\u001b[10;41H\u001b[39;49m──────────────────────────────────────\u001b[11;2H* 7fba5fb \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m Support --version, --help and --directory cli arg\u001b[12;2H \u001b[12;4H \u001b[12;12H \u001b[12;30H \u001b[12;38H \u001b[12;49H \u001b[12;56H \u001b[12;60H \u001b[12;72H \u001b[12;76H \u001b[13;3H\u001b[38;5;6;49mrust-action\u001b[13;15H\u001b[39;49m(main\u001b[13;21H->\u001b[13;24Hnext\u001b[13;29H->\u001b[13;32Hdev)\u001b[13;37H\u001b[38;5;2;49mokay\u001b[13;42H\u001b[39;49m─────────────────────────────────────\u001b[14;2H* de4785c \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m feat: ensure toolchains are up-to-date \u001b[15;2H \u001b"]
|
||||||
|
[9.292207, "o", "[15;4H \u001b[15;12H \u001b[15;30H \u001b[15;36H \u001b[15;43H \u001b[15;54H \u001b[15;58H \u001b[16;3H\u001b[38;5;6;49mskip\u001b[16;8H\u001b[39;49m(main\u001b[16;14H->\u001b[16;17Hnext\u001b[16;22H->\u001b[16;25Hdev)\u001b[16;30H\u001b[38;5;2;49mokay\u001b[16;35H\u001b[39;49m────────────────────────────────────────────\u001b[17;2H* fc7fbc\u001b[17;11H \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[17;30H\u001b[39;49mchore(deps): update docker.io/rust docker tag to \u001b[18;2H \u001b[18;4H \u001b[18;12H \u001b[18;30H \u001b[18;43H \u001b[18;50H \u001b[18;65H \u001b[18;72H \u001b[18;76H \u001b[19;3H\u001b[38;5;6;49mtasyn\u001b[19;9H\u001b[39;49m(main\u001b[19;15H->\u001b[19;18Hnext\u001b[19;23H->\u001b[19;26Hdev)\u001b[19;31H\u001b[38;5;2;49mokay\u001b[19;36H\u001b[39;49m───────────────────────────────────────────\u001b[20;2H* 24fe845 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m chore(deps): update docker.io/postgres:16.4-alpin\u001b[21;2H \u001b[21;4H \u001b[21"]
|
||||||
|
[9.292245, "o", ";12H \u001b[21;30H \u001b[21;43H \u001b[21;50H \u001b[22;3H\u001b[38;5;6;49mtest\u001b[22;8H\u001b[39;49m(main\u001b[22;14H->\u001b[22;17Hnext\u001b[22;22H->\u001b[22;25Hdev)\u001b[22;30H\u001b[38;5;2;49mokay\u001b[22;35H\u001b[39;49m────────────────────────────────────────────\u001b[23;2H* b7340df \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[23;30H\u001b[39;49mchore: update 6 \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.314279, "o", "\u001b[2;3H\u001b[38;5;15;48;5;1mkxio\u001b[2;8Hcommit is a Work-in-progress\u001b[2;37H\u001b[39;49m(main\u001b[2;43H->\u001b[2;46Hnext\u001b[2;51H->\u001b[2;54Hdev)\u001b[2;59H\u001b[38;5;1;49mALERT\u001b[2;65H\u001b[39;49m──────────────\u001b[3;2H* 805d0b3 \u001b[38;5;15;48;5;4m(dev)\u001b[39;49m WIP: docs(fs): add\u001b[3;37Hsome docum\u001b[3;48Hn\u001b[3;50Hation \u001b[3;59H \u001b[3;65H \u001b[4;4H9943a0f\u001b[4;13H\u001b[38;5;15;48;5;4mmain)(next)\u001b[39;49m \u001b[4;26Hhore(deps): update docker.\u001b[4;54H/rust\u001b[4;60Hdocker\u001b[4;67Htag\u001b[4;71Hto\u001b[4;74Hv1.81║\u001b[5;2H \u001b[5;4H \u001b[5;12H \u001b[5;25H \u001b[5;38H \u001b[5;45H \u001b[5;60H \u001b[5;67H \u001b[5;71H \u001b[5;74H \u001b[6;3H\u001b[38;5;6;49mpodal\u001b[6;9H\u001b[39;49m(main\u001b[6;15H->\u001b[6;18Hnext\u001b[6;23H->\u001b[6;26Hdev)\u001b[6;31H\u001b[38;5;2;49mokay\u001b[6;36H\u001b[39;49m───────────────────────────────────────────\u001b[7;2H* 249b943 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m fix(deps): update rust crate scraper to 0.20 \u001b[8;2H \u001b[8;4H \u001b[8;12H "]
|
||||||
|
[9.314894, "o", " \u001b[8;30H \u001b[8;41H \u001b[8;48H \u001b[8;53H \u001b[8;59H \u001b[8;67H \u001b[8;70H \u001b[9;3H\u001b[38;5;6;49mrefile-m4b\u001b[9;14H\u001b[39;49m(main\u001b[9;20H->\u001b[9;23Hnext\u001b[9;28H->\u001b[9;31Hdev)\u001b[9;36H\u001b[38;5;2;49mokay\u001b[9;41H\u001b[39;49m──────────────────────────────────────\u001b[10;2H* 7fba5fb \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m Support --version, --help and --directory cli arg\u001b[11;2H \u001b[11;4H \u001b[11;12H \u001b[11;30H \u001b[11;38H \u001b[11;49H \u001b[11;56H \u001b[11;60H \u001b[11;72H \u001b[11;76H \u001b[12;3H\u001b[38;5;6;49mrust-action\u001b[12;15H\u001b[39;49m(main\u001b[12;21H->\u001b[12;24Hnext\u001b[12;29H->\u001b[12;32Hdev)\u001b[12;37H\u001b[38;5;2;49mokay\u001b[12;42H\u001b[39;49m─────────────────────────────────────\u001b[13;2H* de4785c \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m feat: ensure toolchains are up-to-date █\u001b[14;2H \u001b[14;4H \u001b[14;12H \u001b[14;30H \u001b[14;36H \u001b[14;43H"]
|
||||||
|
[9.315054, "o", " \u001b[14;54H \u001b[14;58H \u001b[15;3H\u001b[38;5;6;49mskip\u001b[15;8H\u001b[39;49m(main\u001b[15;14H->\u001b[15;17Hnext\u001b[15;22H->\u001b[15;25Hdev)\u001b[15;30H\u001b[38;5;2;49mokay\u001b[15;35H\u001b[39;49m────────────────────────────────────────────\u001b[16;2H* fc7fbc\u001b[16;11H \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[16;30H\u001b[39;49mchore(deps): update docker.io/rust docker tag to \u001b[17;2H \u001b[17;4H \u001b[17;12H \u001b[17;30H \u001b[17;43H \u001b[17;50H \u001b[17;65H \u001b[17;72H \u001b[17;76H \u001b[18;3H\u001b[38;5;6;49mtasyn\u001b[18;9H\u001b[39;49m(main\u001b[18;15H->\u001b[18;18Hnext\u001b[18;23H->\u001b[18;26Hdev)\u001b[18;31H\u001b[38;5;2;49mokay\u001b[18;36H\u001b[39;49m───────────────────────────────────────────\u001b[19;2H* 24fe845 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m chore(deps): update docker.io/postgres:16.4-alpin\u001b[20;2H \u001b[20;4H \u001b[20;12H \u001b[20;30H \u001b[20;43H \u001b[20;50H "]
|
||||||
|
[9.315195, "o", " \u001b[21;3H\u001b[38;5;6;49mtest\u001b[21;8H\u001b[39;49m(main\u001b[21;14H->\u001b[21;17Hnext\u001b[21;22H->\u001b[21;25Hdev)\u001b[21;30H\u001b[38;5;2;49mokay\u001b[21;35H\u001b[39;49m────────────────────────────────────────────\u001b[22;2H* b7340df \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[22;30H\u001b[39;49mchore: update 6 \u001b[23;2H \u001b[23;4H \u001b[23;12H \u001b[23;30H \u001b[23;37H \u001b[23;44H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.334731, "o", "\u001b[2;2H* 805d0b3 \u001b[38;5;15;48;5;4m(dev)\u001b[39;49m WIP: docs(fs): add\u001b[2;37Hsome docum\u001b[2;48Hn\u001b[2;50Hation \u001b[2;59H \u001b[2;65H \u001b[3;4H9943a0f\u001b[3;13H\u001b[38;5;15;48;5;4mmain)(next)\u001b[39;49m \u001b[3;26Hhore(deps): update docker.\u001b[3;54H/rust\u001b[3;60Hdocker\u001b[3;67Htag\u001b[3;71Hto\u001b[3;74Hv1.81\u001b[4;2H \u001b[4;4H \u001b[4;12H \u001b[4;25H \u001b[4;38H \u001b[4;45H \u001b[4;60H \u001b[4;67H \u001b[4;71H \u001b[4;74H \u001b[5;3H\u001b[38;5;6;49mpodal\u001b[5;9H\u001b[39;49m(main\u001b[5;15H->\u001b[5;18Hnext\u001b[5;23H->\u001b[5;26Hdev)\u001b[5;31H\u001b[38;5;2;49mokay\u001b[5;36H\u001b[39;49m───────────────────────────────────────────\u001b[6;2H* 249b943 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m fix(deps): update rust crate scraper to 0.20 \u001b[7;2H \u001b[7;4H \u001b[7;12H \u001b[7;30H \u001b[7;41H \u001b[7;48H \u001b[7;53H \u001b[7;59H \u001b[7;67H \u001b[7;70H \u001b[8;3H\u001b[38;5;6;49mrefile-m4b\u001b[8;14H\u001b[39;49m(main\u001b[8;20H->\u001b[8;23Hnext\u001b[8;28H->\u001b[8;31Hdev)\u001b[8;36H\u001b[38;5;2;49mokay\u001b[8;4"]
|
||||||
|
[9.334863, "o", "1H\u001b[39;49m──────────────────────────────────────\u001b[9;2H* 7fba5fb \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m Support --version, --help and --directory cli arg\u001b[10;2H \u001b[10;4H \u001b[10;12H \u001b[10;30H \u001b[10;38H \u001b[10;49H \u001b[10;56H \u001b[10;60H \u001b[10;72H \u001b[10;76H \u001b[11;3H\u001b[38;5;6;49mrust-action\u001b[11;15H\u001b[39;49m(main\u001b[11;21H->\u001b[11;24Hnext\u001b[11;29H->\u001b[11;32Hdev)\u001b[11;37H\u001b[38;5;2;49mokay\u001b[11;42H\u001b[39;49m─────────────────────────────────────\u001b[12;2H* de4785c \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m feat: ensure toolchains are up-to-date \u001b[13;2H \u001b[13;4H \u001b[13;12H \u001b[13;30H \u001b[13;36H \u001b[13;43H \u001b[13;54H \u001b[13;58H \u001b[14;3H\u001b[38;5;6;49mskip\u001b[14;8H\u001b[39;49m(main\u001b[14;14H->\u001b[14;17Hnext\u001b[14;22H->\u001b[14;25Hdev)\u001b[14;30H\u001b[38;5;2;49mokay\u001b[14;35H\u001b[39;49m──────────────"]
|
||||||
|
[9.334916, "o", "──────────────────────────────\u001b[15;2H* fc7fbc\u001b[15;11H \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[15;30H\u001b[39;49mchore(deps): update docker.io/rust docker tag to \u001b[16;2H \u001b[16;4H \u001b[16;12H \u001b[16;30H \u001b[16;43H \u001b[16;50H \u001b[16;65H \u001b[16;72H \u001b[16;76H \u001b[17;3H\u001b[38;5;6;49mtasyn\u001b[17;9H\u001b[39;49m(main\u001b[17;15H->\u001b[17;18Hnext\u001b[17;23H->\u001b[17;26Hdev)\u001b[17;31H\u001b[38;5;2;49mokay\u001b[17;36H\u001b[39;49m───────────────────────────────────────────\u001b[18;2H* 24fe845 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m chore(deps): update docker.io/postgres:16.4-alpin\u001b[19;2H \u001b[19;4H \u001b[19;12H \u001b[19;30H \u001b[19;43H \u001b[19;50H \u001b[20;3H\u001b[38;5;6;49mtest\u001b[20;8H\u001b[39;49m(main\u001b[20;14H->\u001b[20;17Hnext\u001b[20;22H->\u001b[20;25Hdev)\u001b[20;30H\u001b[38;5;2;49mokay\u001b[20;35H\u001b[39;49m─────────────────────"]
|
||||||
|
[9.335083, "o", "───────────────────────\u001b[21;2H* b7340df \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[21;30H\u001b[39;49mchore: update 6 \u001b[22;2H \u001b[22;4H \u001b[22;12H \u001b[22;30H \u001b[22;37H \u001b[22;44H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.355977, "o", "\u001b[2;4H9943a0f\u001b[2;13H\u001b[38;5;15;48;5;4mmain)(next)\u001b[39;49m \u001b[2;26Hhore(deps): update docker.\u001b[2;54H/rust\u001b[2;60Hdocker\u001b[2;67Htag\u001b[2;71Hto\u001b[2;74Hv1.81\u001b[3;2H \u001b[3;4H \u001b[3;12H \u001b[3;25H \u001b[3;38H \u001b[3;45H \u001b[3;60H \u001b[3;67H \u001b[3;71H \u001b[3;74H \u001b[4;3H\u001b[38;5;6;49mpodal\u001b[4;9H\u001b[39;49m(main\u001b[4;15H->\u001b[4;18Hnext\u001b[4;23H->\u001b[4;26Hdev)\u001b[4;31H\u001b[38;5;2;49mokay\u001b[4;36H\u001b[39;49m───────────────────────────────────────────\u001b[5;2H* 249b943 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m fix(deps): update rust crate scraper to 0.20 ║\u001b[6;2H \u001b[6;4H \u001b[6;12H \u001b[6;30H \u001b[6;41H \u001b[6;48H \u001b[6;53H \u001b[6;59H \u001b[6;67H \u001b[6;70H \u001b[7;3H\u001b[38;5;6;49mrefile-m4b\u001b[7;14H\u001b[39;49m(main\u001b[7;20H->\u001b[7;23Hnext\u001b[7;28H->\u001b[7;31Hdev)\u001b[7;36H\u001b[38;5;2;49mokay\u001b[7;41H\u001b[39;49m──────────────────────────────────────\u001b[8;2H* 7fb"]
|
||||||
|
[9.357512, "o", "a5fb \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m Support --version, --help and --directory cli arg\u001b[9;2H \u001b[9;4H \u001b[9;12H \u001b[9;30H \u001b[9;38H \u001b[9;49H \u001b[9;56H \u001b[9;60H \u001b[9;72H \u001b[9;76H \u001b[10;3H\u001b[38;5;6;49mrust-action\u001b[10;15H\u001b[39;49m(main\u001b[10;21H->\u001b[10;24Hnext\u001b[10;29H->\u001b[10;32Hdev)\u001b[10;37H\u001b[38;5;2;49mokay\u001b[10;42H\u001b[39;49m─────────────────────────────────────\u001b[11;2H* de4785c \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m feat: ensure toolchains are up-to-date \u001b[12;2H \u001b[12;4H \u001b[12;12H \u001b[12;30H \u001b[12;36H \u001b[12;43H \u001b[12;54H \u001b[12;58H \u001b[13;3H\u001b[38;5;6;49mskip\u001b[13;8H\u001b[39;49m(main\u001b[13;14H->\u001b[13;17Hnext\u001b[13;22H->\u001b[13;25Hdev)\u001b[13;30H\u001b[38;5;2;49mokay\u001b[13;35H\u001b[39;49m────────────────────────────────────────────\u001b[14;2H* fc7fbc\u001b[14;11H \u001b[38;5;15;48;5;4m(dev)(main)(nex"]
|
||||||
|
[9.358399, "o", "t)\u001b[14;30H\u001b[39;49mchore(deps): update docker.io/rust docker tag to █\u001b[15;2H \u001b[15;4H \u001b[15;12H \u001b[15;30H \u001b[15;43H \u001b[15;50H \u001b[15;65H \u001b[15;72H \u001b[15;76H \u001b[16;3H\u001b[38;5;6;49mtasyn\u001b[16;9H\u001b[39;49m(main\u001b[16;15H->\u001b[16;18Hnext\u001b[16;23H->\u001b[16;26Hdev)\u001b[16;31H\u001b[38;5;2;49mokay\u001b[16;36H\u001b[39;49m───────────────────────────────────────────\u001b[17;2H* 24fe845 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m chore(deps): update docker.io/postgres:16.4-alpin\u001b[18;2H \u001b[18;4H \u001b[18;12H \u001b[18;30H \u001b[18;43H \u001b[18;50H \u001b[19;3H\u001b[38;5;6;49mtest\u001b[19;8H\u001b[39;49m(main\u001b[19;14H->\u001b[19;17Hnext\u001b[19;22H->\u001b[19;25Hdev)\u001b[19;30H\u001b[38;5;2;49mokay\u001b[19;35H\u001b[39;49m────────────────────────────────────────────\u001b[20;2H* b7340df \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[20;30H\u001b[39;49mchore:"]
|
||||||
|
[9.358584, "o", " update 6 \u001b[21;2H \u001b[21;4H \u001b[21;12H \u001b[21;30H \u001b[21;37H \u001b[21;44H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.392711, "o", "\u001b[2;2H \u001b[2;4H \u001b[2;12H \u001b[2;25H \u001b[2;38H \u001b[2;45H \u001b[2;60H \u001b[2;67H \u001b[2;71H \u001b[2;74H \u001b[3;3H\u001b[38;5;6;49mpodal\u001b[3;9H\u001b[39;49m(main\u001b[3;15H->\u001b[3;18Hnext\u001b[3;23H->\u001b[3;26Hdev)\u001b[3;31H\u001b[38;5;2;49mokay\u001b[3;36H\u001b[39;49m───────────────────────────────────────────\u001b[4;2H* 249b943 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m fix(deps): update rust crate scraper to 0.20 \u001b[5;2H \u001b[5;4H \u001b[5;12H \u001b[5;30H \u001b[5;41H \u001b[5;48H \u001b[5;53H \u001b[5;59H \u001b[5;67H \u001b[5;70H \u001b[6;3H\u001b[38;5;6;49mrefile-m4b\u001b[6;14H\u001b[39;49m(main\u001b[6;20H->\u001b[6;23Hnext\u001b[6;28H->\u001b[6;31Hdev)\u001b[6;36H\u001b[38;5;2;49mokay\u001b[6;41H\u001b[39;49m──────────────────────────────────────\u001b[7;2H* 7fba5fb \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m Support --version, --help and --directory cli arg\u001b[8;2H \u001b[8;4H \u001b[8;12H \u001b[8;30H "]
|
||||||
|
[9.392818, "o", " \u001b[8;38H \u001b[8;49H \u001b[8;56H \u001b[8;60H \u001b[8;72H \u001b[8;76H \u001b[9;3H\u001b[38;5;6;49mrust-action\u001b[9;15H\u001b[39;49m(main\u001b[9;21H->\u001b[9;24Hnext\u001b[9;29H->\u001b[9;32Hdev)\u001b[9;37H\u001b[38;5;2;49mokay\u001b[9;42H\u001b[39;49m─────────────────────────────────────\u001b[10;2H* de4785c \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m feat: ensure toolchains are up-to-date \u001b[11;2H \u001b[11;4H \u001b[11;12H \u001b[11;30H \u001b[11;36H \u001b[11;43H \u001b[11;54H \u001b[11;58H \u001b[12;3H\u001b[38;5;6;49mskip\u001b[12;8H\u001b[39;49m(main\u001b[12;14H->\u001b[12;17Hnext\u001b[12;22H->\u001b[12;25Hdev)\u001b[12;30H\u001b[38;5;2;49mokay\u001b[12;35H\u001b[39;49m────────────────────────────────────────────\u001b[13;2H* fc7fbc\u001b[13;11H \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[13;30H\u001b[39;49mchore(deps): update docker.io/rust docker tag to \u001b[14;2H \u001b[14;4H \u001b[14;12H \u001b[14;30H \u001b[14;43H \u001b[14;50H "]
|
||||||
|
[9.392892, "o", " \u001b[14;65H \u001b[14;72H \u001b[14;76H \u001b[15;3H\u001b[38;5;6;49mtasyn\u001b[15;9H\u001b[39;49m(main\u001b[15;15H->\u001b[15;18Hnext\u001b[15;23H->\u001b[15;26Hdev)\u001b[15;31H\u001b[38;5;2;49mokay\u001b[15;36H\u001b[39;49m───────────────────────────────────────────\u001b[16;2H* 24fe845 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m chore(deps): update docker.io/postgres:16.4-alpin\u001b[17;2H \u001b[17;4H \u001b[17;12H \u001b[17;30H \u001b[17;43H \u001b[17;50H \u001b[18;3H\u001b[38;5;6;49mtest\u001b[18;8H\u001b[39;49m(main\u001b[18;14H->\u001b[18;17Hnext\u001b[18;22H->\u001b[18;25Hdev)\u001b[18;30H\u001b[38;5;2;49mokay\u001b[18;35H\u001b[39;49m────────────────────────────────────────────\u001b[19;2H* b7340df \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[19;30H\u001b[39;49mchore: update 6 \u001b[20;2H \u001b[20;4H \u001b[20;12H \u001b[20;30H \u001b[20;37H \u001b[20;44H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.413689, "o", "\u001b[2;3H\u001b[38;5;6;49mpodal\u001b[2;9H\u001b[39;49m(main\u001b[2;15H->\u001b[2;18Hnext\u001b[2;23H->\u001b[2;26Hdev)\u001b[2;31H\u001b[38;5;2;49mokay\u001b[2;36H\u001b[39;49m───────────────────────────────────────────\u001b[3;2H* 249b943 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m fix(deps): update rust crate scraper to 0.20 \u001b[4;2H \u001b[4;4H \u001b[4;12H \u001b[4;30H \u001b[4;41H \u001b[4;48H \u001b[4;53H \u001b[4;59H \u001b[4;67H \u001b[4;70H \u001b[5;3H\u001b[38;5;6;49mrefile-m4b\u001b[5;14H\u001b[39;49m(main\u001b[5;20H->\u001b[5;23Hnext\u001b[5;28H->\u001b[5;31Hdev)\u001b[5;36H\u001b[38;5;2;49mokay\u001b[5;41H\u001b[39;49m──────────────────────────────────────\u001b[6;2H* 7fba5fb \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m Support --version, --help and --directory cli arg\u001b[7;2H \u001b[7;4H \u001b[7;12H \u001b[7;30H \u001b[7;38H \u001b[7;49H \u001b[7;56H \u001b[7;60H \u001b[7;72H \u001b[7;76H \u001b[8;3H\u001b[38;5;6;49mrust-action\u001b[8;15H\u001b[39;49m(main\u001b[8"]
|
||||||
|
[9.413775, "o", ";21H->\u001b[8;24Hnext\u001b[8;29H->\u001b[8;32Hdev)\u001b[8;37H\u001b[38;5;2;49mokay\u001b[8;42H\u001b[39;49m─────────────────────────────────────\u001b[9;2H* de4785c \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m feat: ensure toolchains are up-to-date \u001b[10;2H \u001b[10;4H \u001b[10;12H \u001b[10;30H \u001b[10;36H \u001b[10;43H \u001b[10;54H \u001b[10;58H \u001b[11;3H\u001b[38;5;6;49mskip\u001b[11;8H\u001b[39;49m(main\u001b[11;14H->\u001b[11;17Hnext\u001b[11;22H->\u001b[11;25Hdev)\u001b[11;30H\u001b[38;5;2;49mokay\u001b[11;35H\u001b[39;49m────────────────────────────────────────────\u001b[12;2H* fc7fbc\u001b[12;11H \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[12;30H\u001b[39;49mchore(deps): update docker.io/rust docker tag to \u001b[13;2H \u001b[13;4H \u001b[13;12H \u001b[13;30H \u001b[13;43H \u001b[13;50H \u001b[13;65H \u001b[13;72H \u001b[13;76H \u001b[14;3H\u001b[38;5;6;49mtasyn\u001b[14;9H\u001b[39;49m(main\u001b[14;15H->\u001b[14;18Hnext\u001b[14;23H->\u001b[14;26Hdev)\u001b"]
|
||||||
|
[9.413866, "o", "[14;31H\u001b[38;5;2;49mokay\u001b[14;36H\u001b[39;49m───────────────────────────────────────────\u001b[15;2H* 24fe845 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m chore(deps): update docker.io/postgres:16.4-alpin█\u001b[16;2H \u001b[16;4H \u001b[16;12H \u001b[16;30H \u001b[16;43H \u001b[16;50H \u001b[17;3H\u001b[38;5;6;49mtest\u001b[17;8H\u001b[39;49m(main\u001b[17;14H->\u001b[17;17Hnext\u001b[17;22H->\u001b[17;25Hdev)\u001b[17;30H\u001b[38;5;2;49mokay\u001b[17;35H\u001b[39;49m────────────────────────────────────────────\u001b[18;2H* b7340df \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[18;30H\u001b[39;49mchore: update 6 \u001b[19;2H \u001b[19;4H \u001b[19;12H \u001b[19;30H \u001b[19;37H \u001b[19;44H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.434833, "o", "\u001b[2;2H* 249b943 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m fix(deps): update rust crate scraper to 0.20 \u001b[3;2H \u001b[3;4H \u001b[3;12H \u001b[3;30H \u001b[3;41H \u001b[3;48H \u001b[3;53H \u001b[3;59H \u001b[3;67H \u001b[3;70H \u001b[4;3H\u001b[38;5;6;49mrefile-m4b\u001b[4;14H\u001b[39;49m(main\u001b[4;20H->\u001b[4;23Hnext\u001b[4;28H->\u001b[4;31Hdev)\u001b[4;36H\u001b[38;5;2;49mokay\u001b[4;41H\u001b[39;49m──────────────────────────────────────\u001b[5;2H* 7fba5fb \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m Support --version, --help and --directory cli arg\u001b[6;2H \u001b[6;4H \u001b[6;12H \u001b[6;30H \u001b[6;38H \u001b[6;49H \u001b[6;56H \u001b[6;60H \u001b[6;72H \u001b[6;76H ║\u001b[7;3H\u001b[38;5;6;49mrust-action\u001b[7;15H\u001b[39;49m(main\u001b[7;21H->\u001b[7;24Hnext\u001b[7;29H->\u001b[7;32Hdev)\u001b[7;37H\u001b[38;5;2;49mokay\u001b[7;42H\u001b[39;49m─────────────────────────────────────\u001b[8;2H* de4785c \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m f"]
|
||||||
|
[9.435142, "o", "eat: ensure toolchains are up-to-date \u001b[9;2H \u001b[9;4H \u001b[9;12H \u001b[9;30H \u001b[9;36H \u001b[9;43H \u001b[9;54H \u001b[9;58H \u001b[10;3H\u001b[38;5;6;49mskip\u001b[10;8H\u001b[39;49m(main\u001b[10;14H->\u001b[10;17Hnext\u001b[10;22H->\u001b[10;25Hdev)\u001b[10;30H\u001b[38;5;2;49mokay\u001b[10;35H\u001b[39;49m────────────────────────────────────────────\u001b[11;2H* fc7fbc\u001b[11;11H \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[11;30H\u001b[39;49mchore(deps): update docker.io/rust docker tag to \u001b[12;2H \u001b[12;4H \u001b[12;12H \u001b[12;30H \u001b[12;43H \u001b[12;50H \u001b[12;65H \u001b[12;72H \u001b[12;76H \u001b[13;3H\u001b[38;5;6;49mtasyn\u001b[13;9H\u001b[39;49m(main\u001b[13;15H->\u001b[13;18Hnext\u001b[13;23H->\u001b[13;26Hdev)\u001b[13;31H\u001b[38;5;2;49mokay\u001b[13;36H\u001b[39;49m───────────────────────────────────────────\u001b[14;2H* 24fe845 \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[39;49m chore(deps): update docker"]
|
||||||
|
[9.435248, "o", ".io/postgres:16.4-alpin\u001b[15;2H \u001b[15;4H \u001b[15;12H \u001b[15;30H \u001b[15;43H \u001b[15;50H \u001b[16;3H\u001b[38;5;6;49mtest\u001b[16;8H\u001b[39;49m(main\u001b[16;14H->\u001b[16;17Hnext\u001b[16;22H->\u001b[16;25Hdev)\u001b[16;30H\u001b[38;5;2;49mokay\u001b[16;35H\u001b[39;49m────────────────────────────────────────────\u001b[17;2H* b7340df \u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[17;30H\u001b[39;49mchore: update 6 \u001b[18;2H \u001b[18;4H \u001b[18;12H \u001b[18;30H \u001b[18;37H \u001b[18;44H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.472802, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.510706, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.547102, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.586478, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.621846, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.656939, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.694522, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.730343, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.768279, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.804285, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.844258, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.881454, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.920047, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.957121, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[9.995542, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.03548, "o", "\u001b[24;43H💚\u001b[24;45H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.072844, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.110417, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.146604, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.183643, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.223757, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.259221, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.298185, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.335671, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.377657, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.413226, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.449543, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.485979, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.530581, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.568398, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.588452, "o", "\u001b[2;2H \u001b[38;5;6;49mpodal\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ───────────────────────────────────────────\u001b[3;2H*\u001b[3;4H249b943\u001b[3;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[3;30H\u001b[39;49mfix(deps):\u001b[3;41Hupdate\u001b[3;48Hrust\u001b[3;53Hcrate\u001b[3;59Hscraper\u001b[3;67Hto\u001b[3;70H0.20\u001b[4;3H \u001b[4;14H \u001b[4;20H \u001b[4;23H \u001b[4;28H \u001b[4;31H \u001b[4;36H \u001b[4;41H \u001b[5;2H \u001b[38;5;6;49mrefile-m4b\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ──────────────────────────────────────\u001b[6;2H*\u001b[6;4H7fba5fb\u001b[6;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[6;30H\u001b[39;49mSupport\u001b[6;38H--version,\u001b[6;49H--help\u001b[6;56Hand\u001b[6;60H--directory\u001b[6;72Hcli\u001b[6;76Harg█\u001b[7;3H \u001b[7;15H \u001b[7;21H \u001b[7;24H \u001b[7;29H \u001b[7;32H \u001b[7;37H \u001b[7;42H \u001b[8;2H \u001b[38;5;6;49mrust-action\u001b[39;49m (main -> "]
|
||||||
|
[10.588626, "o", "next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ─────────────────────────────────────\u001b[9;2H*\u001b[9;4Hde4785c\u001b[9;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[9;30H\u001b[39;49mfeat:\u001b[9;36Hensure\u001b[9;43Htoolchains\u001b[9;54Hare\u001b[9;58Hup-to-date\u001b[10;3H \u001b[10;8H \u001b[10;14H \u001b[10;17H \u001b[10;22H \u001b[10;25H \u001b[10;30H \u001b[10;35H \u001b[11;2H \u001b[38;5;6;49mskip\u001b[39;49m (m\u001b[11;11Hin -> next -> dev)\u001b[11;30H\u001b[38;5;2;49mokay\u001b[39;49m ────────────────────────────────────────────\u001b[12;2H*\u001b[12;4Hfc7fbca\u001b[12;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[12;30H\u001b[39;49mchore(deps):\u001b[12;43Hupdate\u001b[12;50Hdocker.io/rust\u001b[12;65Hdocker\u001b[12;72Htag\u001b[12;76Hto\u001b[13;3H \u001b[13;9H \u001b[13;15H \u001b[13;18H \u001b[13;23H \u001b[13;26H \u001b[13;31H \u001b[13;36H \u001b[14;2H \u001b[38;5;6;49mtasyn\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ─"]
|
||||||
|
[10.588685, "o", "──────────────────────────────────────────\u001b[15;2H*\u001b[15;4H24fe845\u001b[15;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[15;30H\u001b[39;49mchore(deps):\u001b[15;43Hupdate\u001b[15;50Hdocker.io/postgres:16.4-alpin\u001b[16;3H \u001b[16;8H \u001b[16;14H \u001b[16;17H \u001b[16;22H \u001b[16;25H \u001b[16;30H \u001b[16;35H \u001b[17;2H \u001b[38;5;6;49mtest\u001b[39;49m (main -> next -> dev)\u001b[17;30H\u001b[38;5;2;49mokay\u001b[39;49m ────────────────────────────────────────────\u001b[18;2H*\u001b[18;4Hb7340df\u001b[18;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[18;30H\u001b[39;49mchore:\u001b[18;37Hupdate\u001b[18;44H6\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.607079, "o", "\u001b[2;3H \u001b[2;9H \u001b[2;15H \u001b[2;18H \u001b[2;23H \u001b[2;26H \u001b[2;31H \u001b[2;36H \u001b[3;2H \u001b[38;5;6;49mpodal\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ───────────────────────────────────────────\u001b[4;2H*\u001b[4;4H249b943\u001b[4;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[4;30H\u001b[39;49mfix(deps):\u001b[4;41Hupdate\u001b[4;48Hrust\u001b[4;53Hcrate\u001b[4;59Hscraper\u001b[4;67Hto\u001b[4;70H0.20\u001b[5;3H \u001b[5;14H \u001b[5;20H \u001b[5;23H \u001b[5;28H \u001b[5;31H \u001b[5;36H \u001b[5;41H \u001b[6;2H \u001b[38;5;6;49mrefile-m4b\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ──────────────────────────────────────\u001b[7;2H*\u001b[7;4H7fba5fb\u001b[7;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[7;30H\u001b[39;49mSupport\u001b[7;38H--version,\u001b[7;49H--help\u001b[7;56Hand\u001b[7;60H--directory\u001b[7;72Hcli\u001b[7;76Harg\u001b[8;3H \u001b[8;15H \u001b[8;21H \u001b[8;24H \u001b[8"]
|
||||||
|
[10.607191, "o", ";29H \u001b[8;32H \u001b[8;37H \u001b[8;42H \u001b[9;2H \u001b[38;5;6;49mrust-action\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ─────────────────────────────────────\u001b[10;2H*\u001b[10;4Hde4785c\u001b[10;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[10;30H\u001b[39;49mfeat:\u001b[10;36Hensure\u001b[10;43Htoolchains\u001b[10;54Hare\u001b[10;58Hup-to-date\u001b[11;3H \u001b[11;8H \u001b[11;14H \u001b[11;17H \u001b[11;22H \u001b[11;25H \u001b[11;30H \u001b[11;35H \u001b[12;2H \u001b[38;5;6;49mskip\u001b[39;49m (m\u001b[12;11Hin -> next -> dev)\u001b[12;30H\u001b[38;5;2;49mokay\u001b[39;49m ────────────────────────────────────────────\u001b[13;2H*\u001b[13;4Hfc7fbca\u001b[13;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[13;30H\u001b[39;49mchore(deps):\u001b[13;43Hupdate\u001b[13;50Hdocker.io/rust\u001b[13;65Hdocker\u001b[13;72Htag\u001b[13;76Hto\u001b[14;3H \u001b[14;9H \u001b[14;15H \u001b[14;18H \u001b[14;23H \u001b[14;26H \u001b[14;31H \u001b[14;36H "]
|
||||||
|
[10.607383, "o", " \u001b[15;2H \u001b[38;5;6;49mtasyn\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ───────────────────────────────────────────║\u001b[16;2H*\u001b[16;4H24fe845\u001b[16;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[16;30H\u001b[39;49mchore(deps):\u001b[16;43Hupdate\u001b[16;50Hdocker.io/postgres:16.4-alpin\u001b[17;3H \u001b[17;8H \u001b[17;14H \u001b[17;17H \u001b[17;22H \u001b[17;25H \u001b[17;30H \u001b[17;35H \u001b[18;2H \u001b[38;5;6;49mtest\u001b[39;49m (main -> next -> dev)\u001b[18;30H\u001b[38;5;2;49mokay\u001b[39;49m ────────────────────────────────────────────\u001b[19;2H*\u001b[19;4Hb7340df\u001b[19;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[19;30H\u001b[39;49mchore:\u001b[19;37Hupdate\u001b[19;44H6\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.625804, "o", "\u001b[2;2H*\u001b[2;4H9943a0f\u001b[2;12H\u001b[38;5;15;48;5;4m(main)(next)\u001b[2;25H\u001b[39;49mchore(deps):\u001b[2;38Hupdate\u001b[2;45Hdocker.io/rust\u001b[2;60Hdocker\u001b[2;67Htag\u001b[2;71Hto\u001b[2;74Hv1.81\u001b[3;3H \u001b[3;9H \u001b[3;15H \u001b[3;18H \u001b[3;23H \u001b[3;26H \u001b[3;31H \u001b[3;36H \u001b[4;2H \u001b[38;5;6;49mpodal\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ───────────────────────────────────────────\u001b[5;2H*\u001b[5;4H249b943\u001b[5;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[5;30H\u001b[39;49mfix(deps):\u001b[5;41Hupdate\u001b[5;48Hrust\u001b[5;53Hcrate\u001b[5;59Hscraper\u001b[5;67Hto\u001b[5;70H0.20\u001b[6;3H \u001b[6;14H \u001b[6;20H \u001b[6;23H \u001b[6;28H \u001b[6;31H \u001b[6;36H \u001b[6;41H \u001b[7;2H \u001b[38;5;6;49mrefile-m4b\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ──────────────────────────────────────\u001b[8;2H*\u001b[8;4H7fba5fb\u001b[8;12H\u001b[38;5;15;48;5;4m(dev)(ma"]
|
||||||
|
[10.625948, "o", "in)(next)\u001b[8;30H\u001b[39;49mSupport\u001b[8;38H--version,\u001b[8;49H--help\u001b[8;56Hand\u001b[8;60H--directory\u001b[8;72Hcli\u001b[8;76Harg\u001b[9;3H \u001b[9;15H \u001b[9;21H \u001b[9;24H \u001b[9;29H \u001b[9;32H \u001b[9;37H \u001b[9;42H \u001b[10;2H \u001b[38;5;6;49mrust-action\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ─────────────────────────────────────\u001b[11;2H*\u001b[11;4Hde4785c\u001b[11;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[11;30H\u001b[39;49mfeat:\u001b[11;36Hensure\u001b[11;43Htoolchains\u001b[11;54Hare\u001b[11;58Hup-to-date\u001b[12;3H \u001b[12;8H \u001b[12;14H \u001b[12;17H \u001b[12;22H \u001b[12;25H \u001b[12;30H \u001b[12;35H \u001b[13;2H \u001b[38;5;6;49mskip\u001b[39;49m (m\u001b[13;11Hin -> next -> dev)\u001b[13;30H\u001b[38;5;2;49mokay\u001b[39;49m ────────────────────────────────────────────\u001b[14;2H*\u001b[14;4Hfc7fbca\u001b[14;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[14;30H\u001b[39;49mchore(deps"]
|
||||||
|
[10.626011, "o", "):\u001b[14;43Hupdate\u001b[14;50Hdocker.io/rust\u001b[14;65Hdocker\u001b[14;72Htag\u001b[14;76Hto\u001b[15;3H \u001b[15;9H \u001b[15;15H \u001b[15;18H \u001b[15;23H \u001b[15;26H \u001b[15;31H \u001b[15;36H \u001b[16;2H \u001b[38;5;6;49mtasyn\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ───────────────────────────────────────────\u001b[17;2H*\u001b[17;4H24fe845\u001b[17;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[17;30H\u001b[39;49mchore(deps):\u001b[17;43Hupdate\u001b[17;50Hdocker.io/postgres:16.4-alpin\u001b[18;3H \u001b[18;8H \u001b[18;14H \u001b[18;17H \u001b[18;22H \u001b[18;25H \u001b[18;30H \u001b[18;35H \u001b[19;2H \u001b[38;5;6;49mtest\u001b[39;49m (main -> next -> dev)\u001b[19;30H\u001b[38;5;2;49mokay\u001b[39;49m ────────────────────────────────────────────\u001b[20;2H*\u001b[20;4Hb7340df\u001b[20;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[20;30H\u001b[39;49mchore:\u001b[20;37Hupdate\u001b[20;44H6\u001b[39m\u001b[4"]
|
||||||
|
[10.626024, "o", "9m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.644844, "o", "\u001b[2;4H805d0b3\u001b[2;13H\u001b[38;5;15;48;5;4mdev)\u001b[39;49m WIP: do\u001b[2;26Hs(fs): add some documentat\u001b[2;54Hn \u001b[2;60H \u001b[2;67H \u001b[2;71H \u001b[2;74H \u001b[3;2H*\u001b[3;4H9943a0f\u001b[3;12H\u001b[38;5;15;48;5;4m(main)(next)\u001b[3;25H\u001b[39;49mchore(deps):\u001b[3;38Hupdate\u001b[3;45Hdocker.io/rust\u001b[3;60Hdocker\u001b[3;67Htag\u001b[3;71Hto\u001b[3;74Hv1.81\u001b[4;3H \u001b[4;9H \u001b[4;15H \u001b[4;18H \u001b[4;23H \u001b[4;26H \u001b[4;31H \u001b[4;36H \u001b[5;2H \u001b[38;5;6;49mpodal\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ───────────────────────────────────────────█\u001b[6;2H*\u001b[6;4H249b943\u001b[6;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[6;30H\u001b[39;49mfix(deps):\u001b[6;41Hupdate\u001b[6;48Hrust\u001b[6;53Hcrate\u001b[6;59Hscraper\u001b[6;67Hto\u001b[6;70H0.20\u001b[7;3H \u001b[7;14H \u001b[7;20H \u001b[7;23H \u001b[7;28H \u001b[7;31H \u001b[7;36H \u001b[7;41H \u001b[8;2H \u001b[38;5;6;49mrefile-m4b\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ─────"]
|
||||||
|
[10.644992, "o", "─────────────────────────────────\u001b[9;2H*\u001b[9;4H7fba5fb\u001b[9;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[9;30H\u001b[39;49mSupport\u001b[9;38H--version,\u001b[9;49H--help\u001b[9;56Hand\u001b[9;60H--directory\u001b[9;72Hcli\u001b[9;76Harg\u001b[10;3H \u001b[10;15H \u001b[10;21H \u001b[10;24H \u001b[10;29H \u001b[10;32H \u001b[10;37H \u001b[10;42H \u001b[11;2H \u001b[38;5;6;49mrust-action\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ─────────────────────────────────────\u001b[12;2H*\u001b[12;4Hde4785c\u001b[12;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[12;30H\u001b[39;49mfeat:\u001b[12;36Hensure\u001b[12;43Htoolchains\u001b[12;54Hare\u001b[12;58Hup-to-date\u001b[13;3H \u001b[13;8H \u001b[13;14H \u001b[13;17H \u001b[13;22H \u001b[13;25H \u001b[13;30H \u001b[13;35H \u001b[14;2H \u001b[38;5;6;49mskip\u001b[39;49m (m\u001b[14;11Hin -> next -> dev)\u001b[14;30H\u001b[38;5;2;49mokay\u001b[39;49m ─────────────────────"]
|
||||||
|
[10.645137, "o", "───────────────────────║\u001b[15;2H*\u001b[15;4Hfc7fbca\u001b[15;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[15;30H\u001b[39;49mchore(deps):\u001b[15;43Hupdate\u001b[15;50Hdocker.io/rust\u001b[15;65Hdocker\u001b[15;72Htag\u001b[15;76Hto\u001b[16;3H \u001b[16;9H \u001b[16;15H \u001b[16;18H \u001b[16;23H \u001b[16;26H \u001b[16;31H \u001b[16;36H \u001b[17;2H \u001b[38;5;6;49mtasyn\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ───────────────────────────────────────────\u001b[18;2H*\u001b[18;4H24fe845\u001b[18;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[18;30H\u001b[39;49mchore(deps):\u001b[18;43Hupdate\u001b[18;50Hdocker.io/postgres:16.4-alpin\u001b[19;3H \u001b[19;8H \u001b[19;14H \u001b[19;17H \u001b[19;22H \u001b[19;25H \u001b[19;30H \u001b[19;35H \u001b[20;2H \u001b[38;5;6;49mtest\u001b[39;49m (main -> next -> dev)\u001b[20;30H\u001b[38;5;2;49mokay\u001b[39;49m ─────────────────────────────"]
|
||||||
|
[10.645277, "o", "───────────────\u001b[21;2H*\u001b[21;4Hb7340df\u001b[21;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[21;30H\u001b[39;49mchore:\u001b[21;37Hupdate\u001b[21;44H6\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.663505, "o", "\u001b[2;2H \u001b[38;5;15;48;5;1mkxio\u001b[39;49m \u001b[38;5;15;48;5;1mcommit is a Work-in-progress\u001b[2;37H\u001b[39;49m(main -> n\u001b[2;48Hx\u001b[2;50H -> dev)\u001b[2;59H\u001b[38;5;1;49mALERT\u001b[2;65H\u001b[39;49m──────────────\u001b[3;4H805d0b3\u001b[3;13H\u001b[38;5;15;48;5;4mdev)\u001b[39;49m WIP: do\u001b[3;26Hs(fs): add some documentat\u001b[3;54Hn \u001b[3;60H \u001b[3;67H \u001b[3;71H \u001b[3;74H \u001b[4;2H*\u001b[4;4H9943a0f\u001b[4;12H\u001b[38;5;15;48;5;4m(main)(next)\u001b[4;25H\u001b[39;49mchore(deps):\u001b[4;38Hupdate\u001b[4;45Hdocker.io/rust\u001b[4;60Hdocker\u001b[4;67Htag\u001b[4;71Hto\u001b[4;74Hv1.81\u001b[5;3H \u001b[5;9H \u001b[5;15H \u001b[5;18H \u001b[5;23H \u001b[5;26H \u001b[5;31H \u001b[5;36H \u001b[6;2H \u001b[38;5;6;49mpodal\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ───────────────────────────────────────────\u001b[7;2H*\u001b[7;4H249b943\u001b[7;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[7;30H\u001b[39;49mfix(deps):\u001b[7;41Hupdate\u001b[7;48Hrust\u001b[7;53Hcrate\u001b[7;59Hscraper\u001b[7;67Hto\u001b[7;70H0.20\u001b[8;3H \u001b["]
|
||||||
|
[10.663582, "o", "8;14H \u001b[8;20H \u001b[8;23H \u001b[8;28H \u001b[8;31H \u001b[8;36H \u001b[8;41H \u001b[9;2H \u001b[38;5;6;49mrefile-m4b\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ──────────────────────────────────────\u001b[10;2H*\u001b[10;4H7fba5fb\u001b[10;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[10;30H\u001b[39;49mSupport\u001b[10;38H--version,\u001b[10;49H--help\u001b[10;56Hand\u001b[10;60H--directory\u001b[10;72Hcli\u001b[10;76Harg\u001b[11;3H \u001b[11;15H \u001b[11;21H \u001b[11;24H \u001b[11;29H \u001b[11;32H \u001b[11;37H \u001b[11;42H \u001b[12;2H \u001b[38;5;6;49mrust-action\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ─────────────────────────────────────\u001b[13;2H*\u001b[13;4Hde4785c\u001b[13;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[13;30H\u001b[39;49mfeat:\u001b[13;36Hensure\u001b[13;43Htoolchains\u001b[13;54Hare\u001b[13;58Hup-to-date\u001b[14;3H \u001b[14;8H \u001b[14;14H \u001b[14;17H \u001b[14;22H \u001b[14;25H \u001b[14;"]
|
||||||
|
[10.663631, "o", "30H \u001b[14;35H \u001b[15;2H \u001b[38;5;6;49mskip\u001b[39;49m (m\u001b[15;11Hin -> next -> dev)\u001b[15;30H\u001b[38;5;2;49mokay\u001b[39;49m ────────────────────────────────────────────\u001b[16;2H*\u001b[16;4Hfc7fbca\u001b[16;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[16;30H\u001b[39;49mchore(deps):\u001b[16;43Hupdate\u001b[16;50Hdocker.io/rust\u001b[16;65Hdocker\u001b[16;72Htag\u001b[16;76Hto\u001b[17;3H \u001b[17;9H \u001b[17;15H \u001b[17;18H \u001b[17;23H \u001b[17;26H \u001b[17;31H \u001b[17;36H \u001b[18;2H \u001b[38;5;6;49mtasyn\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ───────────────────────────────────────────\u001b[19;2H*\u001b[19;4H24fe845\u001b[19;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[19;30H\u001b[39;49mchore(deps):\u001b[19;43Hupdate\u001b[19;50Hdocker.io/postgres:16.4-alpin\u001b[20;3H \u001b[20;8H \u001b[20;14H \u001b[20;17H \u001b[20;22H \u001b[20;25H \u001b[20;30H \u001b[20;35H "]
|
||||||
|
[10.663766, "o", " \u001b[21;2H \u001b[38;5;6;49mtest\u001b[39;49m (main -> next -> dev)\u001b[21;30H\u001b[38;5;2;49mokay\u001b[39;49m ────────────────────────────────────────────\u001b[22;2H*\u001b[22;4Hb7340df\u001b[22;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[22;30H\u001b[39;49mchore:\u001b[22;37Hupdate\u001b[22;44H6\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.682703, "o", "\u001b[2;3H \u001b[2;8H \u001b[2;37H \u001b[2;43H \u001b[2;46H \u001b[2;51H \u001b[2;54H \u001b[2;59H \u001b[2;65H \u001b[3;2H \u001b[38;5;15;48;5;1mkxio\u001b[39;49m \u001b[38;5;15;48;5;1mcommit is a Work-in-progress\u001b[3;37H\u001b[39;49m(main -> n\u001b[3;48Hx\u001b[3;50H -> dev)\u001b[3;59H\u001b[38;5;1;49mALERT\u001b[3;65H\u001b[39;49m──────────────\u001b[4;4H805d0b3\u001b[4;13H\u001b[38;5;15;48;5;4mdev)\u001b[39;49m WIP: do\u001b[4;26Hs(fs): add some documentat\u001b[4;54Hn \u001b[4;60H \u001b[4;67H \u001b[4;71H \u001b[4;74H █\u001b[5;2H*\u001b[5;4H9943a0f\u001b[5;12H\u001b[38;5;15;48;5;4m(main)(next)\u001b[5;25H\u001b[39;49mchore(deps):\u001b[5;38Hupdate\u001b[5;45Hdocker.io/rust\u001b[5;60Hdocker\u001b[5;67Htag\u001b[5;71Hto\u001b[5;74Hv1.81\u001b[6;3H \u001b[6;9H \u001b[6;15H \u001b[6;18H \u001b[6;23H \u001b[6;26H \u001b[6;31H \u001b[6;36H \u001b[7;2H \u001b[38;5;6;49mpodal\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ───────────────────────────────────────────\u001b[8;2H*\u001b[8;4H249b943\u001b[8;12H\u001b[38;5;15;48;5;"]
|
||||||
|
[10.682851, "o", "4m(dev)(main)(next)\u001b[8;30H\u001b[39;49mfix(deps):\u001b[8;41Hupdate\u001b[8;48Hrust\u001b[8;53Hcrate\u001b[8;59Hscraper\u001b[8;67Hto\u001b[8;70H0.20\u001b[9;3H \u001b[9;14H \u001b[9;20H \u001b[9;23H \u001b[9;28H \u001b[9;31H \u001b[9;36H \u001b[9;41H \u001b[10;2H \u001b[38;5;6;49mrefile-m4b\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ──────────────────────────────────────\u001b[11;2H*\u001b[11;4H7fba5fb\u001b[11;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[11;30H\u001b[39;49mSupport\u001b[11;38H--version,\u001b[11;49H--help\u001b[11;56Hand\u001b[11;60H--directory\u001b[11;72Hcli\u001b[11;76Harg\u001b[12;3H \u001b[12;15H \u001b[12;21H \u001b[12;24H \u001b[12;29H \u001b[12;32H \u001b[12;37H \u001b[12;42H \u001b[13;2H \u001b[38;5;6;49mrust-action\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ─────────────────────────────────────║\u001b[14;2H*\u001b[14;4Hde4785c\u001b[14;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[14;30H\u001b[39;49m"]
|
||||||
|
[10.683246, "o", "feat:\u001b[14;36Hensure\u001b[14;43Htoolchains\u001b[14;54Hare\u001b[14;58Hup-to-date\u001b[15;3H \u001b[15;8H \u001b[15;14H \u001b[15;17H \u001b[15;22H \u001b[15;25H \u001b[15;30H \u001b[15;35H \u001b[16;2H \u001b[38;5;6;49mskip\u001b[39;49m (m\u001b[16;11Hin -> next -> dev)\u001b[16;30H\u001b[38;5;2;49mokay\u001b[39;49m ────────────────────────────────────────────\u001b[17;2H*\u001b[17;4Hfc7fbca\u001b[17;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[17;30H\u001b[39;49mchore(deps):\u001b[17;43Hupdate\u001b[17;50Hdocker.io/rust\u001b[17;65Hdocker\u001b[17;72Htag\u001b[17;76Hto\u001b[18;3H \u001b[18;9H \u001b[18;15H \u001b[18;18H \u001b[18;23H \u001b[18;26H \u001b[18;31H \u001b[18;36H \u001b[19;2H \u001b[38;5;6;49mtasyn\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ───────────────────────────────────────────\u001b[20;2H*\u001b[20;4H24fe845\u001b[20;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[20;30H\u001b[39;49mchore(deps):\u001b[20;"]
|
||||||
|
[10.683342, "o", "43Hupdate\u001b[20;50Hdocker.io/postgres:16.4-alpin\u001b[21;3H \u001b[21;8H \u001b[21;14H \u001b[21;17H \u001b[21;22H \u001b[21;25H \u001b[21;30H \u001b[21;35H \u001b[22;2H \u001b[38;5;6;49mtest\u001b[39;49m (main -> next -> dev)\u001b[22;30H\u001b[38;5;2;49mokay\u001b[39;49m ────────────────────────────────────────────\u001b[23;2H*\u001b[23;4Hb7340df\u001b[23;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[23;30H\u001b[39;49mchore:\u001b[23;37Hupdate\u001b[23;44H6\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.702671, "o", "\u001b[2;2H*\u001b[2;4H91c5973\u001b[2;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[2;30H\u001b[39;49mchore:\u001b[2;37Hrelease\u001b[3;3H \u001b[3;8H \u001b[3;37H \u001b[3;43H \u001b[3;46H \u001b[3;51H \u001b[3;54H \u001b[3;59H \u001b[3;65H \u001b[4;2H \u001b[38;5;15;48;5;1mkxio\u001b[39;49m \u001b[38;5;15;48;5;1mcommit is a Work-in-progress\u001b[4;37H\u001b[39;49m(main -> n\u001b[4;48Hx\u001b[4;50H -> dev)\u001b[4;59H\u001b[38;5;1;49mALERT\u001b[4;65H\u001b[39;49m──────────────\u001b[5;4H805d0b3\u001b[5;13H\u001b[38;5;15;48;5;4mdev)\u001b[39;49m WIP: do\u001b[5;26Hs(fs): add some documentat\u001b[5;54Hn \u001b[5;60H \u001b[5;67H \u001b[5;71H \u001b[5;74H \u001b[6;2H*\u001b[6;4H9943a0f\u001b[6;12H\u001b[38;5;15;48;5;4m(main)(next)\u001b[6;25H\u001b[39;49mchore(deps):\u001b[6;38Hupdate\u001b[6;45Hdocker.io/rust\u001b[6;60Hdocker\u001b[6;67Htag\u001b[6;71Hto\u001b[6;74Hv1.81\u001b[7;3H \u001b[7;9H \u001b[7;15H \u001b[7;18H \u001b[7;23H \u001b[7;26H \u001b[7;31H \u001b[7;36H \u001b[8;2H \u001b[38;5;6;49mpodal\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ──────────────────────────"]
|
||||||
|
[10.703019, "o", "─────────────────\u001b[9;2H*\u001b[9;4H249b943\u001b[9;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[9;30H\u001b[39;49mfix(deps):\u001b[9;41Hupdate\u001b[9;48Hrust\u001b[9;53Hcrate\u001b[9;59Hscraper\u001b[9;67Hto\u001b[9;70H0.20\u001b[10;3H \u001b[10;14H \u001b[10;20H \u001b[10;23H \u001b[10;28H \u001b[10;31H \u001b[10;36H \u001b[10;41H \u001b[11;2H \u001b[38;5;6;49mrefile-m4b\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ──────────────────────────────────────\u001b[12;2H*\u001b[12;4H7fba5fb\u001b[12;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[12;30H\u001b[39;49mSupport\u001b[12;38H--version,\u001b[12;49H--help\u001b[12;56Hand\u001b[12;60H--directory\u001b[12;72Hcli\u001b[12;76Harg\u001b[13;3H \u001b[13;15H \u001b[13;21H \u001b[13;24H \u001b[13;29H \u001b[13;32H \u001b[13;37H \u001b[13;42H \u001b[14;2H \u001b[38;5;6;49mrust-action\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ───────────────────────────────"]
|
||||||
|
[10.703551, "o", "──────\u001b[15;2H*\u001b[15;4Hde4785c\u001b[15;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[15;30H\u001b[39;49mfeat:\u001b[15;36Hensure\u001b[15;43Htoolchains\u001b[15;54Hare\u001b[15;58Hup-to-date\u001b[16;3H \u001b[16;8H \u001b[16;14H \u001b[16;17H \u001b[16;22H \u001b[16;25H \u001b[16;30H \u001b[16;35H \u001b[17;2H \u001b[38;5;6;49mskip\u001b[39;49m (m\u001b[17;11Hin -> next -> dev)\u001b[17;30H\u001b[38;5;2;49mokay\u001b[39;49m ────────────────────────────────────────────\u001b[18;2H*\u001b[18;4Hfc7fbca\u001b[18;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[18;30H\u001b[39;49mchore(deps):\u001b[18;43Hupdate\u001b[18;50Hdocker.io/rust\u001b[18;65Hdocker\u001b[18;72Htag\u001b[18;76Hto\u001b[19;3H \u001b[19;9H \u001b[19;15H \u001b[19;18H \u001b[19;23H \u001b[19;26H \u001b[19;31H \u001b[19;36H \u001b[20;2H \u001b[38;5;6;49mtasyn\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ──────────────────────────────────────────"]
|
||||||
|
[10.703743, "o", "─\u001b[21;2H*\u001b[21;4H24fe845\u001b[21;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[21;30H\u001b[39;49mchore(deps):\u001b[21;43Hupdate\u001b[21;50Hdocker.io/postgres:16.4-alpin\u001b[22;3H \u001b[22;8H \u001b[22;14H \u001b[22;17H \u001b[22;22H \u001b[22;25H \u001b[22;30H \u001b[22;35H \u001b[23;2H \u001b[38;5;6;49mtest\u001b[39;49m (main -> next -> dev)\u001b[23;30H\u001b[38;5;2;49mokay\u001b[39;49m ────────────────────────────────────────────\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.72275, "o", "\u001b[2;2H \u001b[38;5;6;49mgit-next\u001b[2;12H\u001b[39;49m(main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ────────────────────────────────────────\u001b[3;2H*\u001b[3;4H91c5973\u001b[3;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[3;30H\u001b[39;49mchore:\u001b[3;37Hrelease\u001b[3;79H█\u001b[4;3H \u001b[4;8H \u001b[4;37H \u001b[4;43H \u001b[4;46H \u001b[4;51H \u001b[4;54H \u001b[4;59H \u001b[4;65H \u001b[5;2H \u001b[38;5;15;48;5;1mkxio\u001b[39;49m \u001b[38;5;15;48;5;1mcommit is a Work-in-progress\u001b[5;37H\u001b[39;49m(main -> n\u001b[5;48Hx\u001b[5;50H -> dev)\u001b[5;59H\u001b[38;5;1;49mALERT\u001b[5;65H\u001b[39;49m──────────────\u001b[6;4H805d0b3\u001b[6;13H\u001b[38;5;15;48;5;4mdev)\u001b[39;49m WIP: do\u001b[6;26Hs(fs): add some documentat\u001b[6;54Hn \u001b[6;60H \u001b[6;67H \u001b[6;71H \u001b[6;74H \u001b[7;2H*\u001b[7;4H9943a0f\u001b[7;12H\u001b[38;5;15;48;5;4m(main)(next)\u001b[7;25H\u001b[39;49mchore(deps):\u001b[7;38Hupdate\u001b[7;45Hdocker.io/rust\u001b[7;60Hdocker\u001b[7;67Htag\u001b[7;71Hto\u001b[7;74Hv1.81\u001b[8;3H \u001b[8;9H \u001b[8;15H \u001b[8;18H \u001b[8;23H \u001b[8;26H "]
|
||||||
|
[10.7228, "o", "\u001b[8;31H \u001b[8;36H \u001b[9;2H \u001b[38;5;6;49mpodal\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ───────────────────────────────────────────\u001b[10;2H*\u001b[10;4H249b943\u001b[10;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[10;30H\u001b[39;49mfix(deps):\u001b[10;41Hupdate\u001b[10;48Hrust\u001b[10;53Hcrate\u001b[10;59Hscraper\u001b[10;67Hto\u001b[10;70H0.20\u001b[11;3H \u001b[11;14H \u001b[11;20H \u001b[11;23H \u001b[11;28H \u001b[11;31H \u001b[11;36H \u001b[11;41H \u001b[12;2H \u001b[38;5;6;49mrefile-m4b\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ──────────────────────────────────────\u001b[13;2H*\u001b[13;4H7fba5fb\u001b[13;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[13;30H\u001b[39;49mSupport\u001b[13;38H--version,\u001b[13;49H--help\u001b[13;56Hand\u001b[13;60H--directory\u001b[13;72Hcli\u001b[13;76Harg\u001b[14;3H \u001b[14;15H \u001b[14;21H \u001b[14;24H \u001b[14;29H \u001b[14;32H \u001b[14;37H "]
|
||||||
|
[10.723231, "o", " \u001b[14;42H \u001b[15;2H \u001b[38;5;6;49mrust-action\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ─────────────────────────────────────\u001b[16;2H*\u001b[16;4Hde4785c\u001b[16;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[16;30H\u001b[39;49mfeat:\u001b[16;36Hensure\u001b[16;43Htoolchains\u001b[16;54Hare\u001b[16;58Hup-to-date\u001b[17;3H \u001b[17;8H \u001b[17;14H \u001b[17;17H \u001b[17;22H \u001b[17;25H \u001b[17;30H \u001b[17;35H \u001b[18;2H \u001b[38;5;6;49mskip\u001b[39;49m (m\u001b[18;11Hin -> next -> dev)\u001b[18;30H\u001b[38;5;2;49mokay\u001b[39;49m ────────────────────────────────────────────\u001b[19;2H*\u001b[19;4Hfc7fbca\u001b[19;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[19;30H\u001b[39;49mchore(deps):\u001b[19;43Hupdate\u001b[19;50Hdocker.io/rust\u001b[19;65Hdocker\u001b[19;72Htag\u001b[19;76Hto\u001b[20;3H \u001b[20;9H \u001b[20;15H \u001b[20;18H \u001b[20;23H \u001b[20;26H \u001b[20;31H \u001b[20;36H "]
|
||||||
|
[10.723349, "o", " \u001b[21;2H \u001b[38;5;6;49mtasyn\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ───────────────────────────────────────────\u001b[22;2H*\u001b[22;4H24fe845\u001b[22;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[22;30H\u001b[39;49mchore(deps):\u001b[22;43Hupdate\u001b[22;50Hdocker.io/postgres:16.4-alpin\u001b[23;3H \u001b[23;8H \u001b[23;14H \u001b[23;17H \u001b[23;22H \u001b[23;25H \u001b[23;30H \u001b[23;35H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.742361, "o", "\u001b[2;3Hforge: jo \u001b[2;18H \u001b[2;21H \u001b[2;26H \u001b[2;29H \u001b[2;34H \u001b[2;39H \u001b[3;2H \u001b[38;5;6;49mgit-next\u001b[3;12H\u001b[39;49m(main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ────────────────────────────────────────\u001b[4;2H*\u001b[4;4H91c5973\u001b[4;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[4;30H\u001b[39;49mchore:\u001b[4;37Hrelease\u001b[5;3H \u001b[5;8H \u001b[5;37H \u001b[5;43H \u001b[5;46H \u001b[5;51H \u001b[5;54H \u001b[5;59H \u001b[5;65H \u001b[6;2H \u001b[38;5;15;48;5;1mkxio\u001b[39;49m \u001b[38;5;15;48;5;1mcommit is a Work-in-progress\u001b[6;37H\u001b[39;49m(main -> n\u001b[6;48Hx\u001b[6;50H -> dev)\u001b[6;59H\u001b[38;5;1;49mALERT\u001b[6;65H\u001b[39;49m──────────────\u001b[7;4H805d0b3\u001b[7;13H\u001b[38;5;15;48;5;4mdev)\u001b[39;49m WIP: do\u001b[7;26Hs(fs): add some documentat\u001b[7;54Hn \u001b[7;60H \u001b[7;67H \u001b[7;71H \u001b[7;74H \u001b[8;2H*\u001b[8;4H9943a0f\u001b[8;12H\u001b[38;5;15;48;5;4m(main)(next)\u001b[8;25H\u001b[39;49mchore(deps):\u001b[8;38Hupdate\u001b[8;45Hdocker.io/ru"]
|
||||||
|
[10.742451, "o", "st\u001b[8;60Hdocker\u001b[8;67Htag\u001b[8;71Hto\u001b[8;74Hv1.81\u001b[9;3H \u001b[9;9H \u001b[9;15H \u001b[9;18H \u001b[9;23H \u001b[9;26H \u001b[9;31H \u001b[9;36H \u001b[10;2H \u001b[38;5;6;49mpodal\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ───────────────────────────────────────────\u001b[11;2H*\u001b[11;4H249b943\u001b[11;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[11;30H\u001b[39;49mfix(deps):\u001b[11;41Hupdate\u001b[11;48Hrust\u001b[11;53Hcrate\u001b[11;59Hscraper\u001b[11;67Hto\u001b[11;70H0.20\u001b[12;3H \u001b[12;14H \u001b[12;20H \u001b[12;23H \u001b[12;28H \u001b[12;31H \u001b[12;36H \u001b[12;41H ║\u001b[13;2H \u001b[38;5;6;49mrefile-m4b\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ──────────────────────────────────────\u001b[14;2H*\u001b[14;4H7fba5fb\u001b[14;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[14;30H\u001b[39;49mSupport\u001b[14;38H--version,\u001b[14;49H--help\u001b[14;56Hand\u001b[14;60H--dire"]
|
||||||
|
[10.742513, "o", "ctory\u001b[14;72Hcli\u001b[14;76Harg\u001b[15;3H \u001b[15;15H \u001b[15;21H \u001b[15;24H \u001b[15;29H \u001b[15;32H \u001b[15;37H \u001b[15;42H \u001b[16;2H \u001b[38;5;6;49mrust-action\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ─────────────────────────────────────\u001b[17;2H*\u001b[17;4Hde4785c\u001b[17;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[17;30H\u001b[39;49mfeat:\u001b[17;36Hensure\u001b[17;43Htoolchains\u001b[17;54Hare\u001b[17;58Hup-to-date\u001b[18;3H \u001b[18;8H \u001b[18;14H \u001b[18;17H \u001b[18;22H \u001b[18;25H \u001b[18;30H \u001b[18;35H \u001b[19;2H \u001b[38;5;6;49mskip\u001b[39;49m (m\u001b[19;11Hin -> next -> dev)\u001b[19;30H\u001b[38;5;2;49mokay\u001b[39;49m ────────────────────────────────────────────\u001b[20;2H*\u001b[20;4Hfc7fbca\u001b[20;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[20;30H\u001b[39;49mchore(deps):\u001b[20;43Hupdate\u001b[20;50Hdocker.io/rust\u001b[20;65Hdocker\u001b[20;72Htag\u001b[20;76Hto\u001b"]
|
||||||
|
[10.742578, "o", "[21;3H \u001b[21;9H \u001b[21;15H \u001b[21;18H \u001b[21;23H \u001b[21;26H \u001b[21;31H \u001b[21;36H \u001b[22;2H \u001b[38;5;6;49mtasyn\u001b[39;49m (main -> next -> dev) \u001b[38;5;2;49mokay\u001b[39;49m ───────────────────────────────────────────\u001b[23;2H*\u001b[23;4H24fe845\u001b[23;12H\u001b[38;5;15;48;5;4m(dev)(main)(next)\u001b[23;30H\u001b[39;49mchore(deps):\u001b[23;43Hupdate\u001b[23;50Hdocker.io/postgres:16.4-alpin\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.761454, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.782349, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.801877, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.822526, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.842672, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.861559, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.879728, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.898859, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.917931, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.946604, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.966104, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[10.985743, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.023523, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.061011, "o", "\u001b[24;43H 💚\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.100465, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.138144, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.174063, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.211364, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.24819, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.285142, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.322272, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.358341, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.39547, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.431719, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.469256, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.511171, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.546092, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.583528, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.618694, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.657656, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.693252, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.731247, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.769971, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.804203, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.841036, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.877137, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.914426, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.954717, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[11.990908, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.028533, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.066414, "o", "\u001b[24;43H💚\u001b[24;45H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.107049, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.142204, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.179509, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.216573, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.253728, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.289769, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.326863, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.363905, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.40106, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.43865, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.475818, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.512054, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.550834, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.589195, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.626474, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.665855, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.702211, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.737993, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.774967, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.815764, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.852596, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.892064, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.92746, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[12.964137, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.002874, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.03968, "o", "\u001b[24;43H 💚\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.076753, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.113219, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.151584, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.188483, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.229106, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.264818, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.301622, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.338226, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.375524, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.411574, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.447307, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.483603, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.520106, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.560836, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.598547, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.635115, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.672651, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.712643, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.7507, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.786601, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.82323, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.858725, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.8978, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.934514, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[13.972287, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.008834, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.046299, "o", "\u001b[24;43H💚\u001b[24;45H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.083399, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.120763, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.155627, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.193875, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.231887, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.267898, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.302399, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.343537, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.380356, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.417261, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.453534, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.49263, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.530636, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.566577, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.606367, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.641865, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.679072, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.71686, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.760187, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.795183, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.83164, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.868972, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.905974, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.94637, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[14.983598, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.019429, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.056081, "o", "\u001b[24;43H 💚\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.093109, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.130406, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.172122, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.209038, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.244863, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.282047, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.316998, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.360829, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.39752, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.435025, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.476643, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.518269, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.551214, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.588339, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.626227, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.668075, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.704194, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.740791, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.778154, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.819102, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.855694, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.891253, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.927393, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[15.963477, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.000617, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.036768, "o", "\u001b[24;43H💚\u001b[24;45H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.074615, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.109168, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.147181, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.184001, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.221019, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.259995, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.298455, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.335449, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.374772, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.412157, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.45174, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.487307, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.525937, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.564883, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.602005, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.638765, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.674415, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.712126, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.746806, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.783087, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.821257, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.859364, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.897079, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.934126, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[16.970609, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.007439, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.043377, "o", "\u001b[24;43H 💚\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.081879, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.119148, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.156208, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.192544, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.229623, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.268441, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.304077, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.341245, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.377117, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.417434, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.456131, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.492909, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.530736, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.568137, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.608431, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.646151, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.683754, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.718481, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.75638, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.792562, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.829402, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.866012, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.903936, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.943019, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[17.984106, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.021665, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.059774, "o", "\u001b[24;43H💚\u001b[24;45H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.098821, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.135715, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.17206, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.208703, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.245904, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.283908, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.31957, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.355896, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.393339, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.429976, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.466756, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.506115, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.545975, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.583191, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.621038, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.656638, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.701071, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.739152, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.776111, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.81384, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.850448, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.888985, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.925942, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[18.962416, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[19.000353, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[19.039442, "o", "\u001b[24;43H 💚\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
|
||||||
|
[19.042413, "o", "\u001b[?25h"]
|
||||||
|
[19.042469, "o", "\u001b[?1049l"]
|
||||||
|
[19.110591, "o", "\u001b[?1049l"]
|
BIN
demo.gif
Normal file
BIN
demo.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 578 KiB |
35
justfile
35
justfile
|
@ -47,24 +47,17 @@ grcov-coverage:
|
||||||
find . -name '*.profraw' -exec rm "{}" \;
|
find . -name '*.profraw' -exec rm "{}" \;
|
||||||
echo "Now:\n\topen target/debug/coverage/index.html"
|
echo "Now:\n\topen target/debug/coverage/index.html"
|
||||||
|
|
||||||
publish version:
|
docker-build-builder:
|
||||||
#!/usr/bin/bash -e
|
docker build -t git.kemitix.net/kemitix/git-next-builder:2024.08.04 -f Dockerfile.builder .
|
||||||
echo "Publishing git-next v{{version}} to crates.io..."
|
|
||||||
if [ -z $(git status --short) ]; then
|
docker-build: docker-build-builder
|
||||||
echo "Worktree is clean - proceeding"
|
docker build -t git.kemitix.net/kemitix/git-next:latest .
|
||||||
else
|
|
||||||
echo "Worktree is Dirty - aborting" ; exit
|
docker-run: docker-build
|
||||||
fi
|
docker run -it -p "7777:8888" -v .:/app/ git.kemitix.net/kemitix/git-next:latest server start --ui
|
||||||
git checkout v{{version}}
|
|
||||||
ORDER=$(cargo publish-workspace --target-version {{version}} --crate-prefix git-next --show-order 2>/dev/null | cut -d\ -f2-)
|
run *args:
|
||||||
echo "Publishing crates in order: ${ORDER}"
|
cargo run -- {{ args }}
|
||||||
# INFO: Why not use publish-workspace to publish? It doesn't support when crates-io registry is replaced
|
|
||||||
for P in ${ORDER}
|
run-ui:
|
||||||
do
|
just run server start --ui
|
||||||
echo "Publishing ${P}..."
|
|
||||||
cargo publish --registry crates-io -p $P
|
|
||||||
echo "Done: ${P}"
|
|
||||||
echo "======================================"
|
|
||||||
done
|
|
||||||
echo "All crates published"
|
|
||||||
git checkout dev
|
|
||||||
|
|
Loading…
Reference in a new issue