From 379d6e0095e2ed17feea2596bac6fcbc24c0909c Mon Sep 17 00:00:00 2001 From: Alex Clarke Date: Wed, 30 Oct 2024 15:24:03 -0600 Subject: [PATCH] Pre-alpha CI/CD release support --- .cargo-husky/hooks/pre-commit | 11 ++ .cargo-husky/hooks/pre-push | 11 ++ .github/ISSUE_TEMPLATE/blank_issue.md | 4 + .github/ISSUE_TEMPLATE/bug_report.yaml | 71 +++++++++++ .github/ISSUE_TEMPLATE/enhancement.md | 13 ++ .github/workflows/check.yml | 81 +++++++++++++ .github/workflows/release.yml | 32 +++++ .github/workflows/test.yml | 159 +++++++++++++++++++++++++ CODE_OF_CONDUCT.md | 128 ++++++++++++++++++++ CONTRIBUTING.md | 25 ++++ Cargo.lock | 31 ++++- Cargo.toml | 10 +- README.md | 49 ++++---- SECURITY.md | 14 +++ src/ui/widgets/input_box.rs | 2 +- src/utils.rs | 26 +++- 16 files changed, 642 insertions(+), 25 deletions(-) create mode 100755 .cargo-husky/hooks/pre-commit create mode 100755 .cargo-husky/hooks/pre-push create mode 100644 .github/ISSUE_TEMPLATE/blank_issue.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yaml create mode 100644 .github/ISSUE_TEMPLATE/enhancement.md create mode 100644 .github/workflows/check.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/test.yml create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 SECURITY.md diff --git a/.cargo-husky/hooks/pre-commit b/.cargo-husky/hooks/pre-commit new file mode 100755 index 0000000..103fa60 --- /dev/null +++ b/.cargo-husky/hooks/pre-commit @@ -0,0 +1,11 @@ +#!/bin/sh + +set -e + +echo "Running pre-push hook:" + +echo "Executing: make lint" +make lint + +echo "Executing: cargo test" +cargo test diff --git a/.cargo-husky/hooks/pre-push b/.cargo-husky/hooks/pre-push new file mode 100755 index 0000000..103fa60 --- /dev/null +++ b/.cargo-husky/hooks/pre-push @@ -0,0 +1,11 @@ +#!/bin/sh + +set -e + +echo "Running pre-push hook:" + +echo "Executing: make lint" +make lint + +echo "Executing: cargo test" +cargo test diff --git a/.github/ISSUE_TEMPLATE/blank_issue.md b/.github/ISSUE_TEMPLATE/blank_issue.md new file mode 100644 index 0000000..9aef3eb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/blank_issue.md @@ -0,0 +1,4 @@ +--- +name: Blank Issue +about: Create a blank issue. +--- diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml new file mode 100644 index 0000000..0554017 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -0,0 +1,71 @@ +name: Bug Report +description: Create a report to help us improve +labels: bug +body: + - type: markdown + attributes: + value: Thank you for filing a bug report! + - type: textarea + id: problem + attributes: + label: Summary + description: > + Please provide a short summary of the bug, along with any information + you feel relevant to replicate the bug. + validations: + required: true + - type: textarea + id: reproduction-steps + attributes: + label: Reproduction Steps + value: | + + + I tried this: + + 1. `managarr` + + I expected this to happen: + + Instead, this happened: + - type: textarea + id: managarr-log + attributes: + label: Managarr log + description: Include the Managarr log file to help diagnose the issue. + value: | + | OS | Log file location | + | ------- | ----------------------------------------------------- | + | Linux | `~/.cache/managarr/managarr.log` | + | Mac | `~/Library/Logs/managarr/managarr.log` | + | Windows | `C:\Users\\AppData\Local\managarr\managarr.log` | + + ``` + please provide a copy of your managarr log file here if possible, you may need to redact some of the lines + ``` + + - type: input + id: platform + attributes: + label: Platform + placeholder: Linux / macOS / Windows + validations: + required: true + - type: input + id: terminal-emulator + attributes: + label: Terminal Emulator + placeholder: wezterm 20220101-133340-7edc5b5a + validations: + required: true + - type: input + id: managarr-version + attributes: + label: Managarr Version + description: > + Managarr version (`managarr --version` if using a release, `git describe` if building + from main). + **Make sure that you are using the [latest managarr release](https://github.com/Dark-Alex-17/managarr/releases) or a newer main build** + placeholder: "managarr 0.0.36" + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/enhancement.md b/.github/ISSUE_TEMPLATE/enhancement.md new file mode 100644 index 0000000..b808e71 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/enhancement.md @@ -0,0 +1,13 @@ +--- +name: Enhancement +about: Suggest an improvement +title: '' +labels: enhancement +assignees: '' +--- + + diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..6acbb61 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,81 @@ +# Adapted from https://github.com/joshka/github-workflows/blob/main/.github/workflows/rust-check.yml +# Thanks to joshka for permission to use this template! +on: + push: + branches: + - main + pull_request: + +name: Check + +env: + CARGO_TERM_COLOR: always + +# ensure that the workflow is only triggered once per PR, subsequent pushes to the PR will cancel +# and restart the workflow. See https://docs.github.com/en/actions/using-jobs/using-concurrency +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + fmt: + name: stable / fmt + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + - name: Run cargo fmt + run: cargo fmt -- --check + - name: Cache Cargo dependencies + uses: Swatinem/rust-cache@v2 + clippy: + name: ${{ matrix.toolchain }} / clippy + runs-on: ubuntu-latest + permissions: + checks: write + strategy: + fail-fast: false + matrix: + # Get early warnings about new lints introduced in the beta channel + toolchain: [stable, beta] + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + with: + components: clippy + - name: Run clippy action + uses: clechasseur/rs-clippy-check@v3 + - name: Cache Cargo dependencies + uses: Swatinem/rust-cache@v2 + doc: + # run docs generation on nightly rather than stable. This enables features like + # https://doc.rust-lang.org/beta/unstable-book/language-features/doc-cfg.html which allows an + # API be documented as only available in some specific platforms. + name: nightly / doc + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install Rust nightly + uses: dtolnay/rust-toolchain@nightly + - name: Run cargo doc + run: cargo doc --no-deps --all-features + env: + RUSTDOCFLAGS: --cfg docsrs + msrv: + # check that we can build using the minimal rust version that is specified by this crate + name: 1.82.0 / check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install 1.82.0 + uses: dtolnay/rust-toolchain@master + with: + toolchain: 1.82.0 + - name: cargo +1.82.0 check + run: cargo check diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..67831fb --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,32 @@ +# Adapted from https://github.com/joshka/github-workflows/blob/main/.github/workflows/rust-release-plz.yml +# Thanks to joshka for permission to use this template! + +name: Create Release PR and publish to crates.io + +permissions: + pull-requests: write + contents: write + +on: + push: + branches: + - main + +jobs: + release-plz: + # see https://release-plz.ieni.dev/docs/github + # for more information + name: Release-plz + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + - name: Run release-plz + uses: MarcoIeni/release-plz-action@v0.5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..386b2de --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,159 @@ +# Adapted from https://github.com/joshka/github-workflows/blob/main/.github/workflows/rust-test.yml +# Thanks to joshka for permission to use this template! +on: + push: + branches: + - main + pull_request: + +name: Test Suite + +# This is the main CI workflow that runs the test suite on all pushes to main and all pull requests. +# It runs the following jobs: +# - required: runs the test suite on ubuntu with stable and beta rust toolchains +# - minimal: runs the test suite with the minimal versions of the dependencies that satisfy the +# requirements of this crate, and its dependencies +# - os-check: runs the test suite on mac and windows +# - coverage: runs the test suite and collects coverage information + +# ensure that the workflow is only triggered once per PR, subsequent pushes to the PR will cancel +# and restart the workflow. See https://docs.github.com/en/actions/using-jobs/using-concurrency +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + required: + runs-on: ubuntu-latest + name: ubuntu / ${{ matrix.toolchain }} + strategy: + fail-fast: false + matrix: + # run on stable and beta to ensure that tests won't break on the next version of the rust + # toolchain + toolchain: [stable, beta] + steps: + - uses: actions/checkout@v4 + - name: Install ${{ matrix.toolchain }} + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.toolchain }} + # enable this ci template to run regardless of whether the lockfile is checked in or not + - name: cargo generate-lockfile + if: hashFiles('Cargo.lock') == '' + run: cargo generate-lockfile + - name: cargo test --locked + run: cargo test --locked --all-features --all-targets + minimal-versions: + # This action chooses the oldest version of the dependencies permitted by Cargo.toml to ensure + # that this crate is compatible with the minimal version that this crate and its dependencies + # require. This will pickup issues where this create relies on functionality that was introduced + # later than the actual version specified (e.g., when we choose just a major version, but a + # method was added after this version). + # + # This particular check can be difficult to get to succeed as often transitive dependencies may + # be incorrectly specified (e.g., a dependency specifies 1.0 but really requires 1.1.5). There + # is an alternative flag available -Zdirect-minimal-versions that uses the minimal versions for + # direct dependencies of this crate, while selecting the maximal versions for the transitive + # dependencies. Alternatively, you can add a line in your Cargo.toml to artificially increase + # the minimal dependency, which you do with e.g.: + # ```toml + # # for minimal-versions + # [target.'cfg(any())'.dependencies] + # openssl = { version = "0.10.55", optional = true } # needed to allow foo to build with -Zminimal-versions + # ``` + # The optional = true is necessary in case that dependency isn't otherwise transitively required + # by your library, and the target bit is so that this dependency edge never actually affects + # Cargo build order. See also + # https://github.com/jonhoo/fantoccini/blob/fde336472b712bc7ebf5b4e772023a7ba71b2262/Cargo.toml#L47-L49. + # This action is run on ubuntu with the stable toolchain, as it is not expected to fail + runs-on: ubuntu-latest + name: ubuntu / stable / minimal-versions + steps: + - uses: actions/checkout@v4 + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + - name: Install nightly for -Zdirect-minimal-versions + uses: dtolnay/rust-toolchain@nightly + - name: rustup default stable + run: rustup default stable + - name: cargo update -Zdirect-minimal-versions + run: cargo +nightly update -Zdirect-minimal-versions + - name: cargo test + run: cargo test --locked --all-features --all-targets + - name: Cache Cargo dependencies + uses: Swatinem/rust-cache@v2 + os-check: + # run cargo test on mac and windows + runs-on: ${{ matrix.os }} + name: ${{ matrix.os }} / stable + strategy: + fail-fast: false + matrix: + os: [macos-latest, windows-latest] + steps: + # if your project needs OpenSSL, uncomment this to fix Windows builds. + # it's commented out by default as the install command takes 5-10m. + # - run: echo "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" | Out-File -FilePath $env:GITHUB_ENV -Append + # if: runner.os == 'Windows' + # - run: vcpkg install openssl:x64-windows-static-md + # if: runner.os == 'Windows' + - name: Checkout + uses: actions/checkout@v4 + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + - name: cargo generate-lockfile + if: hashFiles('Cargo.lock') == '' + run: cargo generate-lockfile + - name: cargo test + run: cargo test --locked --all-features --all-targets + - name: Cache Cargo dependencies + uses: Swatinem/rust-cache@v2 + coverage: + # use llvm-cov to build and collect coverage and outputs in a format that + # is compatible with codecov.io + # + # note that codecov as of v4 requires that CODECOV_TOKEN from + # + # https://app.codecov.io/gh///settings + # + # is set in two places on your repo: + # + # - https://github.com/jonhoo/guardian/settings/secrets/actions + # - https://github.com/jonhoo/guardian/settings/secrets/dependabot + # + # (the former is needed for codecov uploads to work with Dependabot PRs) + # + # PRs coming from forks of your repo will not have access to the token, but + # for those, codecov allows uploading coverage reports without a token. + # it's all a little weird and inconvenient. see + # + # https://github.com/codecov/feedback/issues/112 + # + # for lots of more discussion + runs-on: ubuntu-latest + name: ubuntu / stable / coverage + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + with: + components: llvm-tools-preview + - name: cargo install cargo-llvm-cov + uses: taiki-e/install-action@cargo-llvm-cov + - name: cargo generate-lockfile + if: hashFiles('Cargo.lock') == '' + run: cargo generate-lockfile + - name: cargo llvm-cov + run: cargo llvm-cov --locked --all-features --lcov --output-path lcov.info + - name: Record Rust version + run: echo "RUST=$(rustc --version)" >> "$GITHUB_ENV" + - name: Cache Cargo dependencies + uses: Swatinem/rust-cache@v2 + - name: Upload to codecov.io + uses: codecov/codecov-action@v4 + with: + fail_ci_if_error: true + token: ${{ secrets.CODECOV_TOKEN }} + env_vars: OS,RUST diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..a29f7e7 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +d4udts@gmail.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..d015793 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,25 @@ +# Contributing +Contributors are very welcome! **No contribution is too small and all contributions are valued.** + +You'll need to have the stable Rust toolchain installed in order to develop Managarr. + +The Rust toolchain (stable) can be installed via rustup using the following command: + +```shell +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +``` + +This will install `rustup`, `rustc` and `cargo`. For more information, refer to the [official Rust installation documentation](https://www.rust-lang.org/tools/install). + +## Setup workspace + +1. Clone this repo +2. Run `cargo test` to setup hooks +3. Make changes +4. Run the application using `make run` or `cargo run` +5. Commit changes. This will trigger pre-commit hooks that will run format, test and lint. If there are errors or warnings from Clippy, please fix them. +6. Push your code to a new branch named after the feature/bug/etc. you're adding. This will trigger pre-push hooks that will run lint and test. +7. Create a PR + +## Questions? Reach out to me! +If you encounter any questions while developing Managarr, please don't hesitate to reach out to me at alex.j.tusa@gmail.com. I'm happy to help contributors, new and experienced in any way I can! diff --git a/Cargo.lock b/Cargo.lock index 6a2f9e6..68f9cb7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -228,6 +228,12 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +[[package]] +name = "cargo-husky" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b02b629252fe8ef6460461409564e2c21d0c8e77e0944f3d189ff06c4e932ad" + [[package]] name = "cassowary" version = "0.3.0" @@ -481,6 +487,16 @@ dependencies = [ "dirs-sys", ] +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + [[package]] name = "dirs-sys" version = "0.4.1" @@ -493,6 +509,17 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "doc-comment" version = "0.3.3" @@ -1017,13 +1044,14 @@ dependencies = [ [[package]] name = "managarr" -version = "0.0.36" +version = "0.1.0" dependencies = [ "anyhow", "assert_cmd", "async-trait", "backtrace", "bimap", + "cargo-husky", "chrono", "clap", "clap_complete", @@ -1032,6 +1060,7 @@ dependencies = [ "crossterm 0.27.0", "ctrlc", "derivative", + "dirs-next", "human-panic", "indoc", "itertools", diff --git a/Cargo.toml b/Cargo.toml index c1548e1..9f98e76 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "managarr" -version = "0.0.36" +version = "0.1.0" authors = ["Alex Clarke "] description = "A TUI and CLI to manage your Servarrs" keywords = ["managarr", "tui-rs", "dashboard", "servarr", "tui"] @@ -9,7 +9,9 @@ repository = "https://github.com/Dark-Alex-17/managarr" homepage = "https://github.com/Dark-Alex-17/managarr" readme = "README.md" edition = "2021" +license = "MIT" rust-version = "1.82.0" +exclude = [".github", "CONTRIBUTING.md", "*.log", "tags"] [dependencies] anyhow = "1.0.68" @@ -42,6 +44,7 @@ itertools = "0.13.0" ctrlc = "3.4.5" colored = "2.1.0" async-trait = "0.1.83" +dirs-next = "2.0.0" [dev-dependencies] assert_cmd = "2.0.16" @@ -50,6 +53,11 @@ mockito = "1.0.0" pretty_assertions = "1.3.0" rstest = "0.18.2" +[dev-dependencies.cargo-husky] +version = "1" +default-features = false +features = ["user-hooks"] + [[bin]] bench = false path = "src/main.rs" diff --git a/README.md b/README.md index 1c7ba91..34c5adf 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,20 @@ -# managarr - A TUI to manage your Servarrs -Managarr is a TUI to help you manage your HTPC (Home Theater PC). Built with 🤎 in Rust! +# managarr - A TUI and CLI to manage your Servarrs + +![check](https://github.com/Dark-Alex-17/managarr/actions/workflows/check.yml/badge.svg) +![test](https://github.com/Dark-Alex-17/managarr/actions/workflows/test.yml/badge.svg) +![test](https://github.com/Dark-Alex-17/managarr/actions/workflows/release.yml/badge.svg) +![License](https://img.shields.io/badge/license-MIT-blueviolet.svg) +![LOC](https://tokei.rs/b1/github/Dark-Alex-17/managarr?category=code) +[![crates.io link](https://img.shields.io/crates/v/managarr.svg)](https://crates.io/crates/managarr) +![Release](https://img.shields.io/github/v/release/Dark-Alex-17/managarr?color=%23c694ff) +[![codecov](https://codecov.io/gh/Dark-Alex-17/managarr/graph/badge.svg?token=33G179TW67)](https://codecov.io/gh/Dark-Alex-17/managarr) +[![GitHub Downloads](https://img.shields.io/github/downloads/Dark-Alex-17/managarr/total.svg?label=GitHub%20downloads)](https://github.com/Dark-Alex-17/managarr/releases) +![Crate.io downloads](https://img.shields.io/crates/d/managarr?label=Crate%20downloads) + +Managarr is a TUI and CLI to help you manage your HTPC (Home Theater PC). Built with 🤎 in Rust! ![library](screenshots/library.png) -## NOTE: Managarr is not yet stable (Pre-Alpha) -I'm regularly making changes to get Managarr to an alpha release. As such, I'm regularly refactoring the code to be cleaner -and more easily extensible. Until I get Managarr across the alpha-release finish line, this regular refactoring will make -contributions difficult. Thus, stability is not guaranteed (yet!). - -This means that while all tests will pass, there may be certain menus or keymappings that are no-ops, or produce empty -screens, or things of this sort. - -Part of the alpha release plan is to add contribution guidelines, CI/CD, release pipelines, etc. so that -all future maintenance and additions can be handled easily. So unfortunately, until that happens, Managarr may contain -breaking changes and be slow to react to any PR's. - -Progress for the alpha release can be followed on my [Wekan Board](https://wekan.alexjclarke.com/b/dHoGjBb44MHM9HSv4/managarr) -with all items tagged `Alpha`. - -Thanks for your patience as I work to get this into a place ready for contributions and to make developer experiences as -pleasant as possible! - ## What Servarrs are supported? - ![radarr_logo](logos/radarr.png) [Radarr](https://wiki.servarr.com/radarr) @@ -40,6 +34,17 @@ Simply run the following command to start a demo: curl https://raw.githubusercontent.com/Dark-Alex-17/managarr-demo/main/managarr-demo.sh > /tmp/managarr-demo.sh && bash /tmp/managarr-demo.sh ``` +## Installation +### Cargo +If you have Cargo installed, then you can install Managarr from Crates.io: + +```shell +cargo install managarr + +# If you encounter issues installing, try installing with '--locked' +cargo install --locked managarr +``` + ## Features ### Radarr @@ -218,6 +223,10 @@ tautulli: api_token: someApiToken1234567890 ``` +## Track My Progress for the Beta release (With Sonarr Support!) +Progress for the beta release can be followed on my [Wekan Board](https://wekan.alexjclarke.com/b/dHoGjBb44MHM9HSv4/managarr) +with all items tagged `Beta`. + ## Screenshots ![library](screenshots/library.png) diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..2cdfc49 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,14 @@ +# Security Policy + +## Supported Versions + +Only latest version of the software will be supported with security patches. + +| Version | Supported | +| -------- | ------------------ | +| latest | :white_check_mark: | + +## Reporting a Vulnerability + +If you find a vulnerability, please reach out to me via email (alex.j.tusa@gmail.com). +If you yourself decide you'd like to tackle a fix, please submit a PR with the fix and I'll review it as soon as possible. diff --git a/src/ui/widgets/input_box.rs b/src/ui/widgets/input_box.rs index e0048c3..a9e87a9 100644 --- a/src/ui/widgets/input_box.rs +++ b/src/ui/widgets/input_box.rs @@ -24,7 +24,7 @@ pub struct InputBox<'a> { } impl<'a> InputBox<'a> { - pub fn new(content: &'a str) -> InputBox<'_> { + pub fn new(content: &'a str) -> InputBox<'a> { InputBox { content, offset: 0, diff --git a/src/utils.rs b/src/utils.rs index 6e046c2..ac37626 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,3 +1,6 @@ +use std::fs; +use std::path::PathBuf; + use log::LevelFilter; use log4rs::append::file::FileAppender; use log4rs::config::{Appender, Root}; @@ -7,13 +10,32 @@ use log4rs::encode::pattern::PatternEncoder; #[path = "utils_tests.rs"] mod utils_tests; +pub fn get_log_path() -> PathBuf { + let mut log_path = if cfg!(target_os = "linux") { + dirs_next::cache_dir().unwrap_or_else(|| PathBuf::from("~/.cache")) + } else if cfg!(target_os = "macos") { + dirs_next::home_dir().unwrap().join("Library/Logs") + } else { + dirs_next::data_local_dir().unwrap_or_else(|| PathBuf::from("C:\\Logs")) + }; + + log_path.push("managarr"); + + // Create the directory if it doesn't exist + if let Err(e) = fs::create_dir_all(&log_path) { + eprintln!("Failed to create log directory: {:?}", e); + } + + log_path.push("managarr.log"); + log_path +} + pub fn init_logging_config() -> log4rs::Config { - let file_path = "/tmp/managarr.log"; let logfile = FileAppender::builder() .encoder(Box::new(PatternEncoder::new( "{d(%Y-%m-%d %H:%M:%S%.3f)(utc)} <{i}> [{l}] {f}:{L} - {m}{n}", ))) - .build(file_path) + .build(get_log_path()) .unwrap(); log4rs::Config::builder()