{"id":13611770,"url":"https://github.com/mgrachev/update-informer","last_synced_at":"2025-05-15T00:10:36.171Z","repository":{"id":36978946,"uuid":"436298295","full_name":"mgrachev/update-informer","owner":"mgrachev","description":"Update informer for CLI/GUI applications written in Rust 🦀","archived":false,"fork":false,"pushed_at":"2025-03-31T10:58:21.000Z","size":357,"stargazers_count":216,"open_issues_count":2,"forks_count":9,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-06T17:08:00.103Z","etag":null,"topics":["contributor-friendly","contributors-welcome","hacktoberfest","rust","rust-lang","rust-library","update-checker","update-notifier"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mgrachev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"open_collective":"update-informer"}},"created_at":"2021-12-08T15:31:45.000Z","updated_at":"2025-03-31T10:58:25.000Z","dependencies_parsed_at":"2023-11-11T22:02:17.219Z","dependency_job_id":"dcc9b80f-066b-4e71-96fd-37a80d225877","html_url":"https://github.com/mgrachev/update-informer","commit_stats":{"total_commits":125,"total_committers":8,"mean_commits":15.625,"dds":0.528,"last_synced_commit":"d4b3158d9844809b156794c1b3802bd1a6123fdd"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgrachev%2Fupdate-informer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgrachev%2Fupdate-informer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgrachev%2Fupdate-informer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgrachev%2Fupdate-informer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mgrachev","download_url":"https://codeload.github.com/mgrachev/update-informer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248703819,"owners_count":21148229,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["contributor-friendly","contributors-welcome","hacktoberfest","rust","rust-lang","rust-library","update-checker","update-notifier"],"created_at":"2024-08-01T19:02:06.044Z","updated_at":"2025-04-13T20:41:51.115Z","avatar_url":"https://github.com/mgrachev.png","language":"Rust","readme":"# Update-informer\n\n[ci-badge]: https://github.com/mgrachev/update-informer/workflows/CI/badge.svg\n[ci-url]: https://github.com/mgrachev/update-informer/actions\n[crates-badge]: https://img.shields.io/crates/v/update-informer\n[crates-url]: https://crates.io/crates/update-informer\n[docs-badge]: https://img.shields.io/docsrs/update-informer\n[docs-url]: https://docs.rs/update-informer\n[codecov-badge]: https://codecov.io/gh/mgrachev/update-informer/branch/main/graph/badge.svg?token=A4XD1DGFGJ\n[codecov-url]: https://codecov.io/gh/mgrachev/update-informer\n[downloads-badge]: https://img.shields.io/crates/d/update-informer\n[etcetera]: https://github.com/lunacookies/etcetera\n[ureq]: https://github.com/algesten/ureq\n[semver]: https://github.com/dtolnay/semver\n[serde]: https://github.com/serde-rs/serde\n[GitHub CLI application]: https://github.com/cli/cli/blob/trunk/internal/update/update.go\n[npm]: https://github.com/npm/cli/blob/latest/lib/cli/update-notifier.js\n[JavaScript library]: https://github.com/yeoman/update-notifier\n[MIT]: https://choosealicense.com/licenses/mit\n[git-cliff]: https://github.com/orhun/git-cliff\n[dotenv-linter]: https://github.com/dotenv-linter/dotenv-linter\n[update-informer]: https://evrone.com/update-informer?utm_source=github\u0026utm_campaign=update-informer\n[Evrone]: https://evrone.com/?utm_source=github\u0026utm_campaign=update-informer\n[turbo]: https://github.com/vercel/turbo\n[fselect]: https://github.com/jhspetersson/fselect\n[fzf-make]: https://github.com/kyu08/fzf-make\n[reqwest]: https://github.com/seanmonstar/reqwest\n[isahc]: https://github.com/sagebind/isahc\n[here]: https://github.com/mgrachev/update-informer/tree/main/examples\n[nushell]: https://github.com/nushell/nushell\n\n[![CI][ci-badge]][ci-url]\n[![Version][crates-badge]][crates-url]\n[![Docs.rs][docs-badge]][docs-url]\n[![Codecov][codecov-badge]][codecov-url]\n[![Downloads][downloads-badge]][crates-url]\n\n\u003cimg align=\"right\"\nalt=\"update-informer\"\nsrc=\"https://raw.githubusercontent.com/mgrachev/update-informer/main/logo.svg?sanitize=true\"\u003e\n\nUpdate informer for applications written in Rust 🦀\n\nIt checks for a new version on Crates.io, GitHub, Npm and PyPI. 🚀\n\n## Benefits\n\n- Support of **Crates.io**, **GitHub**, **Npm** and **PyPI**.\n- Configurable [check frequency](#interval) and [request timeout](#request-timeout).\n- [Caching](#caching) the results of checking updates.\n- Ability to implement your own [registry](#implementing-your-own-registry)\n  or [http client](#using-your-own-http-client).\n- **Minimum dependencies** - only [etcetera], [semver], [serde] and an HTTP client ([ureq] or [reqwest]).\n\n## Idea\n\nThe idea is actually not new. This feature has long been present in the [GitHub CLI application] and [npm].\u003cbr\u003e\nThere is also a popular [JavaScript library].\n\n## Usage\n\nAdd `update-informer` to `Cargo.toml`:\n\n```toml\n[dependencies]\nupdate-informer = \"1.1\"\n```\n\nBy default, `update-informer` can only check on Crates.io and uses [ureq] as a default HTTP client.\nTo enable support for other registries or change the HTTP client, use `features`:\n\n```toml\n[dependencies]\nupdate-informer = { version = \"1.1\", default-features = false, features = [\"github\", \"reqwest\", \"native-tls\"] }\n```\n\nAvailable features:\n\n| Name       | Type                | Default? |\n| ---------- | ------------------- | -------- |\n| crates     | Registry            | Yes      |\n| github     | Registry            | No       |\n| npm        | Registry            | No       |\n| pypi       | Registry            | No       |\n| [ureq]     | HTTP client         | Yes      |\n| [reqwest]  | HTTP client         | No       |\n| rustls-tls | HTTP client feature | Yes      |\n| native-tls | HTTP client feature | No       |\n\n## Checking for a new version\n\nTo check for a new version, use the `UpdateInformer::check_version` function.\u003cbr\u003e\nThis function takes the project name and current version as well as registry:\n\n```rust\nuse update_informer::{registry, Check};\n\nlet name = env!(\"CARGO_PKG_NAME\");\nlet version = env!(\"CARGO_PKG_VERSION\");\nlet informer = update_informer::new(registry::Crates, name, version);\n\nif let Some(version) = informer.check_version().ok().flatten()  {\n    println!(\"New version is available: {}\", version);\n}\n```\n\nMore examples you can find [here].\n\n## Interval\n\nNote that the first check will start only after the interval has expired.\nBy default, the interval is **24 hours**, but you can change it:\n\n```rust\nuse std::time::Duration;\nuse update_informer::{registry, Check};\n\nconst EVERY_HOUR: Duration = Duration::from_secs(60 * 60);\n\nlet informer = update_informer::new(registry::Crates, \"crate_name\", \"0.1.0\").interval(EVERY_HOUR);\ninformer.check_version(); // The check will start only after an hour\n```\n\n## Caching\n\nBy default, `update-informer` creates a file in the cache directory to avoid spam requests to the registry API.\n\nIn order not to cache requests, use a zero interval:\n\n```rust\nuse std::time::Duration;\nuse update_informer::{registry, Check};\n\nlet informer = update_informer::new(registry::Crates, \"crate_name\", \"0.1.0\").interval(Duration::ZERO);\ninformer.check_version();\n```\n\n## Request timeout\n\nYou can also change the request timeout. By default, it is **5 seconds**:\n\n```rust\nuse std::time::Duration;\nuse update_informer::{registry, Check};\n\nconst THIRTY_SECONDS: Duration = Duration::from_secs(30);\n\nlet informer = update_informer::new(registry::Crates, \"crate_name\", \"0.1.0\").timeout(THIRTY_SECONDS);\ninformer.check_version();\n```\n\n## Implementing your own registry\n\nYou can implement your own registry to check updates. For example:\n\n```rust\nuse update_informer::{http_client::{GenericHttpClient, HttpClient}, registry, Check, Package, Registry, Result};\n\n#[derive(serde::Deserialize)]\nstruct Response {\n    version: String,\n}\n\nstruct YourOwnRegistry;\nimpl Registry for YourOwnRegistry {\n    const NAME: \u0026'static str = \"your_own_registry\";\n\n    fn get_latest_version\u003cT: HttpClient\u003e(http_client: GenericHttpClient\u003cT\u003e, pkg: \u0026Package) -\u003e Result\u003cOption\u003cString\u003e\u003e {\n        let url = \"https://turbo.build/api/binaries/version\";\n        let resp = http_client.get::\u003cResponse\u003e(\u0026url)?;\n\n        Ok(Some(resp.version))\n    }\n}\n\nlet informer = update_informer::new(YourOwnRegistry, \"turbo\", \"0.1.0\");\ninformer.check_version();\n```\n\n## Using your own HTTP client\n\nYou can use your own HTTP client to check updates. For example, [isahc]:\n\n```rust\nuse isahc::ReadResponseExt;\nuse std::time::Duration;\nuse serde::de::DeserializeOwned;\nuse update_informer::{http_client::{HeaderMap, HttpClient}, registry, Check};\n\nstruct YourOwnHttpClient;\n\nimpl HttpClient for YourOwnHttpClient {\n    fn get\u003cT: DeserializeOwned\u003e(\n        url: \u0026str,\n        _timeout: Duration,\n        _headers: HeaderMap,\n    ) -\u003e update_informer::Result\u003cT\u003e {\n        let json = isahc::get(url)?.json()?;\n        Ok(json)\n    }\n}\n\nlet informer = update_informer::new(registry::Crates, \"crate_name\", \"0.1.0\").http_client(YourOwnHttpClient);\ninformer.check_version();\n```\n\n## Tests\n\nIn order not to check for updates in tests, you can use the `FakeUpdateInformer::check_version` function, which returns\nthe desired version:\n\n```rust\nuse update_informer::{registry, Check};\n\nlet name = \"crate_name\";\nlet version = \"0.1.0\";\n\n#[cfg(not(test))]\nlet informer = update_informer::new(registry::Crates, name, version);\n\n#[cfg(test)]\nlet informer = update_informer::fake(registry::Crates, name, version, \"1.0.0\");\n\nif let Some(version) = informer.check_version().ok().flatten() {\n    println!(\"New version is available: {}\", version);\n}\n```\n\n## Integration tests\n\nTo use the `FakeUpdateInformer::check_version` function in integration tests, you must first add the feature flag to\n`Cargo.toml`:\n\n```toml\n[features]\nstub_check_version = []\n```\n\nThen use this feature flag in your code and integration tests:\n\n```rust\nuse update_informer::{registry, Check};\n\nlet name = \"crate_name\";\nlet version = \"0.1.0\";\n\n#[cfg(not(feature = \"stub_check_version\"))]\nlet informer = update_informer::new(registry::Crates, name, version);\n\n#[cfg(feature = \"stub_check_version\")]\nlet informer = update_informer::fake(registry::Crates, name, version, \"1.0.0\");\n\ninformer.check_version();\n```\n\n## Users\n\n- [git-cliff]\n- [dotenv-linter]\n- [turbo]\n- [fselect]\n- [fzf-make]\n- [nushell]\n\n## MSRV\n\nMinimum Supported Rust Version: 1.56.1\n\n## Sponsors\n\n[update-informer] is created \u0026 supported by [Evrone]\n\n## License\n\n[MIT]\n","funding_links":["https://opencollective.com/update-informer"],"categories":["库 Libraries","Libraries","Rust"],"sub_categories":["命令行 Command-line","Command-line"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmgrachev%2Fupdate-informer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmgrachev%2Fupdate-informer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmgrachev%2Fupdate-informer/lists"}