1 package File::Tree::Snapshot;
6 our $VERSION = '0.000001';
7 $VERSION = eval $VERSION;
9 has storage_path => (is => 'ro', required => 1);
11 has allow_empty => (is => 'ro');
13 sub file { join '/', (shift)->storage_path, @_}
16 my ($self, $mode, $file, %opt) = @_;
17 $file = $self->file($file)
18 unless $opt{is_absolute};
19 $self->_mkpath(dirname $file)
21 open my $fh, $mode, $file
22 or die "Unable to write '$file': $!\n";
27 my ($self, $dir) = @_;
28 mkpath($dir, { error => \(my $err) });
30 warn "Error while attempting to create '$dir': $_\n"
31 for map { (values %$_) } @$err;
37 my ($self, $cmd) = @_;
38 system($cmd) and die "Error during ($cmd)\n";
43 my ($self, @cmd) = @_;
44 my $path = $self->storage_path;
45 #local $ENV{GIT_DIR} = "$path/.git";
47 sprintf q{cd %s && git %s},
55 my $path = $self->storage_path;
56 $self->_mkpath($path);
57 $self->_git_exec('init');
63 my $path = $self->storage_path;
64 my @changes = `cd $path && git diff --name-only --cached`;
65 return scalar @changes;
70 $self->_git_exec('add .');
71 unless ($self->_has_changes) {
75 $self->_git_exec('commit',
77 ($self->allow_empty ? '--allow-empty' : ()),
78 '-m' => sprintf('"Updated on %s"', scalar localtime),
85 $self->_git_exec('add .');
86 $self->_git_exec('checkout -f');
92 return -e join '/', $self->storage_path, '.git';
96 my ($self, $ext, @path) = @_;
97 my $root = $self->file(@path);
98 my @files = `find $root -name '*.$ext' -type f`;
107 File::Tree::Snapshot - Snapshot files in a git repository
111 use File::Tree::Snapshot;
113 my $tree = File::Tree::Snapshot->new(
114 storage_path => '/path/to/tree',
118 unless $tree->exists;
120 # modify files, see methods below
128 This module manages snapshots of file system trees by wrapping the C<git>
129 command line interface. It currently only manages generating the snapshots.
131 The directories are standard Git repositories and can be accessed in the
138 The path to the tree that should hold the files that are snapshot. This
139 attribute is required.
143 If this attribute is set to true, commits will be created even if no changes
150 my $tree = File::Tree::Snapshot->new(%attributes);
152 Constructor. See L</ATTRIBUTES> for possible parameters.
156 my $path = $tree->file(@relative_path_parts_to_file);
158 Takes a set of path parts and returns the path to the file inside the
163 my $fh = $tree->open($mode, $file, %options);
165 Opens a file within the storage. C<$mode> is passed straight to
166 L<perlfunc/open>. The C<$file> is a relative path inside the storage.
168 Possible options are:
172 =item * C<is_absolute>
174 If set to true the C<$file> will be assumed to already be an absolute
175 path as returned by L</file>, instead of a path relative to the storage.
179 Create the path to the file if it doesn't already exist.
187 Create the directory (if it doesn't exist yet) and initialize it as a
192 my $does_exist = $tree->exists;
194 Returns true if the storage is an initialized Git repository.
198 Will commit the changes made to the tree to the Git repository.
202 Rolls back the changes since the last snapshot.