ragit/index/commands/
pull.rs1use super::Index;
2use super::archive::BlockType;
3use crate::constant::{
4 CHUNK_DIR_NAME,
5 CONFIG_DIR_NAME,
6 FILE_INDEX_DIR_NAME,
7 II_DIR_NAME,
8 IMAGE_DIR_NAME,
9 INDEX_DIR_NAME,
10 INDEX_FILE_NAME,
11 METADATA_FILE_NAME,
12 PROMPT_DIR_NAME,
13};
14use crate::error::Error;
15use ragit_fs::{
16 exists,
17 join,
18 remove_dir_all,
19 rename,
20};
21use reqwest::Url;
22
23pub enum PullResult {
24 PulledArchives,
25 AlreadyUpToDate,
26}
27
28impl Index {
29 pub async fn pull(
31 &self,
32 include_configs: bool,
33 include_prompts: bool,
34 ii: bool,
35 quiet: bool,
36 ) -> Result<PullResult, Error> {
37 let Some(repo_url) = self.repo_url.clone() else {
38 return Err(Error::NoRemoteToPullFrom);
39 };
40
41 let url = Url::parse(&repo_url)?;
43 let get_uid_url = url.join("uid")?;
44
45 match self.get_uid("pull", get_uid_url.as_str()).await {
46 Ok(remote_uid) => {
47 let self_uid = self.calculate_uid(false )?;
48
49 if remote_uid == self_uid {
50 return Ok(PullResult::AlreadyUpToDate);
51 }
52 },
53 Err(e) => {
54 if !quiet {
55 eprintln!("Failed to get {get_uid_url}: {e:?}");
56 }
57 },
58 }
59
60 let mut tmp_no = 0;
61 let mut tmp_clone_dir = format!("tmp-clone-dir-{tmp_no}");
62
63 while exists(&tmp_clone_dir) {
64 tmp_no += 1;
65 tmp_clone_dir = format!("tmp-clone-dir-{tmp_no}");
66 }
67
68 let result = self.pull_worker(
69 repo_url,
70 &tmp_clone_dir,
71 include_configs,
72 include_prompts,
73 ii,
74 quiet,
75 ).await;
76
77 if exists(&tmp_clone_dir) {
78 remove_dir_all(&tmp_clone_dir)?;
79 }
80
81 result
82 }
83
84 async fn pull_worker(
85 &self,
86 repo_url: String,
87 tmp_clone_dir: &str,
88 include_configs: bool,
89 include_prompts: bool,
90 ii: bool,
91 quiet: bool,
92 ) -> Result<PullResult, Error> {
93 let cloned_blocks = Index::clone(repo_url, Some(tmp_clone_dir.to_string()), ii, quiet).await?;
94 let cloned_configs = cloned_blocks.get(&BlockType::Config).map(|n| *n).unwrap_or(0) > 1;
95 let cloned_prompts = cloned_blocks.get(&BlockType::Prompt).map(|n| *n).unwrap_or(0) > 1;
96
97 let curr_index_dir = join(
98 &self.root_dir,
99 INDEX_DIR_NAME,
100 )?;
101 let new_index_dir = join(
102 &tmp_clone_dir,
103 INDEX_DIR_NAME,
104 )?;
105
106 for dir in [
110 FILE_INDEX_DIR_NAME,
111 CHUNK_DIR_NAME,
112 IMAGE_DIR_NAME,
113 ].iter() {
114 remove_dir_all(&join(&curr_index_dir, dir)?)?;
115 rename(
116 &join(&new_index_dir, dir)?,
117 &join(&curr_index_dir, dir)?,
118 )?;
119 }
120
121 rename(
122 &join(&new_index_dir, INDEX_FILE_NAME)?,
123 &join(&curr_index_dir, INDEX_FILE_NAME)?,
124 )?;
125
126 if exists(&join(&new_index_dir, METADATA_FILE_NAME)?) {
127 rename(
128 &join(&new_index_dir, METADATA_FILE_NAME)?,
129 &join(&curr_index_dir, METADATA_FILE_NAME)?,
130 )?;
131 }
132
133 if include_configs && cloned_configs {
134 remove_dir_all(&join(&curr_index_dir, CONFIG_DIR_NAME)?)?;
135 rename(
136 &join(&new_index_dir, CONFIG_DIR_NAME)?,
137 &join(&curr_index_dir, CONFIG_DIR_NAME)?,
138 )?;
139 }
140
141 if include_prompts && cloned_prompts {
142 remove_dir_all(&join(&curr_index_dir, PROMPT_DIR_NAME)?)?;
143 rename(
144 &join(&new_index_dir, PROMPT_DIR_NAME)?,
145 &join(&curr_index_dir, PROMPT_DIR_NAME)?,
146 )?;
147 }
148
149 if exists(&join(&new_index_dir, II_DIR_NAME)?) {
150 remove_dir_all(&join(&curr_index_dir, II_DIR_NAME)?)?;
151 rename(
152 &join(&new_index_dir, II_DIR_NAME)?,
153 &join(&curr_index_dir, II_DIR_NAME)?,
154 )?;
155 }
156
157 Ok(PullResult::PulledArchives)
158 }
159}