Giter VIP home page Giter VIP logo

self_update's Introduction

self_update

Build status Build Status crates.io:clin docs

self_update provides updaters for updating rust executables in-place from various release distribution backends.

Usage

Update (replace) the current executable with the latest release downloaded from https://api.github.com/repos/jaemk/self_update/releases/latest. Note, the trust project provides a nice setup for producing release-builds via CI (travis/appveyor).

Features

The following cargo features are available (but disabled by default):

  • archive-tar: Support for tar archive format;
  • archive-zip: Support for zip archive format;
  • compression-flate2: Support for gzip compression;
  • compression-zip-deflate: Support for zip's deflate compression format;
  • compression-zip-bzip2: Support for zip's bzip2 compression format;
  • rustls: Use pure rust TLS implementation for network requests. This feature does not support 32bit macOS;
  • signatures: Use zipsign to verify .zip and .tar.gz artifacts. Artifacts are assumed to have been signed using zipsign.

Please activate the feature(s) needed by your release files.

Example

Run the following example to see self_update in action:

cargo run --example github --features "archive-tar archive-zip compression-flate2 compression-zip-deflate".

There's also an equivalent example for gitlab:

cargo run --example gitlab --features "archive-tar archive-zip compression-flate2 compression-zip-deflate".

which runs something roughly equivalent to:

use self_update::cargo_crate_version;

fn update() -> Result<(), Box<::std::error::Error>> {
    let status = self_update::backends::github::Update::configure()
        .repo_owner("jaemk")
        .repo_name("self_update")
        .bin_name("github")
        .show_download_progress(true)
        .current_version(cargo_crate_version!())
        .build()?
        .update()?;
    println!("Update status: `{}`!", status.version());
    Ok(())
}

Amazon S3, Google GCS, and DigitalOcean Spaces are also supported through the S3 backend to check for new releases. Provided a bucket_name and asset_prefix string, self_update will look up all matching files using the following format as a convention for the filenames: [directory/]<asset name>-<semver>-<platform/target>.<extension>. Leading directories will be stripped from the file name allowing the use of subdirectories in the S3 bucket, and any file not matching the format, or not matching the provided prefix string, will be ignored.

use self_update::cargo_crate_version;

fn update() -> Result<(), Box<::std::error::Error>> {
    let status = self_update::backends::s3::Update::configure()
        .bucket_name("self_update_releases")
        .asset_prefix("something/self_update")
        .region("eu-west-2")
        .bin_name("self_update_example")
        .show_download_progress(true)
        .current_version(cargo_crate_version!())
        .build()?
        .update()?;
    println!("S3 Update status: `{}`!", status.version());
    Ok(())
}

Separate utilities are also exposed (NOTE: the following example requires the archive-tar feature, see the features section above). The self_replace crate is re-exported for convenience:

fn update() -> Result<(), Box<::std::error::Error>> {
    let releases = self_update::backends::github::ReleaseList::configure()
        .repo_owner("jaemk")
        .repo_name("self_update")
        .build()?
        .fetch()?;
    println!("found releases:");
    println!("{:#?}\n", releases);

    // get the first available release
    let asset = releases[0]
        .asset_for(&self_update::get_target()).unwrap();

    let tmp_dir = tempfile::Builder::new()
            .prefix("self_update")
            .tempdir_in(::std::env::current_dir()?)?;
    let tmp_tarball_path = tmp_dir.path().join(&asset.name);
    let tmp_tarball = ::std::fs::File::open(&tmp_tarball_path)?;

    self_update::Download::from_url(&asset.download_url)
        .set_header(reqwest::header::ACCEPT, "application/octet-stream".parse()?)
        .download_to(&tmp_tarball)?;

    let bin_name = std::path::PathBuf::from("self_update_bin");
    self_update::Extract::from_source(&tmp_tarball_path)
        .archive(self_update::ArchiveKind::Tar(Some(self_update::Compression::Gz)))
        .extract_file(&tmp_dir.path(), &bin_name)?;

    let new_exe = tmp_dir.path().join(bin_name);
    self_replace::self_replace(new_exe)?;

    Ok(())
}

License: MIT

self_update's People

Contributors

