~/selfhut

selfhut/src/git/file.rs -rw-r--r-- 3.80 kB
00c0a257 — Arthur Melton format code 2 years ago

            
7dbdfabf arthurmelton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
e22778fe Arthur Melton
7dbdfabf arthurmelton
0016c2cc arthurmelton
7dbdfabf arthurmelton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
7dbdfabf arthurmelton
0016c2cc arthurmelton
7dbdfabf arthurmelton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
19f9b68c arthurmelton
7dbdfabf arthurmelton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
7dbdfabf arthurmelton
0016c2cc arthurmelton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
7dbdfabf arthurmelton





























































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
use crate::config::CONFIG;
use git2::ObjectType;
use humansize::{format_size, DECIMAL};
use serde_derive::Serialize;
use std::path::Component;
use std::path::PathBuf;

pub fn files(repo: String, branch: String, path: String) -> Option<Vec<File>> {
    if branch.contains(":") {
        return None;
    }
    let mut location = CONFIG.git_location.clone();
    location.push(path.clone());
    if location
        .components()
        .into_iter()
        .any(|x| x == Component::ParentDir)
    {
        return None;
    }
    let mut repo_path = CONFIG.git_location.clone();
    repo_path.push(format!("{}.git", repo));
    let repo = git2::Repository::open(repo_path).ok()?;
    let obj = repo.revparse_single(&format!("{}:{}", branch, path)).ok()?;
    let mut returns = Vec::new();
    match obj.kind() {
        Some(ObjectType::Tree) => {
            let tree = obj.as_tree()?;
            for entry in tree.iter() {
                returns.push(File {
                    name: entry.name()?.to_string(),
                    size: match entry.kind() {
                        Some(ObjectType::Blob) => Some(format_size(
                            entry.to_object(&repo).ok()?.into_blob().ok()?.size(),
                            DECIMAL,
                        )),
                        _ => None,
                    },
                    file_type: match entry.kind() {
                        Some(ObjectType::Blob) => FileType::blob,
                        _ => FileType::tree,
                    },
                    properties: unix_mode::to_string(entry.filemode() as u32),
                    properties_int: entry.filemode(),
                })
            }
        }
        _ => {
            return None;
        }
    }
    Some(returns)
}

pub fn file(repo: String, branch: String, path: String) -> Option<(File, Option<String>, Vec<u8>)> {
    if branch.contains(":") {
        return None;
    }
    let mut location = CONFIG.git_location.clone();
    location.push(path.clone());
    if location
        .components()
        .into_iter()
        .any(|x| x == Component::ParentDir)
    {
        return None;
    }
    let mut repo_path = CONFIG.git_location.clone();
    repo_path.push(format!("{}.git", repo));
    let repo = git2::Repository::open(repo_path).ok()?;
    let obj = repo.revparse_single(&format!("{}:{}", branch, path)).ok()?;
    match obj.kind() {
        Some(ObjectType::Blob) => {
            let blob = obj.as_blob()?;
            let mut path_to_folder = PathBuf::from(path);
            path_to_folder.pop();
            let path_to_folder = path_to_folder.into_os_string().to_str()?.to_string();
            let tree = repo
                .revparse_single(&format!("{}:{}", branch, path_to_folder))
                .ok()?;
            let tree = tree.as_tree()?;
            let tree_item = tree.get_id(blob.id())?;
            let file = File {
                name: tree_item.name()?.to_string(),
                size: Some(format_size(blob.size(), DECIMAL)),
                file_type: FileType::blob,
                properties: unix_mode::to_string(tree_item.filemode() as u32),
                properties_int: tree_item.filemode(),
            };
            let content = match blob.is_binary() {
                false => Some(String::from_utf8_lossy(blob.content()).into_owned()),
                true => None,
            };
            return Some((file, content, blob.content().iter().map(|x| *x).collect()));
        }
        _ => {
            return None;
        }
    }
}

#[derive(Serialize)]
pub struct File {
    pub name: String,
    pub size: Option<String>,
    pub file_type: FileType,
    pub properties: String,
    pub properties_int: i32,
}

#[derive(Serialize)]
pub enum FileType {
    blob,
    tree,
}