fun_with_files 0.0.15 → 0.0.18
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 +5 -5
 - data/CHANGELOG.markdown +15 -3
 - data/Gemfile +17 -7
 - data/{README.rdoc → README.markdown} +11 -10
 - data/VERSION +1 -1
 - data/lib/fun_with/files/bootstrapper.rb +87 -0
 - data/lib/fun_with/files/digest_methods.rb +30 -16
 - data/lib/fun_with/files/directory_builder.rb +4 -0
 - data/lib/fun_with/files/downloader.rb +3 -19
 - data/lib/fun_with/files/errors.rb +9 -1
 - data/lib/fun_with/files/file_manipulation_methods.rb +25 -15
 - data/lib/fun_with/files/file_path.rb +147 -150
 - data/lib/fun_with/files/file_path_class_methods.rb +23 -2
 - data/lib/fun_with/files/file_permission_methods.rb +18 -7
 - data/lib/fun_with/files/file_requirements.rb +63 -7
 - data/lib/fun_with/files/requirements/manager.rb +104 -0
 - data/lib/fun_with/files/root_path.rb +3 -3
 - data/lib/fun_with/files/stat_methods.rb +33 -0
 - data/lib/fun_with/files/string_behavior.rb +6 -2
 - data/lib/fun_with/files/utils/byte_size.rb +143 -0
 - data/lib/fun_with/files/utils/opts.rb +26 -0
 - data/lib/fun_with/files/utils/succession.rb +47 -0
 - data/lib/fun_with/files/utils/timestamp.rb +47 -0
 - data/lib/fun_with/files/utils/timestamp_format.rb +31 -0
 - data/lib/fun_with/files/watcher.rb +157 -0
 - data/lib/fun_with/files/watchers/directory_watcher.rb +67 -0
 - data/lib/fun_with/files/watchers/file_watcher.rb +45 -0
 - data/lib/fun_with/files/watchers/missing_watcher.rb +23 -0
 - data/lib/fun_with/files/watchers/node_watcher.rb +44 -0
 - data/lib/fun_with/testing/assertions/fun_with_files.rb +91 -0
 - data/lib/fun_with/testing/test_case_extensions.rb +12 -0
 - data/lib/fun_with_files.rb +5 -75
 - data/test/helper.rb +13 -5
 - data/test/test_core_extensions.rb +5 -0
 - data/test/test_directory_builder.rb +29 -10
 - data/test/test_extension_methods.rb +62 -0
 - data/test/test_file_manipulation.rb +2 -2
 - data/test/test_file_path.rb +18 -39
 - data/test/test_file_requirements.rb +36 -0
 - data/test/test_fun_with_files.rb +1 -1
 - data/test/test_fwf_assertions.rb +62 -0
 - data/test/test_moving_files.rb +111 -0
 - data/test/test_permission_methods.rb +22 -0
 - data/test/test_root_path.rb +9 -0
 - data/test/test_stat_methods.rb +17 -0
 - data/test/test_timestamping.rb +74 -0
 - data/test/test_utils_bytesize.rb +71 -0
 - data/test/test_utils_succession.rb +30 -0
 - data/test/test_watchers.rb +196 -0
 - metadata +54 -16
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 2 
     | 
    
         
            +
            SHA256:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: d22de5c44faf70d934da05efbd93f17373e8317bbc6304c5674c2f79183d45b2
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 89d022cd00c4e14be9c82fc62045e82db6095e9a16239e29c085a605c0c0cde9
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: b8fb4d70f1bc7c29439b7237e38e79f5661334fd7c8c3457f5ae1bde20b053eb95dccd5d8c5ad3bf3a4f16443375ace9f889822116680b136d154e53ab118411
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: fdd5d8bc41b89c5e0a4f3c83580f4f45679cb3bc38ee9539f332f1a26572cf68ffd549b7118787f6068d1247711cafe175cf7389a0aff1532cf6407c96384ba7
         
     | 
    
        data/CHANGELOG.markdown
    CHANGED
    
    | 
         @@ -1,13 +1,25 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            CHANGELOG
         
     | 
| 
       2 
2 
     | 
    
         
             
            =========
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
      
 4 
     | 
    
         
            +
            v0.0.18
         
     | 
| 
      
 5 
     | 
    
         
            +
            -------
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            * restricted the use of the file.succ() method, and removed timestamp functionality from it.  Now it only works if the initial file has an extension (no trailing counter, like file.000001 ).  Still fills in
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            v0.0.17
         
     | 
| 
      
 10 
     | 
    
         
            +
            -------
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            * `.without_ext()` now takes an argument, will only strip that extension.
         
     | 
| 
      
 13 
     | 
    
         
            +
            * updated `fun_with_testing` dependency, moved FunWith::Files-related stuff from that gem to this one.
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
       4 
16 
     | 
    
         
             
            v0.0.14
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
      
 17 
     | 
    
         
            +
            -------
         
     | 
| 
       6 
18 
     | 
    
         | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
      
 19 
     | 
    
         
            +
            ???
         
     | 
| 
       8 
20 
     | 
    
         | 
| 
       9 
21 
     | 
    
         
             
            v0.0.12
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
      
 22 
     | 
    
         
            +
            -------
         
     | 
