"files" gem - for creating temporary files and dirs

Ever want to create a whole bunch of files at once? Like when you’re
writing tests for a tool that processes files? The Files gem lets you
cleanly specify those files and their contents inside your test code,
instead of forcing you to create a fixture directory and check it in
to your repo. It puts them in a temporary directory and cleans up when
your test is done.

The API currently has two modes – mixin and function – and I would
absolutely adore feedback on which mode is more useful, or other
advice about naming the methods and especially the instance var in
mixin mode.

Usage (mixin mode):

require "files"
include Files

file "hello.txt"     # creates file "hello.txt" containing

“contents of hello.txt”

dir "web" do              # creates directory "web"
  file "snippet.html",    # creates file "web/snippet.html"...
    "<h1>Fix this!</h1>"  # ...containing "<h1>Fix this!</h1>"
  dir "img" do            # creates directory "web/img"
    file File.new("data/hello.png")            # containing a copy

of hello.png
file “hi.png”, File.new(“data/hello.png”) # and a copy of
hello.png named hi.png
end
end

Usage (bare function mode)

require "files"

temp_dir = Files do         # creates a temporary directory inside

Dir.tmpdir
file “hello.txt” # creates file “hello.txt” containing
“contents of hello.txt”
dir “web” do # creates directory “web”
file “snippet.html”, # creates file “web/snippet.html”…

Fix this!

” # …containing “

Fix this!


dir “img” do # creates directory “web/img”
file File.new(“data/hello.png”) # containing a
copy of hello.png
file “hi.png”, File.new(“data/hello.png”) # and a copy of
hello.png named hi.png
end
end
end # “Files” returns a string with the
path to the directory

More docs, examples and tests at GitHub - alexch/files

On 01/24/2012 12:03 PM, Alex C. wrote:

mixin mode.
file “snippet.html”, # creates file “web/snippet.html”…

Fix this!

” # …containing"

Fix this!

"
dir “img” do # creates directory “web/img”
file File.new(“data/hello.png”) # containing a copy
of hello.png
file “hi.png”, File.new(“data/hello.png”) # and a copy of
hello.png named hi.png
end
end

Here’s another way to do it. (FSDB does a lot of other stuff, too…)

require ‘fsdb’ # gem install fsdb
require ‘tmpdir’

data = FSDB::Database.new “data”

formats = [
FSDB::TEXT_FORMAT.when(/.txt$|.html$/),
FSDB::BINARY_FORMAT.when(/.png$/)
]

data.formats = formats

Dir.mktmpdir do |dir|
#dir = “tmp1” # for testing, use a dir that won’t be deleted

tmp = FSDB::Database.new(dir)
tmp.formats = formats

tmp[“hello.txt”] = “contents of hello.txt”
tmp[“web/snippet.html”] = “

Fix this!

img = tmp.subdb(“img”)
img[“hello.png”] = data[“hello.png”]
img[“hi.png”] = data[“hello.png”]
end

you can automatically serialize objects in yaml, json, or marshal:

require ‘yaml’
require ‘json’

Dir.mktmpdir do |dir|
#dir = “tmp2” # for testing, use a dir that won’t be deleted

tmp = FSDB::Database.new(dir)
json_format = FSDB::Format.new(
/.json$/, /.js$/,
:name => “JSON_FORMAT”,
:load => proc {|f| JSON.load(f)},
:dump => proc {|object, f| f.syswrite(JSON.dump(object))}
)
tmp.formats = formats + [FSDB::YAML_FORMAT, json_format]

tmp[“a.yaml”] = {:some => [“complex”, Object]}
tmp[“b.json”] = [“foo”, 2, 3]
end

On 01/25/2012 04:50 PM, Gavin S. wrote:

On Thu, Jan 26, 2012 at 7:13 AM, Joel VanderWerf
[email protected] wrote:

Here’s another way to do it. (FSDB does a lot of other stuff, too…)

Without looking, I’m going to guess that you created that library,
Joel. That immediately assures me of its quality, but I found some of
the API a little unwieldy.

Yeah, it’s kind of ancient (c. 2003) and could use some redesign. I
hadn’t used it for a few years. and the formats api felt awkward to me,
too.

Recently I needed it as a local alternative to Amazon S3, so at least
it’s 1.9.3 compatible, now.

formats = [
FSDB::TEXT_FORMAT.when(/.txt$|.html$/),
FSDB::BINARY_FORMAT.when(/.png$/)
]

formats = { /.txt$|.html$/ => :text, /.png$/ => :binary }

And should the programmer really have to specify these? Can’t they

be baked in?

The defaults could be better (currently the default is that .txt maps to
TEXT_FORMAT and everything else is marshalled), but many formats don’t
have a unique ruby object representation: yaml files could be strings or
objects, png could be binary strings or instances of somebody’s PNG
class… Also, file extensions are not always how you want to
discriminate; you might not even have file extensions, and use subdir
location instead.

But it should definitely be easier to turn on common formats.

img[“hello.png”] = data[“hello.png”]

I don’t get a sense of what that line is doing.

It’s reading a binary string from data/hello.png and writing it back out
to “#{dir}/img/hello.png”. Which is potentially far less efficient than
a file copy…

Seems to me that building yaml, json and marshal capabilities into the
library would be justified and worthwhile.

Sure…

I’m starting work on a project involving a lot of file and directory
manipulation, so I’ll check out fsdb enthusiastically.

Great! Hope it’s suitable, though it’s not really a general purpose
file/dir manager…

On Thu, Jan 26, 2012 at 7:13 AM, Joel VanderWerf
[email protected] wrote:

Here’s another way to do it. (FSDB does a lot of other stuff, too…)

Without looking, I’m going to guess that you created that library,
Joel. That immediately assures me of its quality, but I found some of
the API a little unwieldy.

formats = [
FSDB::TEXT_FORMAT.when(/.txt$|.html$/),
FSDB::BINARY_FORMAT.when(/.png$/)
]

formats = { /.txt$|.html$/ => :text, /.png$/ => :binary }

And should the programmer really have to specify these? Can’t they

be baked in?

img[“hello.png”] = data[“hello.png”]

I don’t get a sense of what that line is doing.

you can automatically serialize objects in yaml, json, or marshal:

[…]
json_format = FSDB::Format.new(
/.json$/, /.js$/,
:name => “JSON_FORMAT”,
:load => proc {|f| JSON.load(f)},
:dump => proc {|object, f| f.syswrite(JSON.dump(object))}
)
tmp.formats = formats + [FSDB::YAML_FORMAT, json_format]

Seems to me that building yaml, json and marshal capabilities into the
library would be justified and worthwhile.

I’m starting work on a project involving a lot of file and directory
manipulation, so I’ll check out fsdb enthusiastically.

Gavin