1package Vimana::Record;
2use warnings;
3use strict;
4use Vimana;
5use Vimana::Util;
6use JSON::PP;
7use File::Path;
8use Digest::MD5 qw(md5_hex);
9use YAML;
10
11sub new_json {
12    return JSON::PP->new->allow_singlequote(1);
13}
14
15sub record_dir {
16    return (  $ENV{VIM_RECORD_DIR} ||
17        do {
18            my @rtps = get_vim_rtp();
19            File::Spec->join($rtps[0],'record');
20        }  );
21}
22
23sub record_path  {
24    my ( $class, $pkgname ) = @_;
25    my $record_dir =  $class->record_dir();
26    if( ! -d $record_dir ) {
27        File::Path::mkpath( $record_dir );
28    }
29    return File::Spec->join( $record_dir , $pkgname );
30}
31
32=head2 load
33
34load package record , returns a hashref which contains:
35
36spec:
37
38    {
39        version => 0.1,
40        generated_by => 'Vimana [Version]'
41        installer_type => 'auto',  # auto , make , rake ... etc
42        meta => {
43            author: Cornelius
44            email: cornelius.howl@gmail.com
45            libpath: ./
46            name: gsession.vim
47            script_id: 2885
48            type: plugin
49            version: 0.21
50            version_from: plugin/gsession.vim
51            vim_version:
52        },
53        files => [
54            { file => "/Users/c9s/.vim/plugin/gsession.vim", checksum => "md5checksum" }
55        ]
56    }
57
58=cut
59
60
61sub load {
62    my ( $class, $pkgname ) = @_;
63    my $record_file =  $class->record_path( $pkgname );
64
65    if( ! -e $record_file ) {
66        print STDERR "Package $pkgname is not installed.\n";
67        return ;
68    }
69
70    open FH , "<" , $record_file;
71    local $/;
72    my $json = <FH>;
73    close FH;
74
75    my $record;
76    eval { $record = new_json()->decode( $json ) };
77    if( $@ ) {
78        # try to load YAML. (old record file)
79        print STDERR $@;
80        $record = YAML::LoadFile( $record_file );
81        unless( $record ) {
82            print STDERR "Can not load record. Use -f or --force option to remove.\n";
83            return;
84        }
85    }
86    return $record;
87}
88
89
90sub _remove_record {
91    my ($self,$pkgname) = @_;
92    my $file = $self->record_path( $pkgname );
93    return unlink $file;
94}
95
96sub remove {
97    my ( $self, $pkgname , $force , $verbose ) = @_;
98    my $record = $self->load($pkgname);
99
100    if( !$record and $force ) {
101        # force remove record file.
102        $self->_remove_record( $pkgname );
103        return;
104    }
105
106    return unless $record;
107
108    my $files = $record->{files};
109    print "Removing package $pkgname\n";
110    for my $entry (@$files) {
111        # XXX: check digest here
112        print "\tRemoving @{[ $entry->{file} ]}\n" if $verbose;
113        unlink $entry->{file};
114    }
115    $self->_remove_record( $pkgname );
116}
117
118sub add {
119    my ( $class , $record ) = @_;
120    my $pkgname = $record->{package};
121    unless( $pkgname ) {
122        die "Package name is not declared.";
123    }
124
125    my $record_file =  $class->record_path( $pkgname );
126    return 0 if -f $record_file;
127
128    open FH , ">" , $record_file;
129    print FH new_json()->encode( $record );
130    close FH;
131
132    #return YAML::DumpFile( $record_file , $record  );
133}
134
135sub mk_file_digest {
136    my ($self,$file) = @_;
137    open my $fh , "<" , $file;
138    binmode $fh,':bytes';
139    local $/;
140    my $content = <$fh>;
141    close $fh;
142    return md5_hex( $content );
143}
144
145sub mk_file_digests {
146    my $self = shift;
147    my @files = @_;
148    my @e = ();
149    for my $f ( @files ) {
150        my $ctx = $self->mk_file_digest( $f );
151        # print " $ctx: $f\n";
152        push @e, { file => $f , checksum => $ctx };
153    }
154    return @e;
155}
156
1571;
158