| 
       11 
23 
     | 
    
         | 
| 
       12 
24 
     | 
    
         
             
            FilePath.touch() takes same options as FileUtils.touch()
         
     | 
| 
       13 
25 
     | 
    
         
             
            FilePath.glob() now takes a block (yields files one at a time)
         
     | 
    
        data/Gemfile
    CHANGED
    
    | 
         @@ -7,12 +7,22 @@ source "http://rubygems.org" 
     | 
|
| 
       7 
7 
     | 
    
         
             
            # Include everything needed to run rake, tests, features, etc.
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
            group :development do
         
     | 
| 
       10 
     | 
    
         
            -
               
     | 
| 
       11 
     | 
    
         
            -
               
     | 
| 
       12 
     | 
    
         
            -
              # gem "bundler", "~> 1.5"
         
     | 
| 
       13 
     | 
    
         
            -
              # gem "juwelier", "~> 2.0"
         
     | 
| 
       14 
     | 
    
         
            -
              # gem "debugger", "~> 1.6"
         
     | 
| 
       15 
     | 
    
         
            -
              gem "fun_with_testing", "~> 0.0", ">= 0.0.5"
         
     | 
| 
      
 10 
     | 
    
         
            +
              gem "debug"
         
     | 
| 
      
 11 
     | 
    
         
            +
              gem "fun_with_testing", "~> 0.0", ">= 0.0.7"
         
     | 
| 
       16 
12 
     | 
    
         
             
            end
         
     | 
| 
       17 
13 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            xdg_version = case RUBY_VERSION
         
     | 
| 
      
 16 
     | 
    
         
            +
                          when /^2\.7/
         
     | 
| 
      
 17 
     | 
    
         
            +
                            3
         
     | 
| 
      
 18 
     | 
    
         
            +
                          when /^3\.0/
         
     | 
| 
      
 19 
     | 
    
         
            +
                            5
         
     | 
| 
      
 20 
     | 
    
         
            +
                          when /^3\.2/
         
     | 
| 
      
 21 
     | 
    
         
            +
                            7
         
     | 
| 
      
 22 
     | 
    
         
            +
                          end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                          
         
     | 
| 
      
 26 
     | 
    
         
            +
            gem "xdg", "~> #{xdg_version}"
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
         @@ -1,4 +1,7 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            # `fun_with_files` 
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
       2 
5 
     | 
    
         | 
| 
       3 
6 
     | 
    
         
             
            FunWith::Files adds a bit of whimsy to your file manipulations, if that's what you're looking for.
         
     | 
| 
       4 
7 
     | 
    
         | 
| 
         @@ -36,18 +39,17 @@ To the code! 
     | 
|
| 
       36 
39 
     | 
    
         | 
| 
       37 
40 
     | 
    
         | 
| 
       38 
41 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
      
 42 
     | 
    
         
            +
            ### Linking files ###
         
     | 
| 
       40 
43 
     | 
    
         | 
| 
       41 
44 
     | 
    
         
             
            While fwf.symlink and fwf.link are both backed by FileUtils.ln / FileUtils.ln_s, the defaults are somewhat different
         
     | 
| 
       42 
45 
     | 
    
         | 
| 
       43 
46 
     | 
    
         | 
| 
       44 
47 
     | 
    
         | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
      
 48 
     | 
    
         
            +
            ## DirectoryBuilder ##
         
     | 
| 
       46 
49 
     | 
    
         | 
| 
       47 
50 
     | 
    
         
             
            DirectoryBuilder is a class for defining and populating a file hierarchy with relative ease.  DirectoryBuilder is probably most easily demonstrated by example.  Sample code:
         
     | 
| 
       48 
51 
     | 
    
         | 
| 
       49 
     | 
    
         
            -
                # starts by creating directory.  If parent 
         
     | 
| 
       50 
     | 
    
         
            -
                # directories don't exist, they will soon.
         
     | 
| 
      
 52 
     | 
    
         
            +
                # starts by creating directory.  If parent directories don't exist, they will soon.
         
     | 
| 
       51 
53 
     | 
    
         
             
                DirectoryBuilder.create( '~/project' ) do |b|
         
     | 
| 
       52 
54 
     | 
    
         
             
                  b.dir("images") do                      # creates subdirectory "images", which gets populated within the block
         
     | 
| 
       53 
55 
     | 
    
         
             
                    for img in src_dir.entries.select{|img| img.extension == ".png"}
         
     | 
| 
         @@ -60,7 +62,7 @@ DirectoryBuilder is a class for defining and populating a file hierarchy with re 
     | 
|
| 
       60 
62 
     | 
    
         | 
| 
       61 
63 
     | 
    
         
             
                  b.dir("text", "scenes") do   # creates ~/project/text/scenes subdir (creating two new directories text/ and text/scene/)
         
     | 
| 
       62 
64 
     | 
    
         
             
                    b.file( "adventure_time.txt" ) do |f|
         
     | 
| 
       63 
     | 
    
         
            -
                      f << "Fill this in later"
         
     | 
| 
      
 65 
     | 
    
         
            +
                      f << "Fill this in later"             # text is written to the file
         
     | 