alpire avatar bleikurr avatar bochaco avatar d-corler avatar dervexdev avatar eindiran avatar jacobkiers avatar jaemk avatar johnathanfl avatar joshuef avatar jqnatividad avatar kijewski avatar logaritmisk avatar my4ng avatar nbigaouette avatar niklasf avatar oeb25 avatar r-darwish avatar roger avatar ryankurte avatar t-mw avatar terakomarigandesblood avatar zeenix avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

self_update's Issues

Support pre-release versions

Hey! It looks like the following use case is not supported yet.

Let's say I have such versions in s3 bucket:

  • 0.1.1
  • 0.1.2-beta

And in Cargo.toml I have version = "0.1.2-beta". When trying to perform self-update, I get roughly this output in stdout:

New release found! v0.1.2-beta --> v0.1.2
New release is *NOT* compatible

mybin release status:
  * Current exe: "/usr/bin/mybin"
  * New exe release: "mybin-0.1.2-beta-x86_64-unknown-linux-gnu"
  * New exe download url: "https://<s3>/mybin-0.1.2-beta-x86_64-unknown-linux-gnu"

But expected behaviour is that self_update understands that binary is already up-to-date. Notice this line:

New release found! v0.1.2-beta --> v0.1.2

Obviously it counts mybin-0.1.2-beta-x86_64-unknown-linux-gnu as v0.1.2 and not as v0.1.2-beta. Probably the issue here is that it is hard to tell when pre-release version ends and when triple starts.

Pre-release versions definition: https://semver.org/#spec-item-9

Feature request: Opt-in survey capability

It'd be nice if whenever self-update runs, for it to optionally collect some statistics with the user's opt-in, and return the survey data to the developer.

Some information that can possibly be collected by the survey:

  • hardware info (platform, number of CPUs, memory available, etc.)
  • IP address (so developer can geocode where his/her users are)
  • what version they are on, and if they upgraded

and perhaps, the survey can be collected using the Google Forms API - with some prior setup of course...

Gitlab Support?

I'd love to use this with Gitlab. How difficult would it be to support a new backend? Would you be interested in a contribution for this feature?

Not usable from async contexts

Hey. Was trying to use the new version to get unified reqwest 0.10 everywhere to move to async / remove dependency tree. But it seems that the blocking client interacts badly with async atm.

cargo toml:

self_update = { version = "0.13.0", features = ["archive-tar"] }
tokio = { version = "0.2.11", features = ["full"] }
reqwest = "0.10.1"

and all I have is a #[tokio::main] that a few functions down ends up calling a list on self_update::backends::github. But because, the reqwest::blocking::Client seems to spawn another tokio runtime, this just causes a panic immediately.

thread 'main' panicked at 'Cannot start a runtime from within a runtime. This happens because a function (like block_on) attempted to block the current thread while the thread is being used to drive asynchronous tasks.

Full stacktrace

