Skip to content

Commit

Permalink
Merge pull request #21 from darkowlzz/current-theme
Browse files Browse the repository at this point in the history
config: Check if a theme is the current theme
  • Loading branch information
lex148 authored Sep 7, 2021
2 parents 6957c63 + 2c84eb4 commit c096ef0
Showing 1 changed file with 125 additions and 3 deletions.
128 changes: 125 additions & 3 deletions src/models/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::path::Path;
use xdg::BaseDirectories;

const THEMES_DIR: &str = "themes";
const CURRENT_DIR: &str = "current";

/// Contains a vector of all global repositories.
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
Expand Down Expand Up @@ -140,7 +141,8 @@ impl Repo {
// Get a list of existing themes.
let path = BaseDirectories::with_prefix("leftwm")?;
let base_config_path = String::from(path.get_config_home().to_str().unwrap());
let existing_themes = Repo::installed_themes(base_config_path).unwrap();
let existing_themes = Repo::installed_themes(base_config_path.clone()).unwrap();
let current_theme = Repo::current_theme(base_config_path).unwrap();
let themes_dir = path.get_config_home().join(THEMES_DIR);

// Iterate over all the themes, and update/add if needed.
Expand All @@ -150,6 +152,12 @@ impl Repo {
if existing_themes.contains(&tema.name.clone()) {
tema.directory = Some(themes_dir.join(tema.name.clone()));
}

// Check if this is the current theme.
if current_theme.eq(&tema.name.clone()) {
tema.current = Some(true);
}

Repo::update_or_append(self, &tema);
}
Ok(self)
Expand Down Expand Up @@ -180,6 +188,50 @@ impl Repo {
}
}

// Looks for the current theme in the themes directory and returns the name
// of the current theme.
fn current_theme(config_path: String) -> Option<String> {
let theme_path = Path::new(&config_path).join(THEMES_DIR);

// Return None if themes directory doesn't exist.
if !theme_path.exists() {
return None;
}

// Read the themes directory, find the "current" theme and get the
// current theme name.
let mut result = String::new();
let current_dir = String::from(CURRENT_DIR);
let paths = fs::read_dir(theme_path).unwrap();
for path in paths {
let p = &path.unwrap().path();
// Get the file with name "current" and check if it's a symlink.
// Follow the symlink to find the target theme.
let target_file_name = p.file_name().unwrap().to_str().unwrap();
if target_file_name.eq(&current_dir) {
let metadata = fs::symlink_metadata(p).unwrap();
let file_type = metadata.file_type();
if file_type.is_symlink() {
result = String::from(
fs::read_link(p)
.unwrap()
.file_name()
.unwrap()
.to_str()
.unwrap(),
);
}
break;
}
}

if result.is_empty() {
return None;
}

Some(result)
}

// Returns a list of all the installed theme names under a given config
// path.
fn installed_themes(config_path: String) -> Result<Vec<String>> {
Expand Down Expand Up @@ -208,7 +260,7 @@ impl Repo {
}

// Ignore the "current" directory for installed theme list.
let current_dir = String::from("current");
let current_dir = String::from(CURRENT_DIR);
let target_path = p.path();
if target_path
.file_name()
Expand Down Expand Up @@ -248,7 +300,7 @@ mod test {
assert!(File::create(unrelated_file).is_ok());

// Create current theme as a symlink to an existing theme.
let current = themes_dir.join("current");
let current = themes_dir.join(CURRENT_DIR);
let src = theme2.to_str().unwrap();
let dst = current.to_str().unwrap();
assert!(unix_fs::symlink(src, dst).is_ok());
Expand All @@ -268,4 +320,74 @@ mod test {
let config_dir = tmpdir.path().to_str().unwrap();
assert!(Repo::installed_themes(String::from(config_dir)).is_ok());
}

#[test]
fn test_current_theme() {
// Create a temporary directory as the config path and create the
// directory layout within it for themes.
let tmpdir = tempfile::tempdir().unwrap();
let themes_dir = tmpdir.path().join(THEMES_DIR);
let theme1 = themes_dir.join("test-theme1");
let theme2 = themes_dir.join("test-theme2");
assert!(fs::create_dir_all(&theme1).is_ok());
assert!(fs::create_dir_all(&theme2).is_ok());

// Create current theme as a symlink to an existing theme.
let current = themes_dir.join(CURRENT_DIR);
let src = theme2.to_str().unwrap();
let dst = current.to_str().unwrap();
assert!(unix_fs::symlink(src, dst).is_ok());

let config_dir = tmpdir.path().to_str().unwrap();
let result = Repo::current_theme(String::from(config_dir));
assert_eq!(result.unwrap(), "test-theme2");
}

#[test]
fn test_current_theme_unmanaged() {
let tmpdir = tempfile::tempdir().unwrap();
let themes_dir = tmpdir.path().join(THEMES_DIR);

// Custom theme, not a symlink, not managed by leftwm-theme.
let current = themes_dir.join(CURRENT_DIR);
assert!(fs::create_dir_all(&current).is_ok());

let config_dir = tmpdir.path().to_str().unwrap();
let result = Repo::current_theme(String::from(config_dir));
assert!(result.is_none());
}

#[test]
fn test_current_theme_no_themes_dir() {
let tmpdir = tempfile::tempdir().unwrap();
let config_dir = tmpdir.path().to_str().unwrap();
assert!(Repo::current_theme(String::from(config_dir)).is_none());
}

#[test]
fn test_current_theme_no_current() {
let tmpdir = tempfile::tempdir().unwrap();
let themes_dir = tmpdir.path().join(THEMES_DIR);
let theme1 = themes_dir.join("test-theme1");
let theme2 = themes_dir.join("test-theme2");
assert!(fs::create_dir_all(&theme1).is_ok());
assert!(fs::create_dir_all(&theme2).is_ok());

let config_dir = tmpdir.path().to_str().unwrap();
assert!(Repo::current_theme(String::from(config_dir)).is_none());
}

#[test]
fn test_current_theme_current_file() {
let tmpdir = tempfile::tempdir().unwrap();
let themes_dir = tmpdir.path().join(THEMES_DIR);
assert!(fs::create_dir_all(&themes_dir).is_ok());

// Create a file "current", instead of a directory.
let current_file = themes_dir.join(CURRENT_DIR);
assert!(File::create(current_file).is_ok());

let config_dir = tmpdir.path().to_str().unwrap();
assert!(Repo::current_theme(String::from(config_dir)).is_none());
}
}

0 comments on commit c096ef0

Please sign in to comment.