| 
       64 
66 
     | 
    
         
             
                    end
         
     | 
| 
       65 
67 
     | 
    
         | 
| 
       66 
68 
     | 
    
         
             
                    # calling .file without feeding it a block leaves it open for writing,
         
     | 
| 
         @@ -106,7 +108,7 @@ DirectoryBuilder is a class for defining and populating a file hierarchy with re 
     | 
|
| 
       106 
108 
     | 
    
         | 
| 
       107 
109 
     | 
    
         | 
| 
       108 
110 
     | 
    
         | 
| 
       109 
     | 
    
         
            -
             
     | 
| 
      
 111 
     | 
    
         
            +
            ## Contributing to fun_with_files ##
         
     | 
| 
       110 
112 
     | 
    
         | 
| 
       111 
113 
     | 
    
         
             
            Boilerplate from Juwelier, but seems to make sense.
         
     | 
| 
       112 
114 
     | 
    
         | 
| 
         @@ -118,8 +120,7 @@ Boilerplate from Juwelier, but seems to make sense. 
     | 
|
| 
       118 
120 
     | 
    
         
             
            * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
         
     | 
| 
       119 
121 
     | 
    
         
             
            * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
         
     | 
| 
       120 
122 
     | 
    
         | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
      
 123 
     | 
    
         
            +
            ## Copyright ##
         
     | 
| 
       122 
124 
     | 
    
         | 
| 
       123 
     | 
    
         
            -
            Copyright (c)  
     | 
| 
       124 
     | 
    
         
            -
            further details.
         
     | 
| 
      
 125 
     | 
    
         
            +
            Copyright (c) 2020 Bryce Anderson. See LICENSE.txt for further details.
         
     | 
| 
       125 
126 
     | 
    
         | 
    
        data/VERSION
    CHANGED
    
    | 
         @@ -1 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            0.0. 
     | 
| 
      
 1 
     | 
    
         
            +
            0.0.18
         
     | 
| 
         @@ -0,0 +1,87 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module FunWith
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Files
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Bootstrapper
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def self.bootstrap
         
     | 
| 
      
 5 
     | 
    
         
            +
                    self.new.bootstrap
         
     | 
| 
      
 6 
     | 
    
         
            +
                  end
         
     | 
| 
      
 7 
     | 
    
         
            +
                  
         
     | 
| 
      
 8 
     | 
    
         
            +
                  def bootstrap
         
     | 
| 
      
 9 
     | 
    
         
            +
                    load_core_extensions
         
     | 
| 
      
 10 
     | 
    
         
            +
                    install_minimal_requir_functionality
         
     | 
| 
      
 11 
     | 
    
         
            +
                    run_requir
         
     | 
| 
      
 12 
     | 
    
         
            +
                    rootify
         
     | 
| 
      
 13 
     | 
    
         
            +
                    add_filepath_class_methods
         
     | 
| 
      
 14 
     | 
    
         
            +
                    extend_gem_api
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  
         
     | 
| 
      
 17 
     | 
    
         
            +
                  protected
         
     | 
| 
      
 18 
     | 
    
         
            +
                  # gets all the core-extending modules from fun_with/files/core_extensions and uses them to
         
     | 
| 
      
 19 
     | 
    
         
            +
                  # beef up the core classes
         
     | 
| 
      
 20 
     | 
    
         
            +
                  def load_core_extensions
         
     | 
| 
      
 21 
     | 
    
         
            +
                    for file in Dir.glob( File.join( __dir__, "core_extensions", "*.rb" ) )
         
     | 
| 
      
 22 
     | 
    
         
            +
                      # remove trailing extension to make it require-friendly.
         
     | 
| 
      
 23 
     | 
    
         
            +
                      file = file.gsub(/\.rb$/,'')
         
     | 
| 
      
 24 
     | 
    
         
            +
                      
         
     | 
| 
      
 25 
     | 
    
         
            +
                      require_relative file
         
     | 
| 
      
 26 
     | 
    
         
            +
                      
         
     | 
| 
      
 27 
     | 
    
         
            +
                      # convert filename into class name
         
     | 
| 
      
 28 
     | 
    
         
            +
                      target_class_str = filename_to_class_name( file )
         
     | 
| 
      
 29 
     | 
    
         
            +
                      
         
     | 
| 
      
 30 
     | 
    
         
            +
                      # get the core class that needs extending, and the 
         
     | 
| 
      
 31 
     | 
    
         
            +
                      target_class = Kernel.const_get( target_class_str )
         
     | 
| 
      
 32 
     | 
    
         
            +
                      mixin_class  = Kernel.const_get( "FunWith::Files::CoreExtensions::#{target_class_str}" )
         
     | 
| 
      
 33 
     | 
    
         
            +
                      
         
     | 
| 
      
 34 
     | 
    
         
            +
                      target_class.send( :include, mixin_class )
         
     | 
| 
      
 35 
     | 
    
         
            +
                    end
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
                  
         
     | 
| 
      
 38 
     | 
    
         
            +
                  def install_minimal_requir_functionality
         
     | 
