Repository: angreal/angreal (language: python)

Issue:
Bump git2 from 0.14.4 to 0.16.1
Bumps [git2](https://github.com/rust-lang/git2-rs) from 0.14.4 to 0.16.1.
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/rust-lang/git2-rs/commit/a233483a3952d6112653be86fb5ce65267e3d5ac"><code>a233483</code></a> Update to libgit2 1.5.1</li>
<li><a href="https://github.com/rust-lang/git2-rs/commit/bce15556ef8fd7fb4f9c5122e78febbdb5b7f1ca"><code>bce1555</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/rust-lang/git2-rs/issues/909">#909</a> from ehuss/ssh-keys</li>
<li><a href="https://github.com/rust-lang/git2-rs/commit/222fbf3b9ebb6f45dad82898faa146ebb4637fdd"><code>222fbf3</code></a> Bump versions</li>
<li><a href="https://github.com/rust-lang/git2-rs/commit/fa4194313509224f023976282b25fb94ea895806"><code>fa41943</code></a> Change the certificate_check callback to support passthrough.</li>
<li><a href="https://github.com/rust-lang/git2-rs/commit/84e21aad4e96729408937f9fdde20cfd4f087d1a"><code>84e21aa</code></a> Add ability to get the SSH host key and its type.</li>
<li><a href="https://github.com/rust-lang/git2-rs/commit/e6aa6666b9f0f9110adf5bad56ea1d1dfa119d1c"><code>e6aa666</code></a> Bump git2-curl version. (<a href="https://github-redirect.dependabot.com/rust-lang/git2-rs/issues/861">#861</a>)</li>
<li><a href="https://github.com/rust-lang/git2-rs/commit/46674cebd9089a6cf78e077fa621347f076705b1"><code>46674ce</code></a> Fix warning about unused_must_use for Box::from_raw (<a href="https://github-redirect.dependabot.com/rust-lang/git2-rs/issues/860">#860</a>)</li>
<li><a href="https://github.com/rust-lang/git2-rs/commit/951dce9deaa07d03f9aec41335a09cd7aeeec142"><code>951dce9</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/rust-lang/git2-rs/issues/858">#858</a> from davidkna/git2150</li>
<li><a href="https://github.com/rust-lang/git2-rs/commit/8871f8e9b38f600a499a4dd636840930c04b65bd"><code>8871f8e</code></a> bump libgit2 to 1.5.0</li>
<li><a href="https://github.com/rust-lang/git2-rs/commit/04278a24ba9b3e15b31ed335008a9fabd193a21a"><code>04278a2</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/rust-lang/git2-rs/issues/839">#839</a> from davidkna/libgit2_143</li>
<li>Additional commits viewable in <a href="https://github.com/rust-lang/git2-rs/compare/0.14.4...0.16.1">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=git2&package-manager=cargo&previous-version=0.14.4&new-version=0.16.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
- `@dependabot use these labels` will set the current labels as the default for future PRs for this repo and language
- `@dependabot use these reviewers` will set the current reviewers as the default for future PRs for this repo and language
- `@dependabot use these assignees` will set the current assignees as the default for future PRs for this repo and language
- `@dependabot use this milestone` will set the current milestone as the default for future PRs for this repo and language

You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/angreal/angreal/network/alerts).

</details>


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index e69de29..ea00286 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -0,0 +1,105 @@
+name: tests
+
+on:
+  push:
+    branches: [main]
+  pull_request:
+    branches: [main]
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.event.pull_request.number || github.sha }}
+  cancel-in-progress: true
+
+env:
+  CARGO_INCREMENTAL: 0
+  CARGO_NET_RETRY: 10
+  RUSTUP_MAX_RETRIES: 10
+
+jobs:
+  cargo-build:
+    name: "cargo build"
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions-rs/toolchain@v1
+        with:
+          profile: minimal
+          toolchain: nightly-2022-11-01
+          override: true
+      - uses: Swatinem/rust-cache@v1
+      - run: cargo build --all
+
+  cargo-fmt:
+    name: "cargo fmt"
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions-rs/toolchain@v1
+        with:
+          profile: minimal
+          toolchain: nightly-2022-11-01
+          override: true
+          components: rustfmt
+      - run: cargo fmt --all --check
+
+  cargo_clippy:
+    name: "cargo clippy"
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions-rs/toolchain@v1
+        with:
+          profile: minimal
+          toolchain: nightly-2022-11-01
+          override: true
+          components: clippy
+      - uses: Swatinem/rust-cache@v1
+      - run: cargo clippy --workspace --all-targets --all-features
+  
+
+
+  angreal-tests:
+    name: "angreal run-tests"
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions-rs/toolchain@v1
+        with:
+          profile: minimal
+          toolchain: 1.65.0
+          override: true
+      - uses: Swatinem/rust-cache@v1
+      - uses: actions/setup-python@v4
+        with:
+          python-version: "3.11"
+      - run: pip install maturin angreal==2.0.0rc-1 pytest
+      - run: angreal run-tests
+
+  maturin-build:
+    name: "maturin build"
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions-rs/toolchain@v1
+        with:
+          profile: minimal
+          toolchain: 1.65.0
+          override: true
+      - uses: Swatinem/rust-cache@v1
+      - uses: actions/setup-python@v4
+        with:
+          python-version: "3.11"
+      - run: pip install maturin
+      - run: maturin build
+
+  typos:
+    name: Spell Check with Typos
+    runs-on: ubuntu-latest
+    steps:
+    - name: Checkout Actions Repository
+      uses: actions/checkout@v2
+
+    - name: Check spelling of file.txt
+      uses: crate-ci/typos@master
+      with:
+        files: .
\ No newline at end of file
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
new file mode 100644
index 0000000..0973850
--- /dev/null
+++ b/.github/workflows/release.yaml
@@ -0,0 +1,294 @@
+name: "Angreal Release"
+
+on:
+  release:
+    types: [published]
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.ref }}
+  cancel-in-progress: true
+
+env:
+  PACKAGE_NAME: angreal
+  PYTHON_VERSION: "3.7" # to build abi3 wheels
+  CARGO_INCREMENTAL: 0
+  CARGO_NET_RETRY: 10
+  RUSTUP_MAX_RETRIES: 10
+
+jobs:
+  macos-x86_64:
+    runs-on: macos-latest
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions/setup-python@v4
+        with:
+          python-version: ${{ env.PYTHON_VERSION }}
+          architecture: x64
+      - name: Install Rust toolchain
+        uses: actions-rs/toolchain@v1
+        with:
+          toolchain: stable
+          profile: minimal
+          default: true
+      - name: Build wheels - x86_64
+        uses: messense/maturin-action@v1
+        with:
+          target: x86_64
+          args: --release --out dist --sdist
+      - name: Install built wheel - x86_64
+        run: |
+          pip install dist/${{ env.PACKAGE_NAME }}-*.whl --force-reinstall
+      - name: Upload wheels
+        uses: actions/upload-artifact@v2
+        with:
+          name: wheels
+          path: dist
+  macos-universal:
+    runs-on: macos-latest
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions/setup-python@v4
+        with:
+          python-version: ${{ env.PYTHON_VERSION }}
+          architecture: x64
+      - name: Install Rust toolchain
+        uses: actions-rs/toolchain@v1
+        with:
+          toolchain: stable
+          profile: minimal
+          default: true
+      - name: Build wheels - universal2
+        uses: messense/maturin-action@v1
+        with:
+          args: --release --universal2 --out dist
+      - name: Install built wheel - universal2
+        run: |
+          pip install dist/${{ env.PACKAGE_NAME }}-*universal2.whl --force-reinstall
+      - name: Upload wheels
+        uses: actions/upload-artifact@v2
+        with:
+          name: wheels
+          path: dist
+
+  windows:
+    runs-on: windows-latest
+    strategy:
+      matrix:
+        target: [x64, x86]
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions/setup-python@v4
+        with:
+          python-version: ${{ env.PYTHON_VERSION }}
+          architecture: ${{ matrix.target }}
+      - name: Install Rust toolchain
+        uses: actions-rs/toolchain@v1
+        with:
+          toolchain: stable
+          profile: minimal
+          default: true
+      - name: Build wheels
+        uses: messense/maturin-action@v1
+        with:
+          target: ${{ matrix.target }}
+          args: --release --out dist
+      - name: Install built wheel
+        shell: bash
+        run: |
+          python -m pip install dist/${{ env.PACKAGE_NAME }}-*.whl --force-reinstall
+      - name: Upload wheels
+        uses: actions/upload-artifact@v2
+        with:
+          name: wheels
+          path: dist
+
+  linux:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        target: [x86_64, i686]
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions/setup-python@v4
+        with:
+          python-version: ${{ env.PYTHON_VERSION }}
+          architecture: x64
+      - name: Build wheels
+        uses: messense/maturin-action@v1
+        with:
+          target: ${{ matrix.target }}
+          manylinux: auto
+          args: --release --out dist
+      - name: Install built wheel
+        if: matrix.target == 'x86_64'
+        run: |
+          pip install dist/${{ env.PACKAGE_NAME }}-*.whl --force-reinstall
+      - name: Upload wheels
+        uses: actions/upload-artifact@v2
+        with:
+          name: wheels
+          path: dist
+
+  linux-cross:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        target: [aarch64, armv7, s390x, ppc64le, ppc64]
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions/setup-python@v4
+        with:
+          python-version: ${{ env.PYTHON_VERSION }}
+      - name: Build wheels
+        uses: messense/maturin-action@v1
+        with:
+          target: ${{ matrix.target }}
+          manylinux: auto
+          args: --no-default-features --release --out dist
+      - uses: uraimo/run-on-arch-action@v2.0.5
+        if: matrix.target != 'ppc64'
+        name: Install built wheel
+        with:
+          arch: ${{ matrix.target }}
+          distro: ubuntu20.04
+          githubToken: ${{ github.token }}
+          install: |
+            apt-get update
+            apt-get install -y --no-install-recommends python3 python3-pip
+            pip3 install -U pip
+          run: |
+            pip3 install ${{ env.PACKAGE_NAME }} --no-index --find-links dist/ --force-reinstall
+      - name: Upload wheels
+        uses: actions/upload-artifact@v2
+        with:
+          name: wheels
+          path: dist
+
+  musllinux:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        target:
+          - x86_64-unknown-linux-musl
+          - i686-unknown-linux-musl
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions/setup-python@v4
+        with:
+          python-version: ${{ env.PYTHON_VERSION }}
+          architecture: x64
+      - name: Build wheels
+        uses: messense/maturin-action@v1
+        with:
+          target: ${{ matrix.target }}
+          manylinux: musllinux_1_2
+          args: --release --out dist
+      - name: Install built wheel
+        if: matrix.target == 'x86_64-unknown-linux-musl'
+        uses: addnab/docker-run-action@v3
+        with:
+          image: alpine:latest
+          options: -v ${{ github.workspace }}:/io -w /io
+          run: |
+            apk add py3-pip
+            pip3 install ${{ env.PACKAGE_NAME }} --no-index --find-links /io/dist/ --force-reinstall
+      - name: Upload wheels
+        uses: actions/upload-artifact@v2
+        with:
+          name: wheels
+          path: dist
+
+  musllinux-cross:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        platform:
+          - target: aarch64-unknown-linux-musl
+            arch: aarch64
+          - target: armv7-unknown-linux-musleabihf
+            arch: armv7
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions/setup-python@v4
+        with:
+          python-version: ${{ env.PYTHON_VERSION }}
+      - name: Build wheels
+        uses: messense/maturin-action@v1
+        with:
+          target: ${{ matrix.platform.target }}
+          manylinux: musllinux_1_2
+          args: --release --out dist
+      - uses: uraimo/run-on-arch-action@master
+        name: Install built wheel
+        with:
+          arch: ${{ matrix.platform.arch }}
+          distro: alpine_latest
+          githubToken: ${{ github.token }}
+          install: |
+            apk add py3-pip
+          run: |
+            pip3 install ${{ env.PACKAGE_NAME }} --no-index --find-links dist/ --force-reinstall
+      - name: Upload wheels
+        uses: actions/upload-artifact@v2
+        with:
+          name: wheels
+          path: dist
+
+  pypy:
+    runs-on: ${{ matrix.os }}
+    strategy:
+      matrix:
+        os: [ubuntu-latest, macos-latest]
+        target: [x86_64, aarch64]
+        python-version:
+          - "3.7"
+          - "3.8"
+          - "3.9"
+        exclude:
+          - os: macos-latest
+            target: aarch64
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions/setup-python@v4
+        with:
+          python-version: pypy${{ matrix.python-version }}
+      - name: Build wheels
+        uses: messense/maturin-action@v1
+        with:
+          target: ${{ matrix.target }}
+          manylinux: auto
+          args: --release --out dist -i pypy${{ matrix.python-version }}
+      - name: Install built wheel
+        if: matrix.target == 'x86_64'
+        run: |
+          pip install dist/${{ env.PACKAGE_NAME }}-*.whl --force-reinstall
+      - name: Upload wheels
+        uses: actions/upload-artifact@v2
+        with:
+          name: wheels
+          path: dist
+  release:
+    name: Release
+    runs-on: ubuntu-latest
+    needs:
+      - macos-universal
+      - macos-x86_64
+      - windows
+      - linux
+      - linux-cross
+      - musllinux
+      - musllinux-cross
+      - pypy
+    if: "startsWith(github.ref, 'refs/tags/')"
+    steps:
+      - uses: actions/download-artifact@v2
+        with:
+          name: wheels
+      - uses: actions/setup-python@v4
+      - name: Publish to PyPi
+        env:
+          TWINE_USERNAME: __token__
+          TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
+        run: |
+          pip install --upgrade twine
+          twine upload --skip-existing *
diff --git a/Cargo.lock b/Cargo.lock
index c231ee9..4531736 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -40,12 +40,12 @@ name = "angreal"
 version = "2.0.0-rc.1"
 dependencies = [
  "clap",
- "env_logger",
  "git-url-parse",
  "git2",
  "glob",
  "home",
  "log",
+ "log4rs",
  "once_cell",
  "pyo3",
  "rand",
@@ -56,6 +56,18 @@ dependencies = [
  "walkdir",
 ]
 
+[[package]]
+name = "anyhow"
+version = "1.0.68"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61"
+
+[[package]]
+name = "arc-swap"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6"
+
 [[package]]
 name = "atty"
 version = "0.2.14"
@@ -140,8 +152,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
 dependencies = [
  "iana-time-zone",
+ "js-sys",
  "num-integer",
  "num-traits",
+ "time",
+ "wasm-bindgen",
  "winapi",
 ]
 
@@ -306,6 +321,23 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "derivative"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "destructure_traitobject"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c877555693c14d2f84191cfd3ad8582790fc52b5e2274b40b59cf5f5cea25c7"
+
 [[package]]
 name = "deunicode"
 version = "0.4.3"
@@ -322,19 +354,6 @@ dependencies = [
  "crypto-common",
 ]
 
-[[package]]
-name = "env_logger"
-version = "0.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7"
-dependencies = [
- "atty",
- "humantime",
- "log",
- "regex",
- "termcolor",
-]
-
 [[package]]
 name = "eyre"
 version = "0.6.8"
@@ -378,7 +397,7 @@ checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
 dependencies = [
  "cfg-if",
  "libc",
- "wasi",
+ "wasi 0.11.0+wasi-snapshot-preview1",
 ]
 
 [[package]]
@@ -403,9 +422,9 @@ dependencies = [
 
 [[package]]
 name = "git2"
-version = "0.14.4"
+version = "0.16.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0155506aab710a86160ddb504a480d2964d7ab5b9e62419be69e0032bc5931c"
+checksum = "ccf7f68c2995f392c49fffb4f95ae2c873297830eb25c6bc4c114ce8f4562acc"
 dependencies = [
  "bitflags",
  "libc",
@@ -600,9 +619,9 @@ checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
 
 [[package]]
 name = "libgit2-sys"
-version = "0.13.4+1.4.2"
+version = "0.14.2+1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0fa6563431ede25f5cc7f6d803c6afbc1c5d3ad3d4925d12c882bf2b526f5d1"
+checksum = "7f3d95f6b51075fe9810a7ae22c7095f12b98005ab364d8544797a825ce946a4"
 dependencies = [
  "cc",
  "libc",
@@ -647,6 +666,12 @@ dependencies = [
  "cc",
 ]
 
+[[package]]
+name = "linked-hash-map"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
+
 [[package]]
 name = "lock_api"
 version = "0.4.9"
@@ -664,6 +689,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
 dependencies = [
  "cfg-if",
+ "serde",
+]
+
+[[package]]
+name = "log-mdc"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7"
+
+[[package]]
+name = "log4rs"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d36ca1786d9e79b8193a68d480a0907b612f109537115c6ff655a3a1967533fd"
+dependencies = [
+ "anyhow",
+ "arc-swap",
+ "chrono",
+ "derivative",
+ "fnv",
+ "humantime",
+ "libc",
+ "log",
+ "log-mdc",
+ "parking_lot",
+ "serde",
+ "serde-value",
+ "serde_json",
+ "serde_yaml",
+ "thiserror",
+ "thread-id",
+ "typemap-ors",
+ "winapi",
 ]
 
 [[package]]
@@ -743,6 +801,15 @@ dependencies = [
  "vcpkg",
 ]
 
+[[package]]
+name = "ordered-float"
+version = "2.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87"
+dependencies = [
+ "num-traits",
+]
+
 [[package]]
 name = "os_str_bytes"
 version = "6.4.1"
@@ -1072,6 +1139,30 @@ name = "serde"
 version = "1.0.150"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde-value"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
+dependencies = [
+ "ordered-float",
+ "serde",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.150"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
 
 [[package]]
 name = "serde_json"
@@ -1084,6 +1175,18 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "serde_yaml"
+version = "0.8.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b"
+dependencies = [
+ "indexmap",
+ "ryu",
+ "serde",
+ "yaml-rust",
+]
+
 [[package]]
 name = "sha1"
 version = "0.10.5"
@@ -1230,6 +1333,17 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "thread-id"
+version = "4.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fdfe0627923f7411a43ec9ec9c39c3a9b4151be313e0922042581fb6c9b717f"
+dependencies = [
+ "libc",
+ "redox_syscall",
+ "winapi",
+]
+
 [[package]]
 name = "thread_local"
 version = "1.1.4"
@@ -1239,6 +1353,17 @@ dependencies = [
  "once_cell",
 ]
 
+[[package]]
+name = "time"
+version = "0.1.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
+dependencies = [
+ "libc",
+ "wasi 0.10.0+wasi-snapshot-preview1",
+ "winapi",
+]
+
 [[package]]
 name = "tinyvec"
 version = "1.6.0"
@@ -1317,6 +1442,15 @@ dependencies = [
  "tracing-core",
 ]
 
+[[package]]
+name = "typemap-ors"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a68c24b707f02dd18f1e4ccceb9d49f2058c2fb86384ef9972592904d7a28867"
+dependencies = [
+ "unsafe-any-ors",
+]
+
 [[package]]
 name = "typenum"
 version = "1.16.0"
@@ -1421,6 +1555,15 @@ version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "58ee9362deb4a96cef4d437d1ad49cffc9b9e92d202b6995674e928ce684f112"
 
+[[package]]
+name = "unsafe-any-ors"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0a303d30665362d9680d7d91d78b23f5f899504d4f08b3c4cf08d055d87c0ad"
+dependencies = [
+ "destructure_traitobject",
+]
+
 [[package]]
 name = "url"
 version = "2.3.1"
@@ -1467,6 +1610,12 @@ dependencies = [
  "winapi-util",
 ]
 
+[[package]]
+name = "wasi"
+version = "0.10.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
+
 [[package]]
 name = "wasi"
 version = "0.11.0+wasi-snapshot-preview1"
@@ -1614,3 +1763,12 @@ name = "windows_x86_64_msvc"
 version = "0.42.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
+
+[[package]]
+name = "yaml-rust"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
+dependencies = [
+ "linked-hash-map",
+]
diff --git a/Cargo.toml b/Cargo.toml
index 6723021..8603d0c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -16,16 +16,16 @@ pyo3 = { version = "0.17.3", extension-module = ["extension-module"], default =
 clap = { version = "3" }
 version = {version = "3.0.0"}
 log = { version = "0.4" }
-env_logger = { version = "0.9" }
 glob = { version = "0.3.0" }
 once_cell = {version = "1.3.1"}
-git2 = {version = "0.14"}
+git2 = {version = "0.16"}
 git-url-parse = { version = "0.4.4" }
 home = { version = "0.5.4" }
 tera = { version = "1.17.1" }
 walkdir = {version = "2.3.2" }
 toml = {version = "0.5" }
 text_io = {version = "0.1.12" }
+log4rs = {version ="1.2.0"}
 
 [dev-dependencies]
 rand = { version="0.8.5" }
diff --git a/docs/_draft/how_to/add_command_line_arguments.rst.md b/docs/_draft/how_to/add_command_line_arguments.rst.md
index 1a7d99b..8414ea7 100644
--- a/docs/_draft/how_to/add_command_line_arguments.rst.md
+++ b/docs/_draft/how_to/add_command_line_arguments.rst.md
@@ -52,6 +52,6 @@ provided it would print \"Hello world!\" to the screen.
 For a full treatment of what you can do, I\'d strongly recommend reading
 :
 
--   [paramaters](https://click.palletsprojects.com/en/7.x/parameters/)
+-   [parameters](https://click.palletsprojects.com/en/7.x/parameters/)
 -   [options](https://click.palletsprojects.com/en/7.x/options/)
 -   [arguments](https://click.palletsprojects.com/en/7.x/arguments/)
diff --git a/docs/_draft/how_to/use-github-integration.rst.md b/docs/_draft/how_to/use-github-integration.rst.md
deleted file mode 100644
index 797b5ee..0000000
--- a/docs/_draft/how_to/use-github-integration.rst.md
+++ /dev/null
@@ -1,74 +0,0 @@
----
-title: GitHub Integrations
----
-
-The Basics
-==========
-
-Access to GitHub\'s API is available throught the class. An access token
-is required to interact with GitHub\'s service.
-
-::: {.note}
-::: {.admonition-title}
-Note
-:::
-
-For information on how to get and setup an user authentication token
-check out GitHub\'s documentation
-[here](https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line).
-For the sake of this documentation it is assumed that the token is
-stored in an environmental variable called [GITHUB\_TOKEN]{.title-ref}.
-:::
-
-``` {.sourceCode .python}
-from angreal import GitHub
-github = GitHub('http://github.com',token=os.environ.get('GITHUB_TOKEN'))
-```
-
-After initializing the GitHub object, the repository to interact with
-must be either fetched or created. Using the method does require having
-the integer id from the remote. If you are creating a template that will
-use this, it is suggested that you store the id inside of the for later
-retrieval.
-
-``` {.sourceCode .python}
-github.get_repo(1)
-github.create_repository('new_repo')
-```
-
-Once the objects repository has been set, you can begin interacting with
-it provided methods in the class. :
-
--   
--   
--   
-
-::: {.note}
-::: {.admonition-title}
-Note
-:::
-
-NoOp methods
-
-While available the following do nothing as GitHub\'s API does not
-support the functionality. They will silently pass if called. - - - -
-:::
-
-::: {.warning}
-::: {.admonition-title}
-Warning
-:::
-
-, is absolutely destructive and does not provide any protections, use at
-your own risk.
-:::
-
-More Advanced Usage
-===================
-
-Once the GitHub object is initialized the
-:py`remote <angreal.integrations.gh.GitHub.remote>`{.interpreted-text
-role="attr"} attribute is available for direct manipulation. This is
-simply a binding to a
-[PyGithub](https://pygithub.readthedocs.io/en/latest/) object, and as
-such can be used as though interacting with that library directly.
diff --git a/docs/_draft/how_to/use-gitlab-integration.rst.md b/docs/_draft/how_to/use-gitlab-integration.rst.md
deleted file mode 100644
index d773a79..0000000
--- a/docs/_draft/how_to/use-gitlab-integration.rst.md
+++ /dev/null
@@ -1,68 +0,0 @@
----
-title: GitLab Integrations
----
-
-The Basics
-==========
-
-Access to GitLab\'s API is available throught the class. An access token
-is required to interact with GitLab\'s service.
-
-::: {.note}
-::: {.admonition-title}
-Note
-:::
-
-For information on how to get and setup an user authentication token
-check out Gitlab\'s documentation
-[here](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html).
-For the sake of this documentation it is assumed that the token is
-stored in an environmental variable called [GITLAB\_TOKEN]{.title-ref}.
-:::
-
-``` {.sourceCode .python}
-from angreal import GitLab
-gitlab = GitLab('http://gitlab.com',token=os.environ.get('GITLAB_TOKEN'))
-```
-
-After initializing the GitLab object, the repository to interact with
-must be either fetched or created. Using the method does require having
-the integer id from the remote. If you are creating a template that will
-use this, it is suggested that you store the id inside of the for later
-retrieval.
-
-``` {.sourceCode .python}
-gitlab.get_repo(1)
-gitlab.create_repository('new_repo')
-```
-
-Once the objects repository has been set, you can begin interacting with
-it provided methods in the class. :
-
--   
--   
--   
--   
--   
--   
--   
-
-::: {.warning}
-::: {.admonition-title}
-Warning
-:::
-
-, is absolutely destructive and does not provide any protections, use at
-your own risk.
-:::
-
-More Advanced Usage
-===================
-
-Once the GitLab object is initialized the
-:py`remote <angreal.integrations.gl.GitLab.remote>`{.interpreted-text
-role="attr"} attribute is available for direct manipulation. This is
-simply a binding to a
-[python-gitlab](https://python-gitlab.readthedocs.io/en/latest/api-usage.html)
-object, and as such can be used as though interacting with that library
-directly.
diff --git a/docs/content/_index.md b/docs/content/_index.md
index a67b8a8..0251c44 100644
--- a/docs/content/_index.md
+++ b/docs/content/_index.md
@@ -37,7 +37,7 @@ something not the actual steps to complete the task.
 Angreal provides a way to template the structure of projects and a way
 of executing methods for interacting with that project in a consistent
 manner. These methods (called tasks) travel with the project so while
-templated intially, they\'re customizable to the project - allowing some
+templated initially, they\'re customizable to the project - allowing some
 level of flexibility in how a task functions between projects.
 
 ### Why 2.0 ?
diff --git a/src/builder.rs b/src/builder.rs
index befc718..3f7a853 100644
--- a/src/builder.rs
+++ b/src/builder.rs
@@ -1,5 +1,5 @@
 use crate::task::{AngrealArg, ANGREAL_ARGS, ANGREAL_TASKS};
-use clap::{App, AppSettings, Arg, Command};
+use clap::{App, AppSettings, Arg, ArgAction, Command};
 
 pub fn select_args(name: String) -> Vec<AngrealArg> {
     let this = ANGREAL_ARGS.lock().unwrap().clone();
@@ -15,7 +15,13 @@ pub fn build_app() -> App<'static> {
     let mut app = App::new("angreal")
         .setting(AppSettings::NoBinaryName)
         .setting(AppSettings::SubcommandRequiredElseHelp)
-        .allow_external_subcommands(true)
+        .arg(Arg::new("verbose")
+            .short('v')
+            .long("verbose")
+            .action(ArgAction::Count)
+            .global(true)
+            .help("verbose level, (may be used multiple times for more verbosity)")
+        )
         .subcommand(Command::new("init")
                     .about("Initialize an Angreal template from source.")
                     .arg(
diff --git a/src/init.rs b/src/init.rs
index b295a89..3dbe3bd 100644
--- a/src/init.rs
+++ b/src/init.rs
@@ -5,6 +5,9 @@ use home::home_dir;
 
 use glob::glob;
 use log::error;
+use pyo3::prelude::*;
+use pyo3::types::{PyList, PyModule};
+
 use std::env;
 use std::fs;
 use std::fs::File;
@@ -16,9 +19,6 @@ use tera::{Context, Tera};
 use text_io::read;
 use toml::Value;
 use walkdir::WalkDir;
-use pyo3::prelude::*;
-use pyo3::types::{PyList, PyModule};
-use pyo3::PyResult;
 /// Initialize a new project by rendering a template.
 /// If we wish a full over write use force == True
 /// If we wish to use the angreal.toml defaults take_inputs == False
@@ -51,7 +51,7 @@ pub fn init(template: &str, force: bool, take_inputs: bool) {
             let mut try_template = angreal_home;
             try_template.push(Path::new(template));
 
-            //  First we try ~/.angreal for a teamplate with that name
+            //  First we try ~/.angreal for a template with that name
             if try_template.is_dir() {
                 git_pull_ff(try_template.to_str().unwrap())
             } else if Path::new(template).is_dir() {
@@ -84,18 +84,29 @@ pub fn init(template: &str, force: bool, take_inputs: bool) {
     let mut rendered_angreal_init = Path::new(&rendered_dot_angreal_path).to_path_buf();
     rendered_angreal_init.push("init.py");
 
-    if rendered_angreal_init.is_file(){
+    if rendered_angreal_init.is_file() {
         let init_contents = fs::read_to_string(rendered_angreal_init).unwrap();
         // Get our init function
         Python::with_gil(|py| {
-            let syspath: &PyList = py.import("sys").unwrap().getattr("path").unwrap().downcast::<PyList>().unwrap();
-            syspath.insert(0, rendered_dot_angreal_path.clone()).unwrap();
-
-            let function: Py<PyAny> = PyModule::from_code(py, & init_contents, "", "").unwrap().getattr("init").unwrap().into();
+            let syspath: &PyList = py
+                .import("sys")
+                .unwrap()
+                .getattr("path")
+                .unwrap()
+                .downcast::<PyList>()
+                .unwrap();
+            syspath
+                .insert(0, rendered_dot_angreal_path.clone())
+                .unwrap();
+
+            let function: Py<PyAny> = PyModule::from_code(py, &init_contents, "", "")
+                .unwrap()
+                .getattr("init")
+                .unwrap()
+                .into();
             function.call0(py).unwrap();
         });
     }
-    
 }
 
 fn get_scheme(u: &str) -> Result<String, ()> {
@@ -187,34 +198,34 @@ fn render_template(path: &Path, take_input: bool, force: bool) -> String {
     // first we create a Tera instance from an empty directory so we can extend it
     let mut tmp_dir = env::temp_dir();
     tmp_dir.push(Path::new("angreal_tmp"));
-    
-    if tmp_dir.is_dir().not(){
+
+    if tmp_dir.is_dir().not() {
         fs::create_dir(&tmp_dir).unwrap();
     }
 
     tmp_dir.push(Path::new("*"));
     let mut tera = Tera::new(tmp_dir.to_str().unwrap()).unwrap();
-    
+
     tmp_dir.pop();
-    if tmp_dir.is_dir(){
+    if tmp_dir.is_dir() {
         fs::remove_dir_all(&tmp_dir).unwrap();
     }
 
     // We get our templates glob
-    let mut template = path.clone().to_path_buf();
+    let mut template = <&std::path::Path>::clone(&path).to_path_buf();
     template.push(Path::new("**/*"));
 
     // And build our full prefix
-    let _template_name = path.clone().file_name().unwrap();
+    let _template_name = <&std::path::Path>::clone(&path).file_name().unwrap();
 
     for file in glob(template.to_str().unwrap()).expect("Failed to read glob pattern") {
         let file_path = file.as_ref().unwrap();
         let rel_path = file_path.strip_prefix(path).unwrap().to_str().unwrap();
 
-        if file.as_ref().unwrap().is_file() {
-            if rel_path.starts_with("{{") && rel_path.contains("}}") {
-                tera.add_template_file(file.as_ref().unwrap().to_str().unwrap(), Some(rel_path)).unwrap();
-            }
+        if file.as_ref().unwrap().is_file() && rel_path.starts_with("{{") && rel_path.contains("}}")
+        {
+            tera.add_template_file(file.as_ref().unwrap().to_str().unwrap(), Some(rel_path))
+                .unwrap();
         }
     }
 
@@ -241,7 +252,7 @@ fn render_template(path: &Path, take_input: bool, force: bool) -> String {
                 continue;
             }
 
-            if real_path.ends_with(".angreal"){
+            if real_path.ends_with(".angreal") {
                 angreal_path = real_path.clone();
             }
 
@@ -270,7 +281,6 @@ fn render_template(path: &Path, take_input: bool, force: bool) -> String {
         write!(output, "{}", rendered.as_str()).unwrap();
     }
 
-
     angreal_path
 
     // return path to .angreal
@@ -282,8 +292,7 @@ mod tests {
 
     use std::ops::Not;
     use std::path::{Path, PathBuf};
-    use std::{env, fs, thread, time::Duration};
-    
+    use std::{env, fs};
 
     mod common;
 
@@ -296,8 +305,7 @@ mod tests {
         );
         let mut rendered_root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
         rendered_root.push(Path::new("angreal_test_project"));
-        fs::remove_dir_all(&rendered_root);
-
+        let _ = fs::remove_dir_all(&rendered_root);
     }
     #[test]
     fn test_render_template() {
@@ -310,22 +318,16 @@ mod tests {
 
         let mut assets = template_root.clone();
         assets.push("assets");
-        
 
         let mut rendered_root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
         rendered_root.push(Path::new("folder_name"));
-        
 
         let mut dot_angreal = rendered_root.clone();
         dot_angreal.push(Path::new(".angreal"));
-        
-        
-        
 
         let mut readme_rst = rendered_root.clone();
         readme_rst.push("README.rst");
 
-
         let assets_no_exists = assets.is_dir().not();
         let dot_angreal_exists = dot_angreal.is_dir();
         let readme_rst_exists = readme_rst.is_file();
diff --git a/src/lib.rs b/src/lib.rs
index aeff0dd..0e8d8c9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -13,12 +13,13 @@ pub mod macros;
 pub mod builder;
 pub mod git;
 pub mod init;
+pub mod logger;
 pub mod py_logger;
 pub mod task;
 pub mod utils;
 
-use task::ANGREAL_TASKS;
 use builder::build_app;
+use task::ANGREAL_TASKS;
 
 use log::{debug, error};
 use pyo3::types::IntoPyDict;
@@ -32,15 +33,14 @@ use pyo3::prelude::*;
 /// The main function is just an entry point to be called from the core angreal library.
 #[pyfunction]
 fn main() -> PyResult<()> {
+    let handle = logger::init_logger();
     // we have to do this because we're calling the main function through python - when lib+bin build support is available, we can factor away
     let mut argvs: Vec<String> = std::env::args().collect();
     argvs.remove(0);
     argvs.remove(0);
 
-    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("trace"))
-        // .format_timestamp(None)
-        // .format_module_path(true)
-        .init();
+    // env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warning"))
+    // .init();
 
     // Load any angreal task assets that are available to us
     let in_angreal_project = utils::is_angreal_project().is_ok();
@@ -67,6 +67,11 @@ fn main() -> PyResult<()> {
     let mut app_copy = app.clone();
     let sub_command = app.get_matches_from(&argvs);
 
+    // Get our asked for verbosity and set the logger up. TODO: find a way to initialize earlier and reset after.
+    let verbosity = sub_command.get_count("verbose");
+
+    logger::update_verbosity(&handle, verbosity);
+
     match sub_command.subcommand() {
         Some(("init", _sub_matches)) => init::init(
             _sub_matches.value_of("template").unwrap(),
@@ -83,7 +88,7 @@ fn main() -> PyResult<()> {
 
             let command = match some_command {
                 None => {
-                    error!("Task {}, not found.", task.clone());
+                    error!("Task {}, not found.", <&str>::clone(&task));
                     app_copy.print_help().unwrap_or(());
                     exit(1)
                 }
@@ -102,13 +107,9 @@ fn main() -> PyResult<()> {
                         None => {
                             // We need to handle "boolean flags" that are present w/o a value
                             // should probably test that the name is a "boolean type also"
-                            let v = if sub_m.is_present(n.clone()){
-                                true
-                            } else{
-                                false
-                            };
-                            kwargs.push((n.as_str(),v.to_object(py)));
-                        },
+                            let v = sub_m.is_present(n.clone());
+                            kwargs.push((n.as_str(), v.to_object(py)));
+                        }
                         Some(v) => {
                             match arg.python_type.unwrap().as_str() {
                                 "str" => kwargs.push((n.as_str(), v.to_object(py))),
@@ -127,7 +128,7 @@ fn main() -> PyResult<()> {
                 match r_value {
                     Ok(_r_value) => {}
                     Err(r_value) => {
-                        error!("An error occured :");
+                        error!("An error occurred :");
                         error!("{:?}", r_value.traceback(py).unwrap().format());
                         exit(1);
                     }
diff --git a/src/logger.rs b/src/logger.rs
new file mode 100644
index 0000000..e27de22
--- /dev/null
+++ b/src/logger.rs
@@ -0,0 +1,35 @@
+use log4rs::append::console::ConsoleAppender;
+use log4rs::append::console::Target;
+use log4rs::config::{Appender, Config, Root};
+use log4rs::Handle;
+
+pub fn init_logger() -> Handle {
+    let stderr = ConsoleAppender::builder().target(Target::Stderr).build();
+    let config = Config::builder()
+        .appender(Appender::builder().build("stderr", Box::new(stderr)))
+        .build(
+            Root::builder()
+                .appender("stderr")
+                .build(log::LevelFilter::Warn),
+        )
+        .unwrap();
+
+    log4rs::init_config(config).unwrap()
+}
+
+pub fn update_verbosity(log_hndl: &Handle, verbosity: u8) {
+    let level_trace = match verbosity {
+        0 => log::LevelFilter::Warn,
+        1 => log::LevelFilter::Info,
+        2 => log::LevelFilter::Debug,
+        3.. => log::LevelFilter::Trace,
+    };
+
+    let stderr = ConsoleAppender::builder().target(Target::Stderr).build();
+    let config = Config::builder()
+        .appender(Appender::builder().build("stderr", Box::new(stderr)))
+        .build(Root::builder().appender("stderr").build(level_trace))
+        .unwrap();
+
+    log_hndl.set_config(config);
+}
diff --git a/src/py_logger.rs b/src/py_logger.rs
index d283b66..a3be4d8 100644
--- a/src/py_logger.rs
+++ b/src/py_logger.rs
@@ -5,7 +5,8 @@ pub fn register() {
     Python::with_gil(|py| {
         // Extend the `logging` module to interact with log
         setup_logging(py)
-    }).unwrap();
+    })
+    .unwrap();
 }
 /// Consume a Python `logging.LogRecord` and emit a Rust `Log` instead.
 #[pyfunction]
diff --git a/src/task.rs b/src/task.rs
index 882be8d..5e04b38 100644
--- a/src/task.rs
+++ b/src/task.rs
@@ -95,6 +95,7 @@ impl AngrealArg {
         help = "None",
         required = "None"
     )]
+    #[allow(clippy::too_many_arguments)]
     fn __new__(
         name: &str,
         command_name: &str,


Test patch:
diff --git a/.angreal/task_run_tests.py b/.angreal/task_run_tests.py
index 227f2f8..9cb4019 100644
--- a/.angreal/task_run_tests.py
+++ b/.angreal/task_run_tests.py
@@ -12,9 +12,6 @@ def run_tests():
     Run tests for both cargo test and pytest
     """
 
-    subprocess.run(["maturin", "develop", "-q"])
-
-
     print(green + "====================" + end )
     print(green + "Starting Cargo tests" + end )
     print(green + "====================" + end )