forked from pre-commit/identify
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathidentify.rs
More file actions
155 lines (133 loc) · 4.05 KB
/
Copy pathidentify.rs
File metadata and controls
155 lines (133 loc) · 4.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#![allow(dead_code)]
#![allow(unused_imports)]
#![allow(unused_variables)]
#![allow(unused_mut)]
use std::collections::HashMap;
use std::collections::HashSet;
use std::ffi::OsStr;
use std::ffi::OsString;
use std::fs;
use std::os::unix::fs::FileTypeExt; // For `filetype.is_socket()` apparently
// use std::os::unix::fs::PermissionsExt; // fs::Permissions `mode()`
use std::os::unix::fs::MetadataExt; // fs::Permissions `mode()`
use std::path::Path;
use crate::tags;
#[derive(Debug, Eq, Hash, PartialEq)]
pub enum Tags {
Directory,
Symlink,
Socket,
File,
Executable,
NonExecutable,
Text,
Binary,
}
pub fn tags_from_path(file_path: &str) -> HashSet<Tags> {
let file = Path::new(file_path);
// TODO: Convert to Error
if !file.exists() {
panic!("{file_path} does not exist.");
}
let metadata = fs::symlink_metadata(&file);
if let Ok(metadata) = metadata {
// let perms = metadata.mode() & 0o777;
// println!("{:o}", perms);
if metadata.is_symlink() {
return HashSet::from([Tags::Symlink]);
}
if metadata.is_dir() {
return HashSet::from([Tags::Directory]);
}
if metadata.file_type().is_socket() {
return HashSet::from([Tags::Socket]);
}
}
let tags = HashSet::from([Tags::File]);
// TODO
// If executable, add to `tags`
let t = tags_from_filename(file_path);
// see if we can get tags_from_filename() and if not,
// then... weird parse_shebang stuff?
// a lil more. reread it when not tired.
tags
}
pub fn tags_from_filename(filename: &str) -> HashSet<String> {
let path = Path::new(filename);
let filename = path.file_name().unwrap().to_str().unwrap().to_string();
let ext = path.extension().unwrap().to_str().unwrap().to_lowercase();
let mut ret = HashSet::new();
/*
let _: Vec<&str> = filename.split('.').collect();
let mut parts = Vec::from([filename.clone()]);
parts.extend(filename.split('.').map(|s| s.to_string()));
for part in parts {
if tags::NAMES.contains_key(&part) {
println!("{:?}", tags::NAMES[&part]);
// ret.push(tags::NAMES[&part]);
}
println!("Boop: {}", part);
}
*/
if tags::EXTENSIONS.contains_key(&ext) {
ret.extend(tags::EXTENSIONS[&ext].iter().map(|s| s.to_string()));
} else if tags::EXTENSIONS_NEED_BINARY_CHECK.contains_key(&ext) {
ret.extend(
tags::EXTENSIONS_NEED_BINARY_CHECK[&ext]
.iter()
.map(|s| s.to_string()),
);
}
/*
for part in Vec::from([
filename.clone(),
filename.split('.').map(|s| s.to_string()).collect()
]) {
println!("Boop: {}", part);
}
*/
// identify.py creates a set, then,
// if filename + filename.split('.') items in extensions.NAMES,
// add to set and break
/*
let mut map = HashSet::new();
if filename in extensions::names() {
map.insert(extension);
}
*/
// if there's an extension,
// lowercase it,
// then if it's in extension.EXTENSIONS, add to set
// or if it's in extension.EXTENSIONS_NEED_BINARY_CHECK, add to set
// return set
/*
let mut tags: HashSet<String> = HashSet::new();
if let Some(name) = path.file_name().and_then(OsStr::to_str) {
tags.insert(name.to_owned());
}
if let Some(ext) = path.extension().and_then(OsStr::to_str) {
tags.insert(ext.to_owned());
}
*/
// Get filename and extension
// Allow "Dockerfile.xenial" to also match "Dockerfile"
// If filename in extensions.NAMES, add
// If extension in EXTENSIONS, add
// tags
ret
}
pub fn tags_from_interpreter(interpreter: &str) -> HashSet<String> {
HashSet::new()
}
pub fn is_text(/* bytes io */) -> bool {
false
}
pub fn file_is_text(path: &str) -> bool {
false
}
/*
pub fn parse_shebang( /* bytesio */) -> tuple of unknown size? {
}
pub fn parse_shebang_from_file(path: PathBuf) -> tuple of unknown size? {
}
*/