| 
      
 39 
     | 
    
         
            +
                    for fil in %w( file_path
         
     | 
| 
      
 40 
     | 
    
         
            +
                                   string_behavior
         
     | 
| 
      
 41 
     | 
    
         
            +
                                   file_manipulation_methods
         
     | 
| 
      
 42 
     | 
    
         
            +
                                   file_permission_methods
         
     | 
| 
      
 43 
     | 
    
         
            +
                                   digest_methods
         
     | 
| 
      
 44 
     | 
    
         
            +
                                   file_requirements
         
     | 
| 
      
 45 
     | 
    
         
            +
                                   requirements/manager
         
     | 
| 
      
 46 
     | 
    
         
            +
                                   stat_methods )
         
     | 
| 
      
 47 
     | 
    
         
            +
                      require_relative fil
         
     | 
| 
      
 48 
     | 
    
         
            +
                    end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                    # These have some FilePath methods required by .requir()
         
     | 
| 
      
 51 
     | 
    
         
            +
                    for mod in [ FunWith::Files::StringBehavior,
         
     | 
| 
      
 52 
     | 
    
         
            +
                                 FunWith::Files::FileManipulationMethods, 
         
     | 
| 
      
 53 
     | 
    
         
            +
                                 FunWith::Files::FilePermissionMethods, 
         
     | 
| 
      
 54 
     | 
    
         
            +
                                 FunWith::Files::DigestMethods,
         
     | 
| 
      
 55 
     | 
    
         
            +
                                 FunWith::Files::FileRequirements,
         
     | 
| 
      
 56 
     | 
    
         
            +
                                 FunWith::Files::StatMethods ]
         
     | 
| 
      
 57 
     | 
    
         
            +
                      FunWith::Files::FilePath.send( :include, mod )
         
     | 
| 
      
 58 
     | 
    
         
            +
                    end
         
     | 
| 
      
 59 
     | 
    
         
            +
                  end
         
     | 
| 
      
 60 
     | 
    
         
            +
                  
         
     | 
| 
      
 61 
     | 
    
         
            +
                  def run_requir
         
     | 
| 
      
 62 
     | 
    
         
            +
                    lib_dir = __dir__.fwf_filepath.up
         
     | 
| 
      
 63 
     | 
    
         
            +
                    
         
     | 
| 
      
 64 
     | 
    
         
            +
                    # And requir() everything else
         
     | 
| 
      
 65 
     | 
    
         
            +
                    lib_dir.requir
         
     | 
| 
      
 66 
     | 
    
         
            +
                  end
         
     | 
| 
      
 67 
     | 
    
         
            +
                  
         
     | 
| 
      
 68 
     | 
    
         
            +
                  def rootify
         
     | 
| 
      
 69 
     | 
    
         
            +
                    root_dir = __dir__.fwf_filepath.up.up.up
         
     | 
| 
      
 70 
     | 
    
         
            +
                    FunWith::Files::RootPath.rootify( FunWith::Files, root_dir )
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
                  
         
     | 
| 
      
 73 
     | 
    
         
            +
                  def add_filepath_class_methods
         
     | 
| 
      
 74 
     | 
    
         
            +
                    FunWith::Files::FilePath.extend( FunWith::Files::FilePathClassMethods )
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
                  
         
     | 
| 
      
 77 
     | 
    
         
            +
                  def extend_gem_api
         
     | 
| 
      
 78 
     | 
    
         
            +
                    FunWith::Files.extend( FunWith::Files::GemAPI )
         
     | 
| 
      
 79 
     | 
    
         
            +
                  end
         
     | 
| 
      
 80 
     | 
    
         
            +
                  
         
     | 
| 
      
 81 
     | 
    
         
            +
                  
         
     | 
| 
      
 82 
     | 
    
         
            +
                  def filename_to_class_name( str )
         
     | 
| 
      
 83 
     | 
    
         
            +
                    File.basename( str ).split( "_" ).map(&:capitalize).join("")
         
     | 
| 
      
 84 
     | 
    
         
            +
                  end
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
              end
         
     | 
| 
      
 87 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -3,36 +3,47 @@ module FunWith 
     | 
|
| 
       3 
3 
     | 
    
         
             
                DIGEST_METHODS = [:md5, :sha1, :sha2, :sha224, :sha256, :sha384, :sha512]
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
                module DigestMethods
         
     | 
| 
       6 
     | 
    
         
            -
                  def md5
         
     | 
| 
       7 
     | 
    
         
            -
                    digest( Digest::MD5 )
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def md5( bytes = :all, offset = 0 )
         
     | 
| 
      
 7 
     | 
    
         
            +
                    digest( Digest::MD5, bytes, offset )
         
     | 
| 
       8 
8 
     | 
    
         
             
                  end
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                  def sha1
         
     | 
| 
       11 
     | 
    
         
            -
                    digest( Digest::SHA1 )
         
     | 
| 
      
 10 
     | 
    
         
            +
                  def sha1( bytes = :all, offset = 0 )
         
     | 
| 
      
 11 
     | 
    
         
            +
                    digest( Digest::SHA1, bytes, offset )
         
     | 
| 
       12 
12 
     | 
    
         
             
                  end
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
                  def sha2
         
     | 