thread 'main' panicked at 'Cannot start a runtime from within a runtime. This happens because a function (like `block_on`) attempted to block the current thread while the thread is being used to drive asynchronous tasks.', /home/clux/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.11/src/runtime/enter.rs:19:5
stack backtrace:
   0:     0x558ad554e274 - backtrace::backtrace::libunwind::trace::heb43798aede8bd30
                               at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
   1:     0x558ad554e274 - backtrace::backtrace::trace_unsynchronized::had2ba7dec4bd2732
                               at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
   2:     0x558ad554e274 - std::sys_common::backtrace::_print_fmt::hda61f46e822731b2
                               at src/libstd/sys_common/backtrace.rs:84
   3:     0x558ad554e274 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hfe37fa5de6572965
                               at src/libstd/sys_common/backtrace.rs:61
   4:     0x558ad5577bac - core::fmt::write::h74887d18db27282c
                               at src/libcore/fmt/mod.rs:1025
   5:     0x558ad55482c7 - std::io::Write::write_fmt::h6808f3d5eceed5e5
                               at src/libstd/io/mod.rs:1426
   6:     0x558ad5550b9e - std::sys_common::backtrace::_print::hcc0fd4b3552039ef
                               at src/libstd/sys_common/backtrace.rs:65
   7:     0x558ad5550b9e - std::sys_common::backtrace::print::h1c9c5c1c0505592d
                               at src/libstd/sys_common/backtrace.rs:50
   8:     0x558ad5550b9e - std::panicking::default_hook::{{closure}}::hefb6085c1ab83a59
                               at src/libstd/panicking.rs:193
   9:     0x558ad5550891 - std::panicking::default_hook::h1b037d2bf0657ab3
                               at src/libstd/panicking.rs:210
  10:     0x558ad555127b - std::panicking::rust_panic_with_hook::h787d7f532b084b9a
                               at src/libstd/panicking.rs:471
  11:     0x558ad4ffbe27 - std::panicking::begin_panic::hf6f80a6760574375
                               at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/panicking.rs:404
  12:     0x558ad4f934dc - tokio::runtime::enter::enter::he9051ec054dcfd32
                               at /home/clux/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.11/src/runtime/enter.rs:19
  13:     0x558ad4fd7ba0 - tokio::runtime::blocking::shutdown::Receiver::wait::h54c85b384d7234d9
                               at /home/clux/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.11/src/runtime/blocking/shutdown.rs:38
  14:     0x558ad4fc372e - <tokio::runtime::blocking::pool::BlockingPool as core::ops::drop::Drop>::drop::h55575462e28eec56
                               at /home/clux/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.11/src/runtime/blocking/pool.rs:116
  15:     0x558ad4925775 - core::ptr::real_drop_in_place::hb5c4378272efde28
                               at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/ptr/mod.rs:182
  16:     0x558ad491eace - core::ptr::real_drop_in_place::h64fb5188d56aaa9b
                               at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/ptr/mod.rs:182
  17:     0x558ad4947df2 - reqwest::blocking::wait::enter::he8252476c7f2eab0
                               at /home/clux/.cargo/registry/src/github.com-1ecc6299db9ec823/reqwest-0.10.1/src/blocking/wait.rs:73
  18:     0x558ad4945fc3 - reqwest::blocking::wait::timeout::hd66cb015ab680631
                               at /home/clux/.cargo/registry/src/github.com-1ecc6299db9ec823/reqwest-0.10.1/src/blocking/wait.rs:14
  19:     0x558ad490c931 - reqwest::blocking::client::ClientHandle::new::hc530c9153f53fbba
                               at /home/clux/.cargo/registry/src/github.com-1ecc6299db9ec823/reqwest-0.10.1/src/blocking/client.rs:662
  20:     0x558ad490bacd - reqwest::blocking::client::ClientBuilder::build::h99c2ec740eba3deb
                               at /home/clux/.cargo/registry/src/github.com-1ecc6299db9ec823/reqwest-0.10.1/src/blocking/client.rs:84
  21:     0x558ad490bb81 - reqwest::blocking::client::Client::new::h49294ac019aa5ac2
                               at /home/clux/.cargo/registry/src/github.com-1ecc6299db9ec823/reqwest-0.10.1/src/blocking/client.rs:469
  22:     0x558ad4375159 - self_update::backends::github::ReleaseList::fetch_releases::h79a06c8acc8f29c0
                               at /home/clux/.cargo/registry/src/github.com-1ecc6299db9ec823/self_update-0.13.0/src/backends/github.rs:159
  23:     0x558ad4374c8f - self_update::backends::github::ReleaseList::fetch::h023cf19d2b8b81c5
                               at /home/clux/.cargo/registry/src/github.com-1ecc6299db9ec823/self_update-0.13.0/src/backends/github.rs:147
  24:     0x558ad3b003aa - shipcat::upgrade::self_upgrade::{{closure}}::h569e7958857a5dfa
                               at /home/clux/babylon/shipcat/shipcat_cli/src/upgrade.rs:77
  25:     0x558ad39ddda8 - <std::future::GenFuture<T> as core::future::future::Future>::poll::h4a29021de0d7d754
                               at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/future.rs:43
  26:     0x558ad39d277a - std::future::poll_with_tls_context::ha5c63dde9323fd1b
                               at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/future.rs:99
  27:     0x558ad3e16b3c - shipcat::dispatch_commands::{{closure}}::h862ab6e248aeebaa
                               at shipcat_cli/src/main.rs:539
  28:     0x558ad39e84a8 - <std::future::GenFuture<T> as core::future::future::Future>::poll::hc741103e33926ebc
                               at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/future.rs:43
  29:     0x558ad39d424a - std::future::poll_with_tls_context::hd217b7e226c0c204
                               at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/future.rs:99
  30:     0x558ad3e11900 - shipcat::run::{{closure}}::h87e0a48886cfe2b5
                               at shipcat_cli/src/main.rs:452
  31:     0x558ad39ea3b8 - <std::future::GenFuture<T> as core::future::future::Future>::poll::hda07fe0bc63b7548
                               at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/future.rs:43
  32:     0x558ad39d03ba - std::future::poll_with_tls_context::h5b5e4f50e0a8939f
                               at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/future.rs:99
  33:     0x558ad3e3e3ed - shipcat::main::{{closure}}::h4c8d52216421cce2
                               at shipcat_cli/src/main.rs:424
  34:     0x558ad39da2ca - <std::future::GenFuture<T> as core::future::future::Future>::poll::h1012b2e438abfda9
                               at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/future.rs:43
  35:     0x558ad3f038cc - tokio::runtime::enter::Enter::block_on::h3e95c77d786ac59d
                               at /home/clux/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.11/src/runtime/enter.rs:100
  36:     0x558ad3f1246d - tokio::runtime::thread_pool::ThreadPool::block_on::h2968698c19f0e6e8
                               at /home/clux/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.11/src/runtime/thread_pool/mod.rs:93
  37:     0x558ad3d3d5bb - tokio::runtime::Runtime::block_on::{{closure}}::hc1778ae61d231d7a
                               at /home/clux/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.11/src/runtime/mod.rs:413
  38:     0x558ad397d22d - tokio::runtime::context::enter::hbbd214dda6ef5038
                               at /home/clux/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.11/src/runtime/context.rs:72
  39:     0x558ad3c19ba6 - tokio::runtime::handle::Handle::enter::he374b51860c2d132
                               at /home/clux/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.11/src/runtime/handle.rs:34
  40:     0x558ad3d3d466 - tokio::runtime::Runtime::block_on::hefb5182b24fe2948
                               at /home/clux/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.11/src/runtime/mod.rs:408
  41:     0x558ad3de31d9 - shipcat::main::h18a1b3b861809cb8
                               at shipcat_cli/src/main.rs:411
  42:     0x558ad3931300 - std::rt::lang_start::{{closure}}::h1b2325711f7f7adb
                               at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/rt.rs:67
  43:     0x558ad5550cc3 - std::rt::lang_start_internal::{{closure}}::h0760fb8bd9f1a4c7
                               at src/libstd/rt.rs:52
  44:     0x558ad5550cc3 - std::panicking::try::do_call::hccaa7cebf2335ab2
                               at src/libstd/panicking.rs:292
  45:     0x558ad555afba - __rust_maybe_catch_panic
                               at src/libpanic_unwind/lib.rs:78
  46:     0x558ad55517d0 - std::panicking::try::h3ce8e2e4440720f0
                               at src/libstd/panicking.rs:270
  47:     0x558ad55517d0 - std::panic::catch_unwind::h2a767bac361346af
                               at src/libstd/panic.rs:394
  48:     0x558ad55517d0 - std::rt::lang_start_internal::h14e7168ba039f170
                               at src/libstd/rt.rs:51
  49:     0x558ad39312d9 - std::rt::lang_start::ha64f6a4661cac25b
                               at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/rt.rs:67
  50:     0x558ad3de325a - main
  51:     0x7f12ed642153 - __libc_start_main
  52:     0x558ad39311be - _start
  53:                0x0 - <unknown>

