turned into a distribution
[scpubgit/File-Tree-Snapshot.git] / lib / File / Tree / Snapshot.pm
1 package File::Tree::Snapshot;
2 use Moo;
3 use File::Path;
4 use File::Basename;
5
6 our $VERSION = '0.000001';
7 $VERSION = eval $VERSION;
8
9 has storage_path => (is => 'ro', required => 1);
10
11 has allow_empty => (is => 'ro');
12
13 sub file { join '/', (shift)->storage_path, @_}
14
15 sub open {
16     my ($self, $mode, $file, %opt) = @_;
17     $file = $self->file($file)
18         unless $opt{is_absolute};
19     $self->_mkpath(dirname $file)
20         if $opt{mkpath};
21     open my $fh, $mode, $file
22         or die "Unable to write '$file': $!\n";
23     return $fh;
24 }
25
26 sub _mkpath {
27     my ($self, $dir) = @_;
28     mkpath($dir, { error => \(my $err) });
29     if (@$err) {
30         warn "Error while attempting to create '$dir': $_\n"
31             for map { (values %$_) } @$err;
32     }
33     return 1;
34 }
35
36 sub _exec {
37     my ($self, $cmd) = @_;
38     system($cmd) and die "Error during ($cmd)\n";
39     return 1;
40 }
41
42 sub _git_exec {
43     my ($self, @cmd) = @_;
44     my $path = $self->storage_path;
45     #local $ENV{GIT_DIR} = "$path/.git";
46     return $self->_exec(
47         sprintf q{cd %s && git %s},
48             $path,
49             join ' ', @cmd,
50     );
51 }
52
53 sub create {
54     my ($self) = @_;
55     my $path = $self->storage_path;
56     $self->_mkpath($path);
57     $self->_git_exec('init');
58     return 1;
59 }
60
61 sub _has_changes {
62     my ($self) = @_;
63     my $path = $self->storage_path;
64     my @changes = `cd $path && git diff --name-only --cached`;
65     return scalar @changes;
66 }
67
68 sub commit {
69     my ($self) = @_;
70     $self->_git_exec('add .');
71     unless ($self->_has_changes) {
72         print "No changes\n";
73         return 1;
74     }
75     $self->_git_exec('commit',
76         '--all',
77         ($self->allow_empty ? '--allow-empty' : ()),
78         '-m' => sprintf('"Updated on %s"', scalar localtime),
79     );
80     return 1;
81 }
82
83 sub reset {
84     my ($self) = @_;
85     $self->_git_exec('add .');
86     $self->_git_exec('checkout -f');
87     return 1;
88 }
89
90 sub exists {
91     my ($self) = @_;
92     return -e join '/', $self->storage_path, '.git';
93 }
94
95 sub find_files {
96     my ($self, $ext, @path) = @_;
97     my $root = $self->file(@path);
98     my @files = `find $root -name '*.$ext' -type f`;
99     chomp @files;
100     return @files;
101 }
102
103 1;