| 
       15 
     | 
    
         
            -
                    digest( Digest::SHA2 )
         
     | 
| 
      
 14 
     | 
    
         
            +
                  def sha2( bytes = :all, offset = 0 )
         
     | 
| 
      
 15 
     | 
    
         
            +
                    digest( Digest::SHA2, bytes, offset )
         
     | 
| 
       16 
16 
     | 
    
         
             
                  end
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
                  def sha224
         
     | 
| 
       19 
     | 
    
         
            -
                    digest( Digest::SHA224 )
         
     | 
| 
      
 18 
     | 
    
         
            +
                  def sha224( bytes = :all, offset = 0 )
         
     | 
| 
      
 19 
     | 
    
         
            +
                    digest( Digest::SHA224, bytes, offset )
         
     | 
| 
       20 
20 
     | 
    
         
             
                  end
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
                  def sha256
         
     | 
| 
       23 
     | 
    
         
            -
                    digest( Digest::SHA256 )
         
     | 
| 
      
 22 
     | 
    
         
            +
                  def sha256( bytes = :all, offset = 0 )
         
     | 
| 
      
 23 
     | 
    
         
            +
                    digest( Digest::SHA256, bytes, offset )
         
     | 
| 
       24 
24 
     | 
    
         
             
                  end
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
     | 
    
         
            -
                  def sha384
         
     | 
| 
       27 
     | 
    
         
            -
                    digest( Digest::SHA384 )
         
     | 
| 
      
 26 
     | 
    
         
            +
                  def sha384( bytes = :all, offset = 0 )
         
     | 
| 
      
 27 
     | 
    
         
            +
                    digest( Digest::SHA384, bytes, offset )
         
     | 
| 
       28 
28 
     | 
    
         
             
                  end
         
     | 
| 
       29 
29 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
                  def sha512
         
     | 
| 
       31 
     | 
    
         
            -
                    digest( Digest::SHA512 )
         
     | 
| 
      
 30 
     | 
    
         
            +
                  def sha512( bytes = :all, offset = 0 )
         
     | 
| 
      
 31 
     | 
    
         
            +
                    digest( Digest::SHA512, bytes, offset )
         
     | 
| 
       32 
32 
     | 
    
         
             
                  end
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
                  def digest( digest_class = Digest::MD5 )
         
     | 
| 
       35 
     | 
    
         
            -
                    self.file?  
     | 
| 
      
 34 
     | 
    
         
            +
                  def digest( digest_class = Digest::MD5, bytes = :all, offset = 0  )
         
     | 
| 
      
 35 
     | 
    
         
            +
                    if self.file? && self.readable?
         
     | 
| 
      
 36 
     | 
    
         
            +
                      if bytes == :all
         
     | 
| 
      
 37 
     | 
    
         
            +
                        digest_class.hexdigest( self.read )
         
     | 
| 
      
 38 
     | 
    
         
            +
                      elsif bytes.is_a?( Integer )
         
     | 
| 
      
 39 
     | 
    
         
            +
                        digest_class.hexdigest( self.read( bytes, offset ) )
         
     | 
| 
      
 40 
     | 
    
         
            +
                      else
         
     | 
| 
      
 41 
     | 
    
         
            +
                        raise ArgumentError.new( "FunWith::Files::DigestMethods.digest() error: bytes argument must be an integer or :all")
         
     | 
| 
      
 42 
     | 
    
         
            +
                      end
         
     | 
| 
      
 43 
     | 
    
         
            +
                    else
         
     | 
| 
      
 44 
     | 
    
         
            +
                      raise IOError.new( "Not a file: #{self.path}" ) unless self.file?
         
     | 
| 
      
 45 
     | 
    
         
            +
                      raise IOError.new( "Not readable: #{self.path}" ) unless self.readable?
         
     | 
| 
      
 46 
     | 
    
         
            +
                    end
         
     | 
| 
       36 
47 
     | 
    
         
             
                  end
         
     | 
| 
       37 
48 
     | 
    
         | 
| 
       38 
49 
     | 
    
         
             
                  # Takes any of the above-named digest functions, determines
         
     | 
| 
         @@ -43,6 +54,9 @@ module FunWith 
     | 
|
| 
       43 
54 
     | 
    
         
             
                  # TODO: how to get around the :md6 problem?  That is, where the
         
     | 
| 
       44 
55 
     | 
    
         
             
                  # user is sending the wrong key, and hence not getting false back
         
     | 
| 
       45 
56 
     | 
    
         
             
                  def valid_digest?( opts )
         
     | 
| 
      
 57 
     | 
    
         
            +
                    digest_opts = Utils::Opts.narrow_options( opts, DIGEST_METHODS )
         
     | 
| 
      
 58 
     | 
    
         
            +
                    
         
     | 
| 
      
 59 
     | 
    
         
            +
                    
         
     | 
| 
       46 
60 
     | 
    
         
             
                    for method, digest in opts
         
     | 
| 
       47 
61 
     | 
    
         
             
                      if DIGEST_METHODS.include?( method )
         
     | 
| 
       48 
62 
     | 
    
         
             
                        return false unless self.send( method ) == digest
         
     | 
| 
         @@ -41,6 +41,9 @@ module FunWith 
     | 
