Skip to content

tempfile with permissions #1276

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 65 additions & 66 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ anyhow = "1.0.42"

gitoxide-core = { version = "^0.36.0", path = "gitoxide-core" }
gix-features = { version = "^0.38.0", path = "gix-features" }
gix = { version = "^0.58.0", path = "gix", default-features = false }
gix = { version = "^0.59.0", path = "gix", default-features = false }
time = "0.3.23"

clap = { version = "4.1.1", features = ["derive", "cargo"] }
Expand Down
6 changes: 3 additions & 3 deletions gitoxide-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ serde = ["gix/serde", "dep:serde_json", "dep:serde", "bytesize/serde"]

[dependencies]
# deselect everything else (like "performance") as this should be controllable by the parent application.
gix = { version = "^0.58.0", path = "../gix", default-features = false, features = ["blob-diff", "revision", "mailmap", "excludes", "attributes", "worktree-mutation", "credentials", "interrupt", "status"] }
gix-pack-for-configuration-only = { package = "gix-pack", version = "^0.47.0", path = "../gix-pack", default-features = false, features = ["pack-cache-lru-dynamic", "pack-cache-lru-static", "generate", "streaming-input"] }
gix = { version = "^0.59.0", path = "../gix", default-features = false, features = ["blob-diff", "revision", "mailmap", "excludes", "attributes", "worktree-mutation", "credentials", "interrupt", "status"] }
gix-pack-for-configuration-only = { package = "gix-pack", version = "^0.48.0", path = "../gix-pack", default-features = false, features = ["pack-cache-lru-dynamic", "pack-cache-lru-static", "generate", "streaming-input"] }
gix-transport-configuration-only = { package = "gix-transport", version = "^0.41.0", path = "../gix-transport", default-features = false }
gix-archive-for-configuration-only = { package = "gix-archive", version = "^0.9.0", path = "../gix-archive", optional = true, features = ["tar", "tar_gz"] }
gix-status = { version = "^0.5.0", path = "../gix-status" }
gix-status = { version = "^0.6.0", path = "../gix-status" }
gix-fsck = { version = "^0.3.0", path = "../gix-fsck" }
serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] }
anyhow = "1.0.42"
Expand Down
4 changes: 2 additions & 2 deletions gix-config/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "gix-config"
version = "0.34.0"
version = "0.35.0"
repository = "https://github.com/Byron/gitoxide"
description = "A git-config file parser and editor from the gitoxide project"
license = "MIT OR Apache-2.0"
Expand All @@ -21,7 +21,7 @@ gix-features = { version = "^0.38.0", path = "../gix-features"}
gix-config-value = { version = "^0.14.4", path = "../gix-config-value" }
gix-path = { version = "^0.10.5", path = "../gix-path" }
gix-sec = { version = "^0.10.4", path = "../gix-sec" }
gix-ref = { version = "^0.41.0", path = "../gix-ref" }
gix-ref = { version = "^0.42.0", path = "../gix-ref" }
gix-glob = { version = "^0.16.0", path = "../gix-glob" }

winnow = { version = "0.5.36", features = ["simd"] }
Expand Down
4 changes: 2 additions & 2 deletions gix-diff/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "gix-diff"
version = "0.40.0"
version = "0.41.0"
repository = "https://github.com/Byron/gitoxide"
license = "MIT OR Apache-2.0"
description = "Calculate differences between various git objects"
Expand All @@ -26,7 +26,7 @@ doctest = false
gix-hash = { version = "^0.14.1", path = "../gix-hash" }
gix-object = { version = "^0.41.0", path = "../gix-object" }
gix-filter = { version = "^0.9.0", path = "../gix-filter", optional = true }
gix-worktree = { version = "^0.30.0", path = "../gix-worktree", default-features = false, features = ["attributes"], optional = true }
gix-worktree = { version = "^0.31.0", path = "../gix-worktree", default-features = false, features = ["attributes"], optional = true }
gix-command = { version = "^0.3.4", path = "../gix-command", optional = true }
gix-path = { version = "^0.10.5", path = "../gix-path", optional = true }
gix-fs = { version = "^0.10.0", path = "../gix-fs", optional = true }
Expand Down
4 changes: 2 additions & 2 deletions gix-discover/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "gix-discover"
version = "0.29.0"
version = "0.30.0"
repository = "https://github.com/Byron/gitoxide"
license = "MIT OR Apache-2.0"
description = "Discover git repositories and check if a directory is a git repository"
Expand All @@ -15,7 +15,7 @@ doctest = false
[dependencies]
gix-sec = { version = "^0.10.4", path = "../gix-sec" }
gix-path = { version = "^0.10.5", path = "../gix-path" }
gix-ref = { version = "^0.41.0", path = "../gix-ref" }
gix-ref = { version = "^0.42.0", path = "../gix-ref" }
gix-hash = { version = "^0.14.1", path = "../gix-hash" }
gix-fs = { version = "^0.10.0", path = "../gix-fs" }

