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