@@ -24,72 +24,38 @@ impl BackupManager {
2424 }
2525
2626 /// Create a backup of specified files
27- ///
28- /// Returns the backup ID on success.
29- ///
30- /// # Arguments
31- ///
32- /// * `files` - Files to backup (relative to workspace root)
33- /// * `metadata` - Metadata describing this backup
34- /// * `max_backups` - Maximum number of backups to keep (0 = unlimited)
3527 pub fn create_backup (
3628 & self ,
3729 files : & [ PathBuf ] ,
3830 mut metadata : BackupMetadata ,
3931 max_backups : usize ,
4032 ) -> RailResult < BackupId > {
41- // Generate backup ID
4233 let backup_id = create_backup_id ( ) ;
4334 let backup_dir = get_backup_dir ( & self . workspace_root , & backup_id) ;
4435
45- // Create backup directory
46- fs:: create_dir_all ( & backup_dir) . map_err ( |e| {
47- RailError :: message ( format ! (
48- "Failed to create backup directory {}: {}" ,
49- backup_dir. display( ) ,
50- e
51- ) )
52- } ) ?;
36+ fs:: create_dir_all ( & backup_dir)
37+ . map_err ( |e| RailError :: message ( format ! ( "failed to create {}: {}" , backup_dir. display( ) , e) ) ) ?;
5338
54- // Backup each file
5539 for file in files {
5640 let src = self . workspace_root . join ( file) ;
5741 let dest = backup_dir. join ( file) ;
5842
59- // Skip if source doesn't exist (might have been deleted)
6043 if !src. exists ( ) {
6144 continue ;
6245 }
6346
64- // Create parent directory in backup
6547 if let Some ( parent) = dest. parent ( ) {
66- fs:: create_dir_all ( parent) . map_err ( |e| {
67- RailError :: message ( format ! (
68- "Failed to create backup subdirectory {}: {}" ,
69- parent. display( ) ,
70- e
71- ) )
72- } ) ?;
48+ fs:: create_dir_all ( parent)
49+ . map_err ( |e| RailError :: message ( format ! ( "failed to create {}: {}" , parent. display( ) , e) ) ) ?;
7350 }
7451
75- // Copy file
76- fs:: copy ( & src, & dest) . map_err ( |e| {
77- RailError :: message ( format ! (
78- "Failed to backup {} to {}: {}" ,
79- src. display( ) ,
80- dest. display( ) ,
81- e
82- ) )
83- } ) ?;
84-
85- // Track in metadata
52+ fs:: copy ( & src, & dest) . map_err ( |e| RailError :: message ( format ! ( "failed to backup {}: {}" , src. display( ) , e) ) ) ?;
53+
8654 metadata. add_file ( file. clone ( ) ) ;
8755 }
8856
89- // Save metadata
9057 metadata. save ( & backup_dir) ?;
9158
92- // Clean up old backups if max_backups > 0
9359 if max_backups > 0 {
9460 let _deleted = self . cleanup_old_backups ( max_backups) ?;
9561 }
@@ -98,115 +64,74 @@ impl BackupManager {
9864 }
9965
10066 /// Restore a backup
101- ///
102- /// Restores all files from the specified backup to their original locations.
103- ///
104- /// # Safety
105- ///
106- /// This WILL overwrite existing files. Use with caution.
10767 pub fn restore_backup ( & self , backup_id : & str ) -> RailResult < ( ) > {
10868 let backup_dir = get_backup_dir ( & self . workspace_root , backup_id) ;
10969
11070 if !backup_dir. exists ( ) {
111- return Err ( RailError :: message ( format ! (
112- "Backup '{}' not found at {}" ,
113- backup_id,
114- backup_dir. display( )
115- ) ) ) ;
71+ return Err ( RailError :: message ( format ! ( "backup '{}' not found" , backup_id) ) ) ;
11672 }
11773
118- // Load metadata to know what files to restore
11974 let metadata = BackupMetadata :: load ( & backup_dir) ?;
12075
121- println ! ( "🔄 Restoring backup from {}" , metadata. timestamp) ;
122- println ! ( " Command: {}" , metadata. command) ;
123- println ! ( " Files: {}" , metadata. files_modified. len( ) ) ;
124- println ! ( ) ;
76+ eprintln ! ( "restoring backup: {}" , metadata. timestamp) ;
77+ eprintln ! ( " {} files" , metadata. files_modified. len( ) ) ;
12578
126- // Restore each file
12779 for file in & metadata. files_modified {
12880 let src = backup_dir. join ( file) ;
12981 let dest = self . workspace_root . join ( file) ;
13082
131- // Skip if backup file doesn't exist (shouldn't happen, but be safe)
13283 if !src. exists ( ) {
133- eprintln ! ( "⚠️ Warning: Backup file {} not found, skipping " , src . display( ) ) ;
84+ eprintln ! ( " skipped (missing): {} " , file . display( ) ) ;
13485 continue ;
13586 }
13687
137- // Create parent directory if needed
13888 if let Some ( parent) = dest. parent ( ) {
139- fs:: create_dir_all ( parent) . map_err ( |e| {
140- RailError :: message ( format ! (
141- "Failed to create directory {} for restore: {}" ,
142- parent. display( ) ,
143- e
144- ) )
145- } ) ?;
89+ fs:: create_dir_all ( parent)
90+ . map_err ( |e| RailError :: message ( format ! ( "failed to create {}: {}" , parent. display( ) , e) ) ) ?;
14691 }
14792
148- // Restore file
149- fs:: copy ( & src, & dest) . map_err ( |e| {
150- RailError :: message ( format ! (
151- "Failed to restore {} to {}: {}" ,
152- src. display( ) ,
153- dest. display( ) ,
154- e
155- ) )
156- } ) ?;
157-
158- println ! ( " ✓ Restored {}" , file. display( ) ) ;
93+ fs:: copy ( & src, & dest) . map_err ( |e| RailError :: message ( format ! ( "failed to restore {}: {}" , file. display( ) , e) ) ) ?;
94+
95+ eprintln ! ( " restored: {}" , file. display( ) ) ;
15996 }
16097
161- println ! ( ) ;
162- println ! ( "✅ Backup restored successfully" ) ;
98+ println ! ( "backup restored" ) ;
16399
164100 Ok ( ( ) )
165101 }
166102
167- /// List all available backups (sorted by timestamp, newest first)
103+ /// List all backups (newest first)
168104 pub fn list_backups ( & self ) -> RailResult < Vec < BackupRecord > > {
169105 if !self . backup_root . exists ( ) {
170106 return Ok ( Vec :: new ( ) ) ;
171107 }
172108
173109 let mut backups = Vec :: new ( ) ;
174110
175- let entries = fs:: read_dir ( & self . backup_root ) . map_err ( |e| {
176- RailError :: message ( format ! (
177- "Failed to read backup directory {}: {}" ,
178- self . backup_root. display( ) ,
179- e
180- ) )
181- } ) ?;
111+ let entries = fs:: read_dir ( & self . backup_root )
112+ . map_err ( |e| RailError :: message ( format ! ( "failed to read {}: {}" , self . backup_root. display( ) , e) ) ) ?;
182113
183114 for entry in entries {
184- let entry = entry. map_err ( |e| RailError :: message ( format ! ( "Failed to read backup entry: {}" , e) ) ) ?;
115+ let entry = entry. map_err ( |e| RailError :: message ( format ! ( "failed to read entry: {}" , e) ) ) ?;
185116
186117 let path = entry. path ( ) ;
187118 if !path. is_dir ( ) {
188119 continue ;
189120 }
190121
191- // Get backup ID from directory name
192122 let backup_id = match path. file_name ( ) {
193123 Some ( name) => name. to_string_lossy ( ) . to_string ( ) ,
194124 None => continue ,
195125 } ;
196126
197- // Load metadata
198127 match BackupMetadata :: load ( & path) {
199128 Ok ( metadata) => {
200129 backups. push ( BackupRecord :: new ( backup_id, metadata, path) ) ;
201130 }
202- Err ( e) => {
203- eprintln ! ( "⚠️ Warning: Failed to load metadata for backup {}: {}" , backup_id, e) ;
204- continue ;
205- }
131+ Err ( _) => continue ,
206132 }
207133 }
208134
209- // Sort by timestamp (newest first)
210135 backups. sort_by ( |a, b| b. metadata . timestamp . cmp ( & a. metadata . timestamp ) ) ;
211136
212137 Ok ( backups)
@@ -231,7 +156,7 @@ impl BackupManager {
231156
232157 for backup in to_delete {
233158 fs:: remove_dir_all ( & backup. path )
234- . map_err ( |e| RailError :: message ( format ! ( "Failed to delete backup {}: {}" , backup. id, e) ) ) ?;
159+ . map_err ( |e| RailError :: message ( format ! ( "failed to delete {}: {}" , backup. id, e) ) ) ?;
235160 }
236161
237162 Ok ( deleted_count)
0 commit comments