Certificate verifye failed

Hello, I am trying to use self_update but when I run my application it returns the following ssl error:

cloudstate --upgrade
Checking target-arch... x86_64-unknown-linux-gnu
Checking current version... v0.2.5
Checking latest released version... thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Reqwest(Error(Hyper(Error(Connect, Custom { kind: Other, error: Ssl(Error { code: ErrorCode(1), cause: Some(Ssl(ErrorStack([Error { code: 336134278, library: "SSL routines", function: "ssl3_get_server_certificate", reason: "certificate verify failed", file: "s3_clnt.c", line: 1264 }]))) }, X509VerifyResult { code: 20, error: "unable to get local issuer certificate" }) })), "https://api.github.com/repos/sleipnir/cloudstate-cli/releases/latest"))', src/libcore/result.rs:1165:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

My code:

pub fn upgrade() {
        let status = self_update::backends::github::Update::configure()
            .repo_owner("sleipnir")
            .repo_name("cloudstate-cli")
            .bin_name("cloudstate")
            .show_download_progress(true)
            .current_version(env!("CARGO_PKG_VERSION"))
            .build().unwrap()
            .update().unwrap();

        println!("Update status: `{}`!", status.version());
    }

Can you help me?

Update fails when current_exe's directory is not writable (even if current_exe is writable)