|
| 
       41 
41 
     | 
    
         | 
| 
       42 
42 
     | 
    
         
             
                  # Copies the given source file into a file in the current_path.
         
     | 
| 
       43 
43 
     | 
    
         
             
                  # If a dest_name is given, the new file will be given that name.
         
     | 
| 
      
 44 
     | 
    
         
            +
                  #
         
     | 
| 
      
 45 
     | 
    
         
            +
                  # TODO: Improve testing, explain behavior better, need a way to distinguish between 
         
     | 
| 
      
 46 
     | 
    
         
            +
                  # forceful and gentle copying
         
     | 
| 
       44 
47 
     | 
    
         
             
                  def copy( src_filepath, dst_name = nil )
         
     | 
| 
       45 
48 
     | 
    
         
             
                    dst_filepath = dst_name ? @current_path.join( dst_name ) : @current_path
         
     | 
| 
       46 
49 
     | 
    
         
             
                    FileUtils.copy( src_filepath, dst_filepath )
         
     | 
| 
         @@ -96,6 +99,7 @@ module FunWith 
     | 
|
| 
       96 
99 
     | 
    
         
             
                    end
         
     | 
| 
       97 
100 
     | 
    
         
             
                  end
         
     | 
| 
       98 
101 
     | 
    
         | 
| 
      
 102 
     | 
    
         
            +
                  # The actual method is installed by 'fun_with_templates'
         
     | 
| 
       99 
103 
     | 
    
         
             
                  def template( *args )
         
     | 
| 
       100 
104 
     | 
    
         
             
                    raise "DirectoryBuilder cannot use template() function.  require 'fun_with_templates' to enable."
         
     | 
| 
       101 
105 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -22,7 +22,7 @@ module FunWith 
     | 
|
| 
       22 
22 
     | 
    
         
             
                    @uri = URI.parse( url )
         
     | 
| 
       23 
23 
     | 
    
         
             
                    @io  = io
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
                    open( url ) do |f|
         
     | 
| 
      
 25 
     | 
    
         
            +
                    URI.open( url ) do |f|
         
     | 
| 
       26 
26 
     | 
    
         
             
                      @io << f.read
         
     | 
| 
       27 
27 
     | 
    
         
             
                    end
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
         @@ -40,26 +40,10 @@ module FunWith 
     | 
|
| 
       40 
40 
     | 
    
         
             
                      warn( "File did not download correctly, or was deleted: #{io_path}")
         
     | 
| 
       41 
41 
     | 
    
         
             
                      false
         
     | 
| 
       42 
42 
     | 
    
         
             
                    end
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                    # @io << Net::HTTP.get( @uri )
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                    # Net::HTTP.start( @uri.host, @uri.port ) do |http| 
         
     | 
| 
       47 
     | 
    
         
            -
                    #   http.request_get( @uri.path ) do |request| 
         
     | 
| 
       48 
     | 
    
         
            -
                    #     request.read_body do |seg|
         
     | 
| 
       49 
     | 
    
         
            -
                    #       puts "==============================  #{seg} ============================="
         
     | 
| 
       50 
     | 
    
         
            -
                    #       io << seg
         
     | 
| 
       51 
     | 
    
         
            -
                    #       #hack -- adjust to suit:
         
     | 
| 
       52 
     | 
    
         
            -
                    #       sleep 0.005 
         
     | 
| 
       53 
     | 
    
         
            -
                    #     end
         
     | 
| 
       54 
     | 
    
         
            -
                    #   end
         
     | 
| 
       55 
     | 
    
         
            -
                    # end
         
     | 
| 
       56 
     | 
    
         
            -
                    
         
     | 
| 
       57 
     | 
    
         
            -
                    
         
     | 
| 
       58 
     | 
    
         
            -
                    
         
     | 
| 
       59 
     | 
    
         
            -
                    
         
     | 
| 
       60 
     | 
    
         
            -
                  rescue Exception => e
         
     | 
| 
      
 43 
     | 
    
         
            +
                  rescue StandardError => e
         
     | 
| 
       61 
44 
     | 
    
         
             
                    handle_network_errors( e )
         
     | 
| 
       62 
45 
     | 
    
         
             
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
                  
         
     | 
| 
       63 
47 
     | 
    
         | 
| 
       64 
48 
     | 
    
         
             
                  def handle_network_errors( e )
         
     | 
| 
       65 
49 
     | 
    
         
             
                    raise e
         
     | 
| 
         @@ -1,5 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module FunWith
         
     | 
| 
       2 
2 
     | 
    
         
             
              module Files
         
     | 
| 
       3 
     | 
    
         
            -
                 
     | 
| 
      
 3 
     | 
    
         
            +
                # Useful... why, exactly?
         
     | 
| 
      
 4 
     | 
    
         
            +
                module Errors
         
     | 
| 
      
 5 
     | 
    
         
            +
                  class Error < StandardError; end
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class SuccessionFormattingError < Error; end
         
     | 
| 
      
 7 
     | 
    
         
            +
                  class TimestampFormatUnrecognized < Error; end
         
     | 
| 
      
 8 
     | 
    
         
            +
                  class FileNotEmpty < Error; end
         
     | 
