Skip to content

Commit

Permalink
Merge pull request #52 from ssciolla/issue-51-hidden-files
Browse files Browse the repository at this point in the history
Add optional hidden file detection (#51)
  • Loading branch information
little9 authored Jul 31, 2024
2 parents 4b09307 + 16b3780 commit 39e19cc
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 5 deletions.
26 changes: 24 additions & 2 deletions lib/bagit/bag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,40 @@
require "bagit/valid"

module BagIt
class FileFinder
def self.find(dir)
raise NotImplementedError
end
end

class StandardFileFinder < FileFinder
def self.find(dir)
Dir[File.join(dir, "**", "*")].select { |f| File.file? f }
end
end

class StandardWithHiddenFileFinder < FileFinder
def self.find(dir)
Dir.glob(File.join(dir, "**", "*"), File::FNM_DOTMATCH).select { |f| File.file? f }
end
end

# Represents the state of a bag on a filesystem
class Bag
attr_reader :bag_dir
attr_reader :detect_hidden

include Validity # Validity functionality
include Info # bagit & bag info functionality
include Manifest # manifest related functionality
include Fetch # fetch related functionality

# Make a new Bag based at path
def initialize(path, info = {}, _create = false)
def initialize(path, info = {}, _create = false, detect_hidden = false)
@bag_dir = path
@detect_hidden = detect_hidden
@file_finder = @detect_hidden ? StandardWithHiddenFileFinder : StandardFileFinder

# make the dir structure if it doesn't exist
FileUtils.mkdir bag_dir unless File.directory? bag_dir
FileUtils.mkdir data_dir unless File.directory? data_dir
Expand All @@ -37,7 +59,7 @@ def data_dir

# Return the paths to each bag file relative to bag_dir
def bag_files
Dir[File.join(data_dir, "**", "*")].select { |f| File.file? f }
@file_finder.find(data_dir)
end

# Return the paths to each tag file relative to bag_dir
Expand Down
6 changes: 5 additions & 1 deletion lib/bagit/valid.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ def complete?

empty_manifests.each do |file|
logger.error("#{file} is manifested but not present".red)
errors.add :completeness, "#{file} is manifested but not present"
error_message = "#{file} is manifested but not present"
if !detect_hidden && file.start_with?(File.join("data", "."))
error_message += "; consider turning on hidden file detection"
end
errors.add :completeness, error_message
end
tag_empty_manifests.each do |file|
logger.error("#{file} is a manifested tag but not present".red)
Expand Down
27 changes: 27 additions & 0 deletions spec/bagit_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,31 @@
end
end
end

describe "bag with hidden files" do
before do
@sandbox = Sandbox.new

# make the bag
@bag_path = File.join @sandbox.to_s, "the_bag"
@bag = described_class.new @bag_path, {}, false, true

# add some files
@bag.add_file(".keep") { |io| io.puts "" }
@bag.add_file("test.txt") { |io| io.puts "testing testing" }
end

after do
@sandbox.cleanup!
end

describe "#bag_files" do
it "returns an array including non-hidden and hidden files" do
files = @bag.bag_files.map { |f| f.sub(File.join(@bag_path, "data", ""), "") }
expect(files).to be_a_kind_of(Array)
expect(files).not_to be_empty
expect(files).to eq([".keep", "test.txt"])
end
end
end
end
67 changes: 65 additions & 2 deletions spec/validation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,17 @@

it "is invalid if there are files that are in the manifest but not in the bag" do
# add a file and then remove it through the back door
@bag.add_file("file-k") { |io| io.puts "time to go" }
file_name = "file-k"
@bag.add_file(file_name) { |io| io.puts "time to go" }
@bag.manifest!

FileUtils.rm File.join(@bag.bag_dir, "data", "file-k")
FileUtils.rm File.join(@bag.bag_dir, "data", file_name)

@bag.validate_only("true_for/completeness")
expect(@bag.errors.on(:completeness)).not_to be_empty
expect(@bag.errors.on(:completeness)).to include(
"#{File.join("data", file_name)} is manifested but not present"
)
expect(@bag).not_to be_valid
end

Expand Down Expand Up @@ -139,4 +143,63 @@
end
end
end

describe "a bag with unmanifested hidden files" do
before do
@sandbox = Sandbox.new

# make a bag with hidden files not manifested
@source_bag_path = File.join @sandbox.to_s, "the_bag"
@source_bag = described_class.new @source_bag_path, {}, false, false
@source_bag.add_file(".keep") { |io| io.puts "" }
@source_bag.add_file("test.txt") { |io| io.puts "testing testing" }
@source_bag.manifest!
end

after do
@sandbox.cleanup!
end

it "fails validation when hidden file detection is on" do
@aware_bag = described_class.new @source_bag_path, {}, false, true
expect(@aware_bag).to_not be_valid
expect(@aware_bag.errors.on(:completeness)).not_to be_empty
end

it "passes validation when hidden file detection is off" do
@unaware_bag = described_class.new @source_bag_path, {}, false, false
expect(@unaware_bag).to be_valid
end
end

describe "a bag with manifested hidden files" do
before do
@sandbox = Sandbox.new

# make a bag with hidden files manifested
@source_bag_path = File.join @sandbox.to_s, "the_bag"
@source_bag = described_class.new @source_bag_path, {}, false, true
@source_bag.add_file(".keep") { |io| io.puts "" }
@source_bag.add_file("test.txt") { |io| io.puts "testing testing" }
@source_bag.manifest!
end

after do
@sandbox.cleanup!
end

it "passes validation when hidden file detection is on" do
@aware_bag = described_class.new @source_bag_path, {}, false, true
expect(@aware_bag).to be_valid
end

it "fails validation when hidden file detection is off, with suggested fix offered" do
@unaware_bag = described_class.new @source_bag_path, {}, false, false
expect(@unaware_bag).to_not be_valid
expect(@unaware_bag.errors.on(:completeness)).not_to be_empty
expect(@unaware_bag.errors.on(:completeness)).to include(
"data/.keep is manifested but not present; consider turning on hidden file detection"
)
end
end
end

0 comments on commit 39e19cc

Please sign in to comment.