We're running into an issue where self update fails trying to write the tmp file in the std::env::current_exes directory. In our particular case, the std::env::current_exes directory is not writable, hence the failure. However, std::env::current_exe is writable, so it could in theory be updated.

It'd be nice if self_update could handle this case, perhaps by using /tmp if /tmp happens to be in the same filesystem as the binary being updated.

Related to #2

Support S3 dualstack

It would be nice to be able to use backend endpoints like s3.dualstack.us-west-2.amazonaws.com for IPv6 support.

Which option is best?

  • Do nothing. People can set region dualstack.us-west-2
  • Just use dualstack by default
  • Add new endpoint type to enum

Access S3 buckets

I cannot find if this is possible or not but I would like to access a bucket that is not globally exposed. Is this possible and if not can it be added as a feature request?

OS supported

Which OS does this library support? IIRC Windows doesn't allow replacing binaries at runtime because they get locked when a program uses them.

My wild guess would be that self_update doesn't support Windows.

Bump indicatif to 0.16.2

Currently, self_update uses indicatif 0.15.

As most CLI programs that use self_update also use indicatif, it'd be great if self_update also uses the latest indicatif release (currently 0.16.2).

Make release prefix configurable

Hi there! Thanks for writing self_update!

I'm playing around with it and I noticed that the release prefix is currently not configurable: https://docs.rs/self_update/0.27.0/src/self_update/backends/github.rs.html#55. Versions beginning with v are not valid semver, and using v is more of a convention than a hard rule. Other projects might use their own prefixes in their tag names (e.g. my-package-1.3.4, common in monorepo situations where multiple binaries are released), or no prefix at all (e.g. 1.3.4).

Moreover, if tag names begin with v but don't use the v1.3.4 naming scheme, they will have unexpected results. For example, if a tag is called very-cool-package-1.3.4, its version will be returned as ery-cool-package-1.3.4. This seems non-ideal.

My proposed solution would be to add a configuration, e.g. fn tag_prefix(&str). This can be "v" by default, but could also be set to "my-package-" or even "". You could then even filter out tags that don't match the prefix.

This would be a breaking change.

download/temp files location

std::fs::rename requires to and from to be on the same filesystem. Since the tempdir::TempDir::new crate uses std::env::temp_dir, the temp location may not be on the same filesystem as the executable. tempdir should be used within the std::env::current_exes directory.

GCS backend

Similarly to how DigitalOcean spaces was added, I'd be interested in a GCS backend as well. I can take a stab at it if you're interested. My main question is do you want a separate backend of should it be just a configuration of S3 backend like Spaces?

The GCS bucket list API is almost identical to S3. The main difference is that the URL does not have a region in it, so if I were to add it as another S3 backend, I'd have to make the region optional.

Is there a `.with_url()` method missing in `UpdateBuilder`?

I'm struggling to adapt the provided example for a GitHub Enterprise environment. There is a .with_url() method in ReleaseListBuilder to get a list of my releases but I don't see the corresponding method in UpdateBuilder to actually perform the update. Was this overlooked in #54?

I keep ending up with a 0 byte executable

I tried changing my main function from async to sync, I tried running as admin, running in a different folder, closing the app after updating, but every time, it looks to be correctly downloading a 13.2MB file from github, but then without warnings, it replaces my local exe with a 0 byte file that will never run.

Is there anything I can do to avoid this? I didn't see it mentioned in other issues. I'm on windows, and so is my ci runner.
image