| 
      
 9 
     | 
    
         
            +
                  class NotADirectory < Error; end
         
     | 
| 
      
 10 
     | 
    
         
            +
                  class NotAFile < Error; end
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
       4 
12 
     | 
    
         
             
              end
         
     | 
| 
       5 
13 
     | 
    
         
             
            end
         
     | 
| 
         @@ -15,6 +15,12 @@ module FunWith 
     | 
|
| 
       15 
15 
     | 
    
         
             
                  # ln_s(list, destdir, options)
         
     | 
| 
       16 
16 
     | 
    
         
             
                  # ln_sf(src, dest, options)
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
      
 18 
     | 
    
         
            +
                  # 
         
     | 
| 
      
 19 
     | 
    
         
            +
                  
         
     | 
| 
      
 20 
     | 
    
         
            +
                  
         
     | 
| 
      
 21 
     | 
    
         
            +
                 # => [:alias_method, :ancestors, :attr, :attr_accessor, :attr_reader, :attr_writer, :autoload, :autoload?, :cd, :chdir, :chmod, :chmod_R, :chown, :chown_R, :class_eval, :class_exec, :class_variable_defined?, :class_variable_get, :class_variable_set, :class_variables, :cmp, :collect_method, :commands, :compare_file, :compare_stream, :const_defined?, :const_get, :const_missing, :const_set, :constants, :copy, :copy_entry, :copy_file, :copy_stream, :cp, :cp_r, :define_method, :deprecate_constant, :getwd, :have_option?, :identical?, :include, :include?, :included_modules, :install, :instance_method, :instance_methods, :link, :ln, :ln_s, :ln_sf, :makedirs, :method_defined?, :mkdir, :mkdir_p, :mkpath, :module_eval, :module_exec, :move, :mv, :name, :options, :options_of, :prepend, :private_class_method, :private_constant, :private_instance_methods, :private_method_defined?, :private_module_function, :protected_instance_methods, :protected_method_defined?, :public_class_method, :public_constant, :public_instance_method, :public_instance_methods, :public_method_defined?, :pwd, :remove, :remove_class_variable, :remove_dir, :remove_entry, :remove_entry_secure, :remove_file, :remove_method, :rm, :rm_f, :rm_r, :rm_rf, :rmdir, :rmtree, :safe_unlink, :singleton_class?, :symlink, :touch, :undef_method, :uptodate?] 
         
     | 
| 
      
 22 
     | 
    
         
            +
                  
         
     | 
| 
      
 23 
     | 
    
         
            +
                  
         
     | 
| 
       18 
24 
     | 
    
         
             
                  # opts are the last argument, and are passed to FileUtils.cp_r
         
     | 
| 
       19 
25 
     | 
    
         
             
                  # returns the destination path.
         
     | 
| 
       20 
26 
     | 
    
         
             
                  # How to detect failure?  What to return on failure?
         
     | 
| 
         @@ -22,16 +28,22 @@ module FunWith 
     | 
|
| 
       22 
28 
     | 
    
         
             
                  # 
         
     | 
| 
       23 
29 
     | 
    
         
             
                  def cp( *args )
         
     | 
| 
       24 
30 
     | 
    
         
             
                    destination_and_options( args ) do |dest, opts|
         
     | 
