1use crate::error::LinearError;
2use std::path::PathBuf;
3
4pub fn token_from_file() -> Result<String, LinearError> {
7 let path = token_file_path()?;
8 std::fs::read_to_string(&path)
9 .map(|s| s.trim().to_string())
10 .map_err(|e| {
11 LinearError::AuthConfig(format!(
12 "Could not read token file {}: {}",
13 path.display(),
14 e
15 ))
16 })
17}
18
19pub fn token_from_env() -> Result<String, LinearError> {
21 std::env::var("LINEAR_API_TOKEN").map_err(|_| {
22 LinearError::AuthConfig("LINEAR_API_TOKEN environment variable not set".to_string())
23 })
24}
25
26pub fn auto_token() -> Result<String, LinearError> {
29 token_from_env().or_else(|_| token_from_file())
30}
31
32fn token_file_path() -> Result<PathBuf, LinearError> {
33 let home = home::home_dir()
34 .ok_or_else(|| LinearError::AuthConfig("Could not determine home directory".to_string()))?;
35 Ok(home.join(".linear_api_token"))
36}
37
38#[cfg(test)]
39mod tests {
40 use super::*;
41
42 #[test]
43 fn token_from_env_success() {
44 std::env::set_var("LINEAR_API_TOKEN", "test-token-12345");
46 let result = token_from_env();
47 std::env::remove_var("LINEAR_API_TOKEN");
48 assert_eq!(result.unwrap(), "test-token-12345");
49 }
50
51 #[test]
52 fn token_from_env_missing() {
53 std::env::remove_var("LINEAR_API_TOKEN");
54 let result = token_from_env();
55 assert!(result.is_err());
56 assert!(result.unwrap_err().to_string().contains("LINEAR_API_TOKEN"));
57 }
58
59 #[test]
60 fn auto_token_prefers_env() {
61 std::env::set_var("LINEAR_API_TOKEN", "env-token-auto");
62 let result = auto_token();
63 std::env::remove_var("LINEAR_API_TOKEN");
64 assert_eq!(result.unwrap(), "env-token-auto");
66 }
67
68 #[test]
69 fn token_file_path_is_home_based() {
70 let path = token_file_path().unwrap();
71 assert!(path.to_str().unwrap().contains(".linear_api_token"));
72 assert!(path.to_str().unwrap().starts_with("/"));
73 }
74}