Expand Down
2 changes: 1 addition & 1 deletion gix-index/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "gix-index"
version = "0.29.0"
version = "0.30.0"
repository = "https://github.com/Byron/gitoxide"
license = "MIT OR Apache-2.0"
description = "A work-in-progress crate of the gitoxide project dedicated implementing the git index file"
Expand Down
36 changes: 35 additions & 1 deletion gix-lock/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,39 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 13.1.0 (2024-02-06)

### New Features

- <csr-id-719fc81fa72756faa13fc3f8d4759df5d40cebd0/> add `*_with_permissions(..., permissions)` methods.
That way it's possible to create lock files with non-default permissions
as well.

### Bug Fixes

- <csr-id-d83e45de625587b7b11e376a4d608854027a723e/> when obtaining locks, use mode 666 on Linux by default.
Doing so helps with using `sudo` and others.

### Commit Statistics

<csr-read-only-do-not-edit/>

- 2 commits contributed to the release.
- 17 days passed between releases.
- 2 commits were understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages

### Commit Details

<csr-read-only-do-not-edit/>

<details><summary>view details</summary>

* **Uncategorized**
- Add `*_with_permissions(..., permissions)` methods. ([`719fc81`](https://github.com/Byron/gitoxide/commit/719fc81fa72756faa13fc3f8d4759df5d40cebd0))
- When obtaining locks, use mode 666 on Linux by default. ([`d83e45d`](https://github.com/Byron/gitoxide/commit/d83e45de625587b7b11e376a4d608854027a723e))
</details>

## 13.0.0 (2024-01-20)

A maintenance release without user-facing changes.
Expand All @@ -13,7 +46,7 @@ A maintenance release without user-facing changes.

<csr-read-only-do-not-edit/>

- 1 commit contributed to the release.
- 2 commits contributed to the release.
- 20 days passed between releases.
- 0 commits were understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
Expand All @@ -25,6 +58,7 @@ A maintenance release without user-facing changes.
<details><summary>view details</summary>

* **Uncategorized**
- Release gix-utils v0.1.9, gix-features v0.38.0, gix-actor v0.30.0, gix-object v0.41.0, gix-path v0.10.4, gix-glob v0.16.0, gix-attributes v0.22.0, gix-command v0.3.3, gix-packetline-blocking v0.17.3, gix-filter v0.9.0, gix-fs v0.10.0, gix-commitgraph v0.24.0, gix-revwalk v0.12.0, gix-traverse v0.37.0, gix-worktree-stream v0.9.0, gix-archive v0.9.0, gix-config-value v0.14.4, gix-tempfile v13.0.0, gix-lock v13.0.0, gix-ref v0.41.0, gix-sec v0.10.4, gix-config v0.34.0, gix-url v0.27.0, gix-credentials v0.24.0, gix-ignore v0.11.0, gix-index v0.29.0, gix-worktree v0.30.0, gix-diff v0.40.0, gix-discover v0.29.0, gix-mailmap v0.22.0, gix-negotiate v0.12.0, gix-pack v0.47.0, gix-odb v0.57.0, gix-pathspec v0.6.0, gix-packetline v0.17.3, gix-transport v0.41.0, gix-protocol v0.44.0, gix-revision v0.26.0, gix-refspec v0.22.0, gix-status v0.5.0, gix-submodule v0.8.0, gix-worktree-state v0.7.0, gix v0.58.0, safety bump 39 crates ([`eb6aa8f`](https://github.com/Byron/gitoxide/commit/eb6aa8f502314f886fc4ea3d52ab220763968208))
- Prepare changelogs prior to release ([`6a2e0be`](https://github.com/Byron/gitoxide/commit/6a2e0bebfdf012dc2ed0ff2604086081f2a0f96d))
</details>

Expand Down
2 changes: 1 addition & 1 deletion gix-lock/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "gix-lock"
version = "13.0.0"
version = "13.1.0"
repository = "https://github.com/Byron/gitoxide"
license = "MIT OR Apache-2.0"
description = "A git-style lock-file implementation"
Expand Down
63 changes: 60 additions & 3 deletions gix-lock/src/acquire.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ impl File {
/// If `boundary_directory` is given, non-existing directories will be created automatically and removed in the case of
/// a rollback. Otherwise the containing directory is expected to exist, even though the resource doesn't have to.
///
/// Note that permissions will be set to `0o666`, which usually results in `0o644` after passing a default umask, on Unix systems.
///
/// ### Warning of potential resource leak
///
/// Please note that the underlying file will remain if destructors don't run, as is the case when interrupting the application.
Expand All @@ -71,7 +73,27 @@ impl File {
boundary_directory: Option<PathBuf>,
) -> Result<File, Error> {
let (lock_path, handle) = lock_with_mode(at_path.as_ref(), mode, boundary_directory, &|p, d, c| {
gix_tempfile::writable_at(p, d, c)
if let Some(permissions) = default_permissions() {
gix_tempfile::writable_at_with_permissions(p, d, c, permissions)
} else {
gix_tempfile::writable_at(p, d, c)
}
})?;
Ok(File {
inner: handle,
lock_path,
})
}

/// Like [`acquire_to_update_resource()`](File::acquire_to_update_resource), but allows to set filesystem permissions using `make_permissions`.
pub fn acquire_to_update_resource_with_permissions(
at_path: impl AsRef<Path>,
mode: Fail,
boundary_directory: Option<PathBuf>,
make_permissions: impl Fn() -> std::fs::Permissions,
) -> Result<File, Error> {
let (lock_path, handle) = lock_with_mode(at_path.as_ref(), mode, boundary_directory, &|p, d, c| {
gix_tempfile::writable_at_with_permissions(p, d, c, make_permissions())
})?;
Ok(File {
inner: handle,
Expand All @@ -81,12 +103,14 @@ impl File {
}

impl Marker {
/// Like [`acquire_to_update_resource()`][File::acquire_to_update_resource()] but _without_ the possibility to make changes
/// Like [`acquire_to_update_resource()`](File::acquire_to_update_resource()) but _without_ the possibility to make changes
/// and commit them.
///
/// If `boundary_directory` is given, non-existing directories will be created automatically and removed in the case of
/// a rollback.
///
/// Note that permissions will be set to `0o666`, which usually results in `0o644` after passing a default umask, on Unix systems.
///
/// ### Warning of potential resource leak
///
/// Please note that the underlying file will remain if destructors don't run, as is the case when interrupting the application.
Expand All @@ -98,7 +122,28 @@ impl Marker {
boundary_directory: Option<PathBuf>,
) -> Result<Marker, Error> {
let (lock_path, handle) = lock_with_mode(at_path.as_ref(), mode, boundary_directory, &|p, d, c| {
gix_tempfile::mark_at(p, d, c)
if let Some(permissions) = default_permissions() {
gix_tempfile::mark_at_with_permissions(p, d, c, permissions)
} else {
gix_tempfile::mark_at(p, d, c)
}
})?;
Ok(Marker {
created_from_file: false,
inner: handle,
lock_path,
})
}

/// Like [`acquire_to_hold_resource()`](Marker::acquire_to_hold_resource), but allows to set filesystem permissions using `make_permissions`.
pub fn acquire_to_hold_resource_with_permissions(
at_path: impl AsRef<Path>,
mode: Fail,
boundary_directory: Option<PathBuf>,
make_permissions: impl Fn() -> std::fs::Permissions,
) -> Result<Marker, Error> {
let (lock_path, handle) = lock_with_mode(at_path.as_ref(), mode, boundary_directory, &|p, d, c| {
gix_tempfile::mark_at_with_permissions(p, d, c, make_permissions())
})?;
Ok(Marker {
created_from_file: false,
Expand Down Expand Up @@ -169,6 +214,18 @@ fn add_lock_suffix(resource_path: &Path) -> PathBuf {
))
}

fn default_permissions() -> Option<std::fs::Permissions> {
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
Some(std::fs::Permissions::from_mode(0o666))
}
#[cfg(not(unix))]
{
None
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
10 changes: 10 additions & 0 deletions gix-lock/tests/lock/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,16 @@ mod acquire {
assert_eq!(file.lock_path(), resource_lock);
assert_eq!(file.resource_path(), resource);
assert!(resource_lock.is_file());
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let perms = resource_lock.metadata()?.permissions();
assert_ne!(
perms.mode() & !0o170000,
0o600,
"mode is more permissive now, even after passing the umask"
);
}
file.with_mut(|out| out.write_all(b"hello world"))?;
assert_eq!(file.commit()?.0, resource, "returned and computed resource path match");
assert_eq!(
Expand Down
10 changes: 10 additions & 0 deletions gix-lock/tests/lock/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ mod commit {
let dir = tempfile::tempdir()?;
let resource = dir.path().join("the-resource");
let mark = gix_lock::Marker::acquire_to_hold_resource(resource, Fail::Immediately, None)?;
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let perms = mark.lock_path().metadata()?.permissions();
assert_ne!(
perms.mode() & !0o170000,
0o600,
"mode is more permissive now, even after passing the umask"
);
}
let err = mark.commit().expect_err("should always fail");
assert_eq!(err.error.kind(), std::io::ErrorKind::Other);
assert_eq!(
Expand Down
4 changes: 2 additions & 2 deletions gix-odb/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "gix-odb"
version = "0.57.0"
version = "0.58.0"
repository = "https://github.com/Byron/gitoxide"
authors = ["Sebastian Thiel <sebastian.thiel@icloud.com>"]
license = "MIT OR Apache-2.0"
Expand All @@ -24,7 +24,7 @@ gix-date = { version = "^0.8.3", path = "../gix-date" }
gix-path = { version = "^0.10.5", path = "../gix-path" }
gix-quote = { version = "^0.4.10", path = "../gix-quote" }
gix-object = { version = "^0.41.0", path = "../gix-object" }
gix-pack = { version = "^0.47.0", path = "../gix-pack", default-features = false }
gix-pack = { version = "^0.48.0", path = "../gix-pack", default-features = false }
gix-fs = { version = "^0.10.0", path = "../gix-fs" }
serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"]}

Expand Down
4 changes: 2 additions & 2 deletions gix-pack/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "gix-pack"
version = "0.47.0"
version = "0.48.0"
repository = "https://github.com/Byron/gitoxide"
authors = ["Sebastian Thiel <sebastian.thiel@icloud.com>"]
license = "MIT OR Apache-2.0"
Expand Down Expand Up @@ -41,7 +41,7 @@ gix-hashtable = { version = "^0.5.1", path = "../gix-hashtable" }

# for streaming of packs (input, output)
gix-traverse = { version = "^0.37.0", path = "../gix-traverse", optional = true }
gix-diff = { version = "^0.40.0", path = "../gix-diff", default-features = false, optional = true }
gix-diff = { version = "^0.41.0", path = "../gix-diff", default-features = false, optional = true }

memmap2 = "0.9.0"
smallvec = "1.3.0"
Expand Down
2 changes: 1 addition & 1 deletion gix-ref/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "gix-ref"
version = "0.41.0"
version = "0.42.0"
repository = "https://github.com/Byron/gitoxide"
license = "MIT OR Apache-2.0"
description = "A crate to handle git references"
Expand Down
6 changes: 3 additions & 3 deletions gix-status/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "gix-status"
version = "0.5.0"
version = "0.6.0"
repository = "https://github.com/Byron/gitoxide"
license = "MIT OR Apache-2.0"
description = "A crate of the gitoxide project dealing with 'git status'-like functionality"
Expand All @@ -14,14 +14,14 @@ autotests = false
doctest = false

[dependencies]
gix-index = { version = "^0.29.0", path = "../gix-index" }
gix-index = { version = "^0.30.0", path = "../gix-index" }
gix-fs = { version = "^0.10.0", path = "../gix-fs" }
gix-hash = { version = "^0.14.1", path = "../gix-hash" }
gix-object = { version = "^0.41.0", path = "../gix-object" }
gix-path = { version = "^0.10.5", path = "../gix-path" }
gix-features = { version = "^0.38.0", path = "../gix-features" }
gix-filter = { version = "^0.9.0", path = "../gix-filter" }
gix-worktree = { version = "^0.30.0", path = "../gix-worktree", default-features = false, features = ["attributes"] }
gix-worktree = { version = "^0.31.0", path = "../gix-worktree", default-features = false, features = ["attributes"] }

thiserror = "1.0.26"
filetime = "0.2.15"
Expand Down
4 changes: 2 additions & 2 deletions gix-submodule/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "gix-submodule"
version = "0.8.0"
version = "0.9.0"
repository = "https://github.com/Byron/gitoxide"
license = "MIT OR Apache-2.0"
description = "A crate of the gitoxide project dealing git submodules"
Expand All @@ -15,7 +15,7 @@ doctest = false
[dependencies]
gix-pathspec = { version = "^0.6.0", path = "../gix-pathspec" }
gix-refspec = { version = "^0.22.0", path = "../gix-refspec" }
gix-config = { version = "^0.34.0", path = "../gix-config" }
gix-config = { version = "^0.35.0", path = "../gix-config" }
gix-path = { version = "^0.10.5", path = "../gix-path" }
gix-url = { version = "^0.27.0", path = "../gix-url" }

Expand Down
Loading