| 
       25 
     | 
    
         
            -
                      FileUtils.cp_r( self, dest,  
     | 
| 
      
 31 
     | 
    
         
            +
                      FileUtils.cp_r( self, dest, ** Utils::Opts.narrow_file_utils_options( opts, :cp_r ) )
         
     | 
| 
       26 
32 
     | 
    
         
             
                      dest.fwf_filepath
         
     | 
| 
       27 
33 
     | 
    
         
             
                    end
         
     | 
| 
       28 
34 
     | 
    
         
             
                  end
         
     | 
| 
       29 
35 
     | 
    
         | 
| 
       30 
36 
     | 
    
         
             
                  alias :copy :cp
         
     | 
| 
       31 
37 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
                  # Treat as a copy then a delete?  Nah, that's a lot slower  
     | 
| 
       33 
     | 
    
         
            -
                   
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
      
 38 
     | 
    
         
            +
                  # Treat as a copy then a delete?  Nah, that's a lot slower especially for larger files.  Should be much more in tune with what the command line program does.
         
     | 
| 
      
 39 
     | 
    
         
            +
                  # Treat it as syntactic sugar for FileUtils.mv?
         
     | 
| 
      
 40 
     | 
    
         
            +
                  # Also want to update the path to the new location - not implemented yet
         
     | 
| 
      
 41 
     | 
    
         
            +
                  #
         
     | 
| 
      
 42 
     | 
    
         
            +
                  # 
         
     | 
| 
      
 43 
     | 
    
         
            +
                  def mv( dst, options = {} )
         
     | 
| 
      
 44 
     | 
    
         
            +
                    # what does FileUtils.rm actually return?  Glancing an the source, it
         
     | 
| 
      
 45 
     | 
    
         
            +
                    # seems to only throw errors.
         
     | 
| 
      
 46 
     | 
    
         
            +
                    FileUtils.mv( self, dst, **options )
         
     | 
| 
       35 
47 
     | 
    
         
             
                  end
         
     | 
| 
       36 
48 
     | 
    
         | 
| 
       37 
49 
     | 
    
         
             
                  alias :move :mv
         
     | 
| 
         @@ -45,13 +57,11 @@ module FunWith 
     | 
|
| 
       45 
57 
     | 
    
         
             
                  def link *args
         
     | 
| 
       46 
58 
     | 
    
         
             
                    self.destination_and_options( args ) do |lnk, opts|
         
     | 
| 
       47 
59 
     | 
    
         
             
                      symlink_requested = self.directory? || opts[:symbolic] || opts[:sym] || opts[:soft]
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
      
 60 
     | 
    
         
            +
                      
         
     | 
| 
       49 
61 
     | 
    
         
             
                      if symlink_requested
         
     | 
| 
       50 
62 
     | 
    
         
             
                        self.symlink lnk, opts
         
     | 
| 
       51 
63 
     | 
    
         
             
                      else
         
     | 
| 
       52 
     | 
    
         
            -
                         
     | 
| 
       53 
     | 
    
         
            -
                        
         
     | 
| 
       54 
     | 
    
         
            -
                        FileUtils.ln self, lnk, opts
         
     | 
| 
      
 64 
     | 
    
         
            +
                        FileUtils.ln self, lnk, ** Utils::Opts.narrow_file_utils_options( opts, :ln )
         
     | 
| 
       55 
65 
     | 
    
         
             
                      end
         
     | 
| 
       56 
66 
     | 
    
         | 
| 
       57 
67 
     | 
    
         
             
                      lnk.fwf_filepath
         
     | 
| 
         @@ -78,7 +88,7 @@ module FunWith 
     | 
|
| 
       78 
88 
     | 
    
         
             
                      lnk = lnk.fwf_filepath
         
     | 
| 
       79 
89 
     | 
    
         
             
                    end
         
     | 
| 
       80 
90 
     | 
    
         | 
| 
       81 
     | 
    
         
            -
                    FileUtils.ln_s( self, lnk,  
     | 
| 
      
 91 
     | 
    
         
            +
                    FileUtils.ln_s( self, lnk, ** Utils::Opts.narrow_file_utils_options( opts, :ln_s ) )
         
     | 
| 
       82 
92 
     | 
    
         
             
                    lnk.fwf_filepath
         
     | 
| 
       83 
93 
     | 
    
         
             
                  end
         
     | 
| 
       84 
94 
     | 
    
         | 
| 
         @@ -86,7 +96,7 @@ module FunWith 
     | 
|
| 
       86 
96 
     | 
    
         | 
| 
       87 
97 
     | 
    
         | 
| 
       88 
98 
     | 
    
         
             
                  def file_gsub( *args, &block )
         
     | 
| 
       89 
     | 
    
         
            -
                     
     | 
| 
      
 99 
     | 
    
         
            +
                    must_be_file
         
     | 
| 
       90 
100 
     | 
    
         | 
| 
       91 
101 
     | 
    
         
             
                    lines = []
         
     | 
| 
       92 
102 
     | 
    
         
             
                    self.each_line do |line|
         
     | 
| 
         @@ -97,8 +107,8 @@ module FunWith 
     | 
|
| 
       97 
107 
     | 
    
         
             
                  end
         
     | 
| 
       98 
108 
     | 
    
         | 
| 
       99 
109 
     | 
    
         
             
                  def file_gsub!( *args, &block )
         
     | 
| 
       100 
     | 
    
         
            -
                     
     | 
| 
       101 
     | 
    
         
            -
                     
     | 
| 
      
 110 
     | 
    
         
            +
                    must_be_file      # raises error
         
     | 
| 
      
 111 
     | 
    
         
            +
                    must_be_writable    # raises error
         
     | 
| 
       102 
112 
     | 
    
         | 
| 
       103 
113 
     | 
    
         
             
                    self.write( self.file_gsub( *args, &block ) )
         
     | 
| 
       104 
114 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -113,9 +123,9 @@ module FunWith 
     | 
|
| 
       113 
123 
     | 
    
         | 
| 
       114 
124 
     | 
    
         
             
                  # TODO: If it's truncated to a longer length than the original file,
         
     | 
| 
       115 
125 
     | 
    
         
             
                  # pad with zeros?  That's how the UNIX truncate command works.
         
     | 
| 
       116 
     | 
    
         
            -
                  def truncate( len )
         
     | 
| 
       117 
     | 
    
         
            -
                     
     | 
| 
       118 
     | 
    
         
            -
                     
     | 
| 
      
 126 
     | 
    
         
            +
                  def truncate( len = 0 )
         
     | 
| 
      
 127 
     | 
    
         
            +
                    must_be_file     # raises error
         
     | 
| 
      
 128 
     | 
    
         
            +
                    must_be_writable   # raises error
         
     | 
| 
       119 
129 
     | 
    
         | 
| 
       120 
130 
     | 
    
         
             
                    old_size = self.size
         
     | 
| 
       121 
131 
     | 
    
         
             
                    padding = len > old_size ? "\0" * (len - old_size) : ""
         
     |