Skip to content

Commit

Permalink
Hack in Windows support
Browse files Browse the repository at this point in the history
  • Loading branch information
piegamesde committed Aug 14, 2023
1 parent 90c8070 commit e5378b7
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 7 deletions.
21 changes: 17 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
name: CI

on: [push, pull_request]
on:
push:
branches: ["*"]
pull_request:
branches: ["*"]

env:
minrust: 1.40.0 # Also update in Cargo.toml

jobs:
Lints:
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix: { os: [ ubuntu-latest, windows-latest ] }
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
Expand All @@ -19,7 +26,10 @@ jobs:
if: always()

Test:
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix: { os: [ ubuntu-latest, windows-latest ] }

steps:
- uses: actions/checkout@v3
Expand All @@ -28,7 +38,10 @@ jobs:
- run: cargo test

MSRV:
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix: { os: [ ubuntu-latest, windows-latest ] }

steps:
- uses: actions/checkout@v3
Expand Down
37 changes: 36 additions & 1 deletion src/base_directories.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::collections::HashSet;
use std::ffi::OsString;
#[cfg(any(unix, target_os = "redox"))]
use std::os::unix::fs::PermissionsExt;
use std::path::{Path, PathBuf};
use std::{env, error, fmt, fs, io};
Expand Down Expand Up @@ -107,6 +108,7 @@ pub struct BaseDirectories {
pub config_dirs: Vec<PathBuf>,
/// Like [`BaseDirectories::get_runtime_directory`], but without any of the sanity checks
/// on the directory (like permissions).
#[cfg(any(unix, target_os = "redox"))]
pub runtime_dir: Option<PathBuf>,
}

