ruborg 0.7.1 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +28 -0
 - data/README.md +1 -1
 - data/lib/ruborg/backup.rb +36 -4
 - data/lib/ruborg/version.rb +1 -1
 - metadata +1 -1
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 314fb4f24b1b5544d95257f5d3f315099f221ecc92b7920e935066319db72458
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 0ef7e5183f7596e1417b4b12915557d9c177b0b2504f6a143c7ff8aa59f726aa
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: fb9bcdb3517dc9fd2c1c05d868e8015fd5fe3a55c00e5c277cf7b0257f238535821f8dbcda594dc9bc4b413a8b96d4739d327e1b420f6bad08ac19e724193199
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 6544e4d87969bd59ca7912653ecaebedeca75795f934edb93ad9435a0e48cff5b0c95734aa5bdc70572a38cbed014ea8ac93cff4abee97867a910acba47d5240
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -7,6 +7,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 
     | 
|
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
            ## [Unreleased]
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
      
 10 
     | 
    
         
            +
            ## [0.7.3] - 2025-10-09
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            ### Changed
         
     | 
| 
      
 13 
     | 
    
         
            +
            - **Smart Remove-Source for Skipped Files**: Skipped files (unchanged, already backed up) are now deleted when `--remove-source` is used
         
     | 
| 
      
 14 
     | 
    
         
            +
              - Previously: Only newly backed-up files were deleted, skipped files remained
         
     | 