Allow specifying the version to update to

the Builder object should have a method version that allows you to specify the version to update to.

Proposed API:

/// update to the specified version.
fn version(&mut self, version: Version)

Usecase: I want to add an update command to my application where the user can specify the version to update to.

This is also great for testing. It lets me test out upgrading and downgrading dynamically.

Use rustls for reqwest (default or provide feature flag)

I've a wee branch on the go, using rustls to avoid libssl issues on linux (which reqwest uses by default).

I'm not sure if it's desirable to use this as the default tls implementation for self_update (it mayyy be better than using openssl performance wise, or in terms of security...

Is there any desire for a PR to enable rustls via feature flag? Or even as default? Happy to update my branch and PR that if desirable ๐Ÿ‘

Thanks for all the work so far!

Add crate "features" to disable some parts?

I use self_update for one of my project (thanks!) with releases being uploaded to GitHub as zip files.

GitHub Actions has everything required to build the project, but I would like to make sure my project can be built directly by users without having to install anything else than rust, specially on Windows.

As such, I chose an archive format to use in my releases that I know has a 100% rust compression code. Unfortunately, because self_update depends on others, they are still pulled even though I don't need them.

The problem comes from Windows where self_update depends on zip:

zip = "0.5.0"

cargo-tree reveals the dependency tree:

> cargo tree
[...]
โ”œโ”€โ”€ self_update v0.11.1
[...]
โ”‚   โ””โ”€โ”€ zip v0.5.4
โ”‚       โ”œโ”€โ”€ bzip2 v0.3.3
โ”‚       โ”‚   โ”œโ”€โ”€ bzip2-sys v0.1.7
โ”‚       โ”‚   โ”‚   โ””โ”€โ”€ libc v0.2.66 (*)
โ”‚       โ”‚   โ”‚   [build-dependencies]
โ”‚       โ”‚   โ”‚   โ””โ”€โ”€ cc v1.0.50
โ”‚       โ”‚   โ””โ”€โ”€ libc v0.2.66 (*)
โ”‚       โ”œโ”€โ”€ crc32fast v1.2.0 (*)
โ”‚       โ”œโ”€โ”€ flate2 v1.0.13 (*)
โ”‚       โ”œโ”€โ”€ podio v0.1.6
โ”‚       โ””โ”€โ”€ time v0.1.42 (*)

Because zip depends on bzip2 and then bzip2-sys, cargo will attempt to build bzip2 on Windows. Because I don't have Visual Studio installed in my VM, I get the following error:

error: failed to run custom build command for `bzip2-sys v0.1.7`

Caused by:
  process didn't exit successfully: `C:\cargo_target\debug\build\bzip2-sys-85bed80a0555d110\build-script-build` (exit code: 1)
--- stdout
TARGET = Some("x86_64-pc-windows-gnu")
OPT_LEVEL = Some("0")
HOST = Some("x86_64-pc-windows-gnu")
CC_x86_64-pc-windows-gnu = None
CC_x86_64_pc_windows_gnu = None
HOST_CC = None
CC = None
CFLAGS_x86_64-pc-windows-gnu = None
CFLAGS_x86_64_pc_windows_gnu = None
HOST_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
DEBUG = Some("true")
CARGO_CFG_TARGET_FEATURE = Some("fxsr,sse,sse2")
running: "gcc.exe" "-O0" "-ffunction-sections" "-fdata-sections" "-g" "-fno-omit-frame-pointer" "-m64" "-I" "bzip2-1.0.6" "-D_WIN32" "-DBZ_EXPORT" "-D_FILE_OFFS
ET_BITS=64" "-DBZ_NO_STDIO" "-o" "C:\\cargo_target\\debug\\build\\bzip2-sys-a067f608dc4f1377\\out\\lib\\bzip2-1.0.6/blocksort.o" "-c" "bzip2-1.0.6/blocksort.c"

--- stderr


error occurred: Failed to find tool. Is `gcc.exe` installed? (see https://github.com/alexcrichton/cc-rs#compile-time-requirements for help)



warning: build failed, waiting for other jobs to finish...
error: build failed

which is unfortunate since I don't even use bzip2.

Looking at zip I see that it has some features:
https://github.com/mvdnes/zip-rs/blob/master/Cargo.toml#L27-L31

I was able to add a feature to self_update to disable zip's bzip2 feature and thus allow having a 100% rust compilation ๐ŸŽ‰ . See updated cargo tree:

> cargo tree
[...]
โ”‚   โ””โ”€โ”€ zip v0.5.4
โ”‚       โ”œโ”€โ”€ crc32fast v1.2.0 (*)
โ”‚       โ”œโ”€โ”€ flate2 v1.0.13 (*)
โ”‚       โ”œโ”€โ”€ podio v0.1.6
โ”‚       โ””โ”€โ”€ time v0.1.42 (*)

I think it could be interesting for others. It would reduce the amount of dependencies used and speed up compilation process.

Would you be interested in a PR?

Check for updates periodically

It would be nice if self_update incorporates an update check policy that works across platforms, where you can set a time interval between checks, so the next time the binary is run and the interval has passed, it will invoke the update automatically.

Required path update error

Hello, I tried to run this project but it throws this message after downloaded, either run as library for other packages.

Extracting archive... [Error] UpdateError: Could not find the required path in the archive: "github"

Can you determined the error so that I can help with a PR?

Update on windows produces error when exe is not on C drive

If you try to run self_update in a binary that is on a different drive to C:, std::fs::rename here will fail with the error: The system cannot move the file to a different disk drive. This is the same as the issue described here golang/go#13766, and it looks like a rename will never work across different drives on Windows. Since the temp directory that self_update downloads to is almost always located on the C: drive this is an issue for anyone who installs programs to other drives. I'll look at whether I can fix it by copying to the destination and deleting the source instead of renaming.

Regular https directory backend

Would it be possible to have a regular https directory backend with a json file describing the release? I think this would be more service-agnostic.

[ERROR] ReleaseError: No asset found for target: `x86_64-unknown-linux-gnu`

Hi

I am pretty new to rust, trying to learn more. This error smell like "nightly" component issue, right ?

[x220@ipa01 rustgb_self_update]$ cat /etc/redhat-release && cargo --version
Fedora release 32 (Thirty Two)
cargo 1.40.0 (bc8e4c8be 2019-11-22)
[x220@ipa01 rustgb_self_update]$
  • steps to re-produce issue.
[x220@ipa01 rustgb_self_update]$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.07s
     Running `target/debug/ghupdate01`
found releases:
[
    Release {
        name: "0.1",
        version: "0.1",
        date: "2020-06-13T16:53:28Z",
        body: Some(
            "Starting from 0.1",
        ),
        assets: [],
    },
]

Checking target-arch... x86_64-unknown-linux-gnu
Checking current version... v0.1.0
Looking for tag: 0.1
[ERROR] ReleaseError: No asset found for target: `x86_64-unknown-linux-gnu`
[x220@ipa01 rustgb_self_update]$ pwd
/home/x220/rustgb_self_update
[x220@ipa01 rustgb_self_update]$ cat src/gh-selfupdate.rs
/*!
Example updating an executable to the latest version released via GitHub
*/

// For the `cargo_crate_version!` macro
#[macro_use]
extern crate self_update;

fn run() -> Result<(), Box<dyn ::std::error::Error>> {
    let releases = self_update::backends::github::ReleaseList::configure()
        .repo_owner("tjyang")
        .repo_name("rustgb_self_update")
        .build()?
        .fetch()?;
    println!("found releases:");
    println!("{:#?}\n", releases);

    let status = self_update::backends::github::Update::configure()
        .repo_owner("tjyang")
        .repo_name("rustgb_self_update")
        .bin_name("ghupdate01")
        .show_download_progress(true)
        //.target_version_tag("v9.9.9")
        .target_version_tag("0.1")
        //.show_output(false)
        //.no_confirm(true)
        //
        // For private repos, you will need to provide a GitHub auth token
        // **Make sure not to bake the token into your app**; it is recommended
        // you obtain it via another mechanism, such as environment variables
        // or prompting the user for input
        //.auth_token(env!("DOWNLOAD_AUTH_TOKEN"))
        .current_version(cargo_crate_version!())
        .build()?
        .update()?;
    println!("Update status: `{}`!", status.version());
    Ok(())
}

pub fn main() {
    if let Err(e) = run() {
        println!("[ERROR] {}", e);
        ::std::process::exit(1);
    }
}
[x220@ipa01 rustgb_self_update]$

update release failed in github

I thought there will be a new release version or the old release version will be updated, but nothing changed in my repository "myrust" releases page.
I give all permission to this GitHub token.
I run the code success below.

image

image

DigitalOcean Spaces backend

This shouldn't be a lot of work, just some minor diffs to S3, I think? I can take a stab at it but would like to know if you'd want a separate backend of should it be just a configuration of S3 backend?

AWS S3 support

This is a proposal to support S3 as a backend in this crate. I'm working on a first implementation of such a backend and was wondering if this is something you'd agree to have and when ready release with self-update crate?

I'm doing this as part of task for some binaries where we use this crate from (I'm working on https://github.com/maidsafe project), and we publish some releases on S3, therefore I was planning to send it as a PR in the next few days if that's something you'll consider for this crate.

atomic file replacement

fix replace_exe to use atomic rename operations instead of copys and avoid removeing the running file.

Help understanding compatible bumps logic

Hi, I use this library to get releases from GitHub, and I noticed something I want to get clarity about. I have a new release 0.4.0, but it's being reported as "not compatible" with the current version of 0.3.0. I double checked this behavior with the following, but you basically already have this as a test case here.

# fails
assert_eq!(true, bump_is_compatible("0.3.0", "0.4.0").unwrap());

I see that the bump compatibility logic is this:

# current bump_is_compatible
if other.major == 0 && current.major == 0 {
    current.minor == other.minor && other.patch > current.patch
} else if other.major > 0 {
    current.major == other.major
        && ((other.minor > current.minor)
            || (current.minor == other.minor && other.patch > current.patch))
} else {
    false
}

This seems surprising, because it means only patch versions can be incremented in a 0.y.z version and still be treated as compatible. Is this intentional? I'd expect minor versions to be allowed to increment and be compatible even with 0.y.z versions, similar to how it is compatible in 1.y.z versions.

Eg, if the logic was changed to this (and the single 0.2.0 -> 0.3.0 test case changed), this would make sense to me:

# theoretical bump_is_compatible
Ok(current.major == other.major
        && ((other.minor > current.minor)
            || (current.minor == other.minor && other.patch > current.patch)))

Can you share more about why 0.y.z versions don't treat minor increments as compatible bumps?

[Github Backend] ReleaseAsset contains wrong url

It gives back the raw api link but not the actual download link.

Can be fixed by replacing url with browser_download_url in ReleaseAsset::from_asset like so:

impl ReleaseAsset {
    /// Parse a release-asset json object
    ///
    /// Errors:
    ///     * Missing required name & download-url keys
    fn from_asset(asset: &serde_json::Value) -> Result<ReleaseAsset> {
        let download_url = asset["browser_download_url"].as_str().ok_or_else(|| {
            format_err!(Error::Release, "Asset missing `browser_download_url`")
        })?;
        let name = asset["name"]
            .as_str()
            .ok_or_else(|| format_err!(Error::Release, "Asset missing `name`"))?;
        Ok(ReleaseAsset {
            download_url: download_url.to_owned(),
            name: name.to_owned(),
        })
    }
}

Allow installs without replacements

Allow installing a file without having to replace it first. bin_install_path is exposed in the github builder, but specifying a install path will currently cause an error since replace expects the file to already exist.

Using unmaintained crate hyper-old-types

The hyper-old-types crate is rather old by now and pulls in various old versions of other crates.

I'd recommend you either drop the usage of typed headers entirely (AFAICT the only use of hyper-old-types in this crate is two headers) or update the headers crate which is the continuation of hyper's previous typed-headers API to work for your needs (hyperium/headers#76).

Allow for usage for Enterprise Github

I'm looking to leverage this package for an internal app at my employer, but we're required to use an enterprise Github instance.

Right now, it looks like the Github backend is hardcoded to api.github.com.
I think it would be rather easy to have a method that allows overriding that value.
There are a few small URL differences in enterprise, but would you be open to this if I were to create a PR for it?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.