Expand All @@ -130,15 +132,19 @@ impl error::Error for Error {
fn description(&self) -> &str {
match self.kind {
HomeMissing => "$HOME must be set",
#[cfg(any(unix, target_os = "redox"))]
XdgRuntimeDirInaccessible(_, _) => {
"$XDG_RUNTIME_DIR must be accessible by the current user"
}
#[cfg(any(unix, target_os = "redox"))]
XdgRuntimeDirInsecure(_, _) => "$XDG_RUNTIME_DIR must be secure: have permissions 0700",
#[cfg(any(unix, target_os = "redox"))]
XdgRuntimeDirMissing => "$XDG_RUNTIME_DIR is not set",
}
}
fn cause(&self) -> Option<&dyn error::Error> {
match self.kind {
#[cfg(any(unix, target_os = "redox"))]
XdgRuntimeDirInaccessible(_, ref e) => Some(e),
_ => None,
}
Expand All @@ -149,6 +155,7 @@ impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.kind {
HomeMissing => write!(f, "$HOME must be set"),
#[cfg(any(unix, target_os = "redox"))]
XdgRuntimeDirInaccessible(ref dir, ref error) => {
write!(
f,
Expand All @@ -158,6 +165,7 @@ impl fmt::Display for Error {
error
)
}
#[cfg(any(unix, target_os = "redox"))]
XdgRuntimeDirInsecure(ref dir, permissions) => {
write!(
f,
Expand All @@ -167,6 +175,7 @@ impl fmt::Display for Error {
permissions
)
}
#[cfg(any(unix, target_os = "redox"))]
XdgRuntimeDirMissing => {
write!(f, "$XDG_RUNTIME_DIR must be set")
}
Expand All @@ -176,10 +185,15 @@ impl fmt::Display for Error {

impl From<Error> for io::Error {
fn from(error: Error) -> io::Error {
#[cfg(any(unix, target_os = "redox"))]
match error.kind {
HomeMissing | XdgRuntimeDirMissing => io::Error::new(io::ErrorKind::NotFound, error),
_ => io::Error::new(io::ErrorKind::Other, error),
}
#[cfg(not(any(unix, target_os = "redox")))]
{
io::Error::new(io::ErrorKind::NotFound, error)
}
}
}

Expand All @@ -202,8 +216,11 @@ impl fmt::Display for Permissions {
#[derive(Debug)]
enum ErrorKind {
HomeMissing,
#[cfg(any(unix, target_os = "redox"))]
XdgRuntimeDirInaccessible(PathBuf, io::Error),
#[cfg(any(unix, target_os = "redox"))]
XdgRuntimeDirInsecure(PathBuf, Permissions),
#[cfg(any(unix, target_os = "redox"))]
XdgRuntimeDirMissing,
}

Expand Down Expand Up @@ -321,6 +338,7 @@ impl BaseDirectories {
let config_dirs = env_var("XDG_CONFIG_DIRS")
.and_then(abspaths)
.unwrap_or(vec![PathBuf::from("/etc/xdg")]);
#[cfg(any(unix, target_os = "redox"))]
let runtime_dir = env_var("XDG_RUNTIME_DIR").and_then(abspath); // optional

let prefix = PathBuf::from(prefix);
Expand All @@ -333,11 +351,13 @@ impl BaseDirectories {
state_home,
data_dirs,
config_dirs,
#[cfg(any(unix, target_os = "redox"))]
runtime_dir,
}
}

/// Returns the user-specific runtime directory (set by `XDG_RUNTIME_DIR`).
#[cfg(any(unix, target_os = "redox"))]
pub fn get_runtime_directory(&self) -> Result<&PathBuf, Error> {
if let Some(ref runtime_dir) = self.runtime_dir {
// If XDG_RUNTIME_DIR is in the environment but not secure,
Expand All @@ -363,7 +383,14 @@ impl BaseDirectories {

/// Returns `true` if `XDG_RUNTIME_DIR` is available, `false` otherwise.
pub fn has_runtime_directory(&self) -> bool {
self.get_runtime_directory().is_ok()
#[cfg(any(unix, target_os = "redox"))]
{
self.get_runtime_directory().is_ok()
}
#[cfg(not(any(unix, target_os = "redox")))]
{
false
}
}

/// Like [`place_config_file()`](#method.place_config_file), but does
Expand Down Expand Up @@ -401,6 +428,7 @@ impl BaseDirectories {
/// Like [`place_runtime_file()`](#method.place_runtime_file), but does
/// not create any directories.
/// If `XDG_RUNTIME_DIR` is not available, returns an error.
#[cfg(any(unix, target_os = "redox"))]
pub fn get_runtime_file<P: AsRef<Path>>(&self, path: P) -> io::Result<PathBuf> {
let runtime_dir = self.get_runtime_directory()?;
Ok(runtime_dir.join(self.user_prefix.join(path)))
Expand Down Expand Up @@ -439,6 +467,7 @@ impl BaseDirectories {
/// Like [`place_config_file()`](#method.place_config_file), but for
/// a runtime file in `XDG_RUNTIME_DIR`.
/// If `XDG_RUNTIME_DIR` is not available, returns an error.
#[cfg(any(unix, target_os = "redox"))]
pub fn place_runtime_file<P: AsRef<Path>>(&self, path: P) -> io::Result<PathBuf> {
write_file(self.get_runtime_directory()?, &self.user_prefix.join(path))
}
Expand Down Expand Up @@ -524,6 +553,7 @@ impl BaseDirectories {
/// Given a relative path `path`, returns an absolute path to an existing
/// runtime file, or `None`. Searches `XDG_RUNTIME_DIR`.
/// If `XDG_RUNTIME_DIR` is not available, returns `None`.
#[cfg(any(unix, target_os = "redox"))]
pub fn find_runtime_file<P: AsRef<Path>>(&self, path: P) -> Option<PathBuf> {
let runtime_dir = self.get_runtime_directory().ok()?;
read_file(
Expand Down Expand Up @@ -576,6 +606,7 @@ impl BaseDirectories {
/// Like [`create_config_directory()`](#method.create_config_directory),
/// but for a runtime directory in `XDG_RUNTIME_DIR`.
/// If `XDG_RUNTIME_DIR` is not available, returns an error.
#[cfg(any(unix, target_os = "redox"))]
pub fn create_runtime_directory<P: AsRef<Path>>(&self, path: P) -> io::Result<PathBuf> {
create_directory(
Some(self.get_runtime_directory()?),
Expand Down Expand Up @@ -660,6 +691,7 @@ impl BaseDirectories {
/// Given a relative path `path`, lists absolute paths to all files
/// in directories with path `path` in `XDG_RUNTIME_DIR`.
/// If `XDG_RUNTIME_DIR` is not available, returns an empty `Vec`.
#[cfg(any(unix, target_os = "redox"))]
pub fn list_runtime_files<P: AsRef<Path>>(&self, path: P) -> Vec<PathBuf> {
if let Ok(runtime_dir) = self.get_runtime_directory() {
list_files(
Expand Down Expand Up @@ -977,6 +1009,7 @@ mod test {
("XDG_CACHE_HOME", "test_files/user/cache".to_string()),
("XDG_DATA_DIRS", "test_files/user/data".to_string()),
("XDG_CONFIG_DIRS", "test_files/user/config".to_string()),
#[cfg(any(unix, target_os = "redox"))]
("XDG_RUNTIME_DIR", "test_files/runtime-bad".to_string()),
]),
);
Expand Down Expand Up @@ -1051,6 +1084,7 @@ mod test {
}

#[test]
#[cfg(any(unix, target_os = "redox"))]
fn test_runtime_bad() {
let cwd = env::current_dir().unwrap().to_string_lossy().into_owned();
let xd = BaseDirectories::with_env(
Expand All @@ -1065,6 +1099,7 @@ mod test {
}

#[test]
#[cfg(any(unix, target_os = "redox"))]
fn test_runtime_good() {
use std::fs::File;

Expand Down
2 changes: 0 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![cfg(any(unix, target_os = "redox"))]

mod base_directories;
pub use crate::base_directories::{
BaseDirectories, Error as BaseDirectoriesError, FileFindIterator,
Expand Down

0 comments on commit e5378b7

Please sign in to comment.