| 
      
 15 
     | 
    
         
            +
              - Now: Both backed-up AND skipped files are deleted (they're all safely backed up)
         
     | 
| 
      
 16 
     | 
    
         
            +
              - Rationale: If a file is skipped because it's already in an archive (verified by hash), it's safe to delete
         
     | 
| 
      
 17 
     | 
    
         
            +
              - Makes `--remove-source` behavior consistent: "delete everything that's safely backed up"
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            ### Technical Details
         
     | 
| 
      
 20 
     | 
    
         
            +
            - Per-file mode verifies files are safely backed up before skipping (path + size + SHA256 hash match)
         
     | 
| 
      
 21 
     | 
    
         
            +
            - Skipped files are deleted immediately after verification (lib/ruborg/backup.rb:102)
         
     | 
| 
      
 22 
     | 
    
         
            +
            - Test updated to verify skipped files are deleted (spec/ruborg/per_file_backup_spec.rb:518)
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            ## [0.7.2] - 2025-10-09
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            ### Fixed
         
     | 
| 
      
 27 
     | 
    
         
            +
            - **Per-File Remove Source Behavior**: Files are now deleted immediately after each successful backup in per-file mode
         
     | 
| 
      
 28 
     | 
    
         
            +
              - Previously deleted entire source paths at the end (dangerous - could delete unchanged files)
         
     | 
| 
      
 29 
     | 
    
         
            +
              - Now deletes only successfully backed-up files, one at a time
         
     | 
| 
      
 30 
     | 
    
         
            +
              - Skipped files (unchanged) are never deleted
         
     | 
| 
      
 31 
     | 
    
         
            +
              - Matches the per-file philosophy: individual file handling throughout the backup process
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            ### Added
         
     | 
| 
      
 34 
     | 
    
         
            +
            - **Test Coverage**: Added 2 new RSpec tests verifying per-file remove-source behavior
         
     | 
| 
      
 35 
     | 
    
         
            +
              - Tests immediate file deletion after backup
         
     | 
| 
      
 36 
     | 
    
         
            +
              - Tests that skipped files are not deleted
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
       10 
38 
     | 
    
         
             
            ## [0.7.1] - 2025-10-08
         
     | 
| 
       11 
39 
     | 
    
         | 
| 
       12 
40 
     | 
    
         
             
            ### Added
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -25,7 +25,7 @@ A friendly Ruby frontend for [Borg Backup](https://www.borgbackup.org/). Ruborg 
     | 
|
| 
       25 
25 
     | 
    
         
             
            - 📈 **Summary View** - Quick overview of all repositories and their configurations
         
     | 
| 
       26 
26 
     | 
    
         
             
            - 🔧 **Custom Borg Path** - Support for custom Borg executable paths per repository
         
     | 
| 
       27 
27 
     | 
    
         
             
            - 🏠 **Hostname Validation** - NEW! Restrict backups to specific hosts (global or per-repository)
         
     | 
| 
       28 
     | 
    
         
            -
            - ✅ **Well-tested** - Comprehensive test suite with RSpec ( 
     | 
| 
      
 28 
     | 
    
         
            +
            - ✅ **Well-tested** - Comprehensive test suite with RSpec (288+ examples)
         
     | 
| 
       29 
29 
     | 
    
         
             
            - 🔒 **Security-focused** - Path validation, safe YAML loading, command injection protection
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
31 
     | 
    
         
             
            ## Prerequisites
         
     | 
    
        data/lib/ruborg/backup.rb
    CHANGED
    
    | 
         @@ -91,12 +91,16 @@ module Ruborg 
     | 
|
| 
       91 
91 
     | 
    
         
             
                          stored_hash = stored_info[:hash]
         
     | 
| 
       92 
92 
     | 
    
         | 
| 
       93 
93 
     | 
    
         
             
                          if current_hash == stored_hash
         
     | 
| 
       94 
     | 
    
         
            -
                            # Content truly unchanged
         
     | 
| 
      
 94 
     | 
    
         
            +
                            # Content truly unchanged - file is already safely backed up
         
     | 
| 
       95 
95 
     | 
    
         
             
                            puts " - Archive already exists (file unchanged)"
         
     | 
| 
       96 
96 
     | 
    
         
             
                            @logger&.info(
         
     | 
| 
       97 
97 
     | 
    
         
             
                              "[#{@repo_name}] Skipped #{file_path} - archive #{archive_name} already exists (file unchanged)"
         
     | 
| 
       98 
98 
     | 
    
         
             
                            )
         
     | 
| 
       99 
99 
     | 
    
         
             
                            skipped_count += 1
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                            # If remove_source is enabled, delete the file (it's already safely backed up)
         
     | 
| 
      
 102 
     | 
    
         
            +
                            remove_single_file(file_path) if remove_source
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
       100 
104 
     | 
    
         
             
                            next
         
     | 
| 
       101 
105 
     | 
    
         
             
                          else
         
     | 
| 
       102 
106 
     | 
    
         
             
                            # Size same but content changed (rare: edited + truncated/padded to same size)
         
     | 
| 
         @@ -131,6 +135,9 @@ module Ruborg 
     | 
|
| 
       131 
135 
     | 
    
         
             
                    # Log successful action with details
         
     | 
| 
       132 
136 
     | 
    
         
             
                    @logger&.info("[#{@repo_name}] Archived #{file_path} in archive #{archive_name}")
         
     | 
| 
       133 
137 
     | 
    
         
             
                    backed_up_count += 1
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                    # Remove source file immediately after successful backup in per-file mode
         
     | 
| 
      
 140 
     | 
    
         
            +
                    remove_single_file(file_path) if remove_source
         
     | 
| 
       134 
141 
     | 
    
         
             
                  end
         
     | 
| 
       135 
142 
     | 
    
         
             
                  # rubocop:enable Metrics/BlockLength
         
     | 
| 
       136 
143 
     | 
    
         | 
| 
         @@ -139,9 +146,6 @@ module Ruborg 
     | 
|
| 
       139 
146 
     | 
    
         
             
                  else
         
     | 
| 
       140 
147 
     | 
    
         
             
                    puts "✓ Per-file backup completed: #{backed_up_count} file(s) backed up"
         
     | 
| 
       141 
148 
     | 
    
         
             
                  end
         
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
                  # NOTE: remove_source handled per file after successful backup
         
     | 
| 
       144 
     | 
    
         
            -
                  remove_source_files if remove_source
         
     | 
| 
       145 
149 
     | 
    
         
             
                end
         
     | 
| 
       146 
150 
     | 
    
         
             
                # rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity, Metrics/BlockNesting
         
     | 
| 
       147 
151 
     | 
    
         | 
| 
         @@ -333,6 +337,34 @@ module Ruborg 
     | 
|
| 
       333 
337 
     | 
    
         
             
                  result
         
     | 
| 
       334 
338 
     | 
    
         
             
                end
         
     | 
| 
       335 
339 
     | 
    
         | 
| 
      
 340 
     | 
    
         
            +
                def remove_single_file(file_path)
         
     | 
| 
      
 341 
     | 
    
         
            +
                  require "fileutils"
         
     | 
| 
      
 342 
     | 
    
         
            +
             
     | 
| 
      
 343 
     | 
    
         
            +
                  # Resolve symlinks and validate path
         
     | 
| 
      
 344 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 345 
     | 
    
         
            +
                    real_path = File.realpath(file_path)
         
     | 
| 
      
 346 
     | 
    
         
            +
                  rescue Errno::ENOENT
         
     | 
| 
      
 347 
     | 
    
         
            +
                    # File doesn't exist (already deleted?), skip
         
     | 
| 
      
 348 
     | 
    
         
            +
                    @logger&.warn("Source file does not exist, skipping: #{file_path}")
         
     | 
| 
      
 349 
     | 
    
         
            +
                    return
         
     | 
| 
      
 350 
     | 
    
         
            +
                  end
         
     | 
| 
      
 351 
     | 
    
         
            +
             
     | 
| 
      
 352 
     | 
    
         
            +
                  # Security check: ensure file still exists
         
     | 
| 
      
 353 
     | 
    
         
            +
                  unless File.exist?(real_path)
         
     | 
| 
      
 354 
     | 
    
         
            +
                    @logger&.warn("Source file no longer exists, skipping: #{real_path}")
         
     | 
| 
      
 355 
     | 
    
         
            +
                    return
         
     | 
| 
      
 356 
     | 
    
         
            +
                  end
         
     | 
| 
      
 357 
     | 
    
         
            +
             
     | 
| 
      
 358 
     | 
    
         
            +
                  # Additional safety: don't delete system files
         
     | 
| 
      
 359 
     | 
    
         
            +
                  if real_path == "/" || real_path.start_with?("/bin", "/sbin", "/usr", "/etc", "/sys", "/proc")
         
     | 
| 
      
 360 
     | 
    
         
            +
                    @logger&.error("Refusing to delete system path: #{real_path}")
         
     | 
| 
      
 361 
     | 
    
         
            +
                    raise BorgError, "Refusing to delete system path: #{real_path}"
         
     | 
| 
      
 362 
     | 
    
         
            +
                  end
         
     | 
| 
      
 363 
     | 
    
         
            +
             
     | 
| 
      
 364 
     | 
    
         
            +
                  @logger&.info("Removing file: #{real_path}")
         
     | 
| 
      
 365 
     | 
    
         
            +
                  FileUtils.rm(real_path)
         
     | 
| 
      
 366 
     | 
    
         
            +
                end
         
     | 
| 
      
 367 
     | 
    
         
            +
             
     | 
| 
       336 
368 
     | 
    
         
             
                def remove_source_files
         
     | 
| 
       337 
369 
     | 
    
         
             
                  require "fileutils"
         
     | 
| 
       338 
370 
     | 
    
         | 
    
        data/lib/ruborg/version.rb
    CHANGED