source: trunk/project-meta/project-meta @ 177

Last change on this file since 177 was 177, checked in by g7moreau, 6 years ago
  • Update version
  • Property svn:executable set to *
File size: 10.5 KB
Line 
1#!/usr/bin/env perl
2#
3# 2018/01/17 Gabriel Moreau
4#
5# apt-get install yamllint libyaml-syck-perl libtemplate-perl
6
7use strict;
8use warnings;
9
10use File::Copy qw{copy};   
11use YAML::Syck;
12use Getopt::Long();
13use Cwd();
14use Template;
15
16
17my ($verbose);
18Getopt::Long::GetOptions(
19   'verbose' => \$verbose,
20   );
21
22
23my %CMD_DB = (
24   'help'            => \&cmd_help,
25   'version'         => \&cmd_version,
26   'check'           => \&cmd_check,
27   'make-link'       => \&cmd_make_link,
28   'make-author'     => \&cmd_make_author,
29   'make-licence'    => \&cmd_make_licence,
30   'make-copyright'  => \&cmd_make_copyright,
31   'list-licence'    => \&cmd_list_licence,
32   );
33
34################################################################
35# main program
36################################################################
37
38my $cmd = shift @ARGV || 'help';
39if (defined $CMD_DB{$cmd}) {
40   $CMD_DB{$cmd}->(@ARGV);
41   }
42else {
43   print {*STDERR} "project-meta: command $cmd not found\n\n";
44   $CMD_DB{'help'}->();
45   exit 1;
46   }
47
48exit;
49
50################################################################
51# subroutine
52################################################################
53
54################################################################
55# command
56################################################################
57
58sub cmd_help {
59   print <<'END';
60project-meta - opendata project metafile manager
61
62 project-meta help
63 project-meta version
64 project-meta check
65 project-meta make-link
66 project-meta make-author
67 project-meta make-licence
68 project-meta make-copyright
69 project-meta make-licence
70 project-meta list-licence
71END
72   }
73
74################################################################
75
76sub cmd_version {
77   print "0.0.2\n";
78   }
79
80################################################################
81
82sub print_ok {
83   my ($key, $test) = @_;
84   
85   printf "%-35s : %s\n", $key, $test ? 'yes' : 'no';
86   }
87
88################################################################
89
90sub cmd_check {
91   my $meta = YAML::Syck::LoadFile("PROJECT-META.yml");
92
93   my $acronym     = $meta->{'project'}{'acronym'};
94   my $current_dir = Cwd::getcwd();
95   my $dap_folder  = $meta->{'public-dap'}{'dap-folder'};
96
97   print_ok 'project/acronym',                  $acronym =~ m{\d\d\w[\w\d_]+};
98   print_ok 'public-dap/dap-folder',            $dap_folder ne '' and $dap_folder =~ m{^/};
99   print_ok 'dap-folder not match current_dir', $dap_folder !~ m{$current_dir};
100
101   #print YAML::Syck::Dump($meta);
102   }
103
104################################################################
105
106sub addfolder2list {
107   my ($folderdb, $folder) = @_;
108   
109   $folder =~ s{/[^/]+$}{};
110   
111   return if $folder !~ m{/};
112
113   $folderdb->{$folder}++;
114   return addfolder2list($folderdb, $folder);
115   }
116
117################################################################
118
119sub cmd_make_link {
120   my $meta = YAML::Syck::LoadFile("PROJECT-META.yml");
121   my $current_dir = Cwd::getcwd();
122   my $acronym     = $meta->{'project'}{'acronym'};
123   my $dap_folder  = $meta->{'public-dap'}{'dap-folder'};
124   my $data_set    = $meta->{'public-dap'}{'data-set'};
125
126   push @{$data_set}, 'AUTHORS.txt', 'COPYRIGHT.txt', 'LICENCE.txt';
127   {
128      # Remove doublon
129      my %seen = ();
130      @{$data_set} = grep { ! $seen{$_}++ } @{$data_set};
131      }
132
133   # Create a list of the folder
134   my %folders;
135   for my $dataset (@{$data_set}) {
136      addfolder2list(\%folders, $dataset);
137      }
138
139   print "chmod o+rX,o-w $current_dir\n";
140   print "mkdir -p $dap_folder/$acronym\n" if not -d "$dap_folder/$acronym";
141   for my $folder (sort keys %folders) {
142      print "chmod o+rX,o-w $current_dir/$folder\n";
143      print "mkdir -p $dap_folder/$acronym/$folder\n" if -d "$current_dir/$folder";
144      }
145
146   for my $dataset (@{$data_set}) {
147      if ($dataset =~ m{/}) {
148         # Folder case
149         my $folder = $dataset =~ s{/[^/]+$}{}r;
150         print "ln --symbolic --target-directory $dap_folder/$acronym/$folder/ $current_dir/$dataset\n";
151         }
152      else {
153         # File case
154         print "ln --symbolic --target-directory $dap_folder/$acronym/ $current_dir/$dataset\n";
155         }
156
157      }
158   print "chmod -R o+rX,o-w $dap_folder/$acronym/\n";
159   }
160
161################################################################
162
163sub cmd_make_author {
164   my $meta = YAML::Syck::LoadFile("PROJECT-META.yml");
165
166   my $current_dir = Cwd::getcwd();
167
168   my $acronym    = $meta->{'project'}{'acronym'};
169   my $authors_list = $meta->{'project'}{'authors'};
170
171   if (-f "$current_dir/AUTHORS.txt") {
172      # Test for manual or automatically generated file
173      # Automatically generated file by project-meta
174      my $automatic;
175      open my $fh, '<', "$current_dir/AUTHORS.txt" or die $!;
176      for my $line (<$fh>) {
177         $line =~ m/Automatically generated .* project-meta/i and $automatic++;
178         }
179      close $fh;
180
181      if (not $automatic) {
182         print "Warning: AUTHORS.txt already exists\n";
183         return;
184         }
185
186      print "Warning: update AUTHORS.txt\n";
187      }
188
189   my $tt = Template->new(INCLUDE_PATH => '/usr/share/project-meta/template.d');
190   my $msg_format = '';
191   $tt->process('AUTHORS.tt',
192      {
193         acronym    => $acronym,
194         authorlist => $authors_list,
195      }, \$msg_format) || die $tt->error;
196
197   open my $fh,  '>', "$current_dir/AUTHORS.txt" or die $!;
198   print $fh "$msg_format\n\n";
199   close $fh;
200   }
201
202################################################################
203
204sub cmd_make_licence {
205   my $meta = YAML::Syck::LoadFile("PROJECT-META.yml");
206
207   my $current_dir = Cwd::getcwd();
208
209   if (-f "$current_dir/LICENCE.txt") {
210      print "Warning: LICENCE.txt already exists\n";
211      return;
212      }
213
214   my $licence = $meta->{'public-dap'}{'data-licence'};
215
216   if (not -f "/usr/share/project-meta/licence.d/$licence.txt") {
217      print "Error: licence $licence doesn't exists in project-meta database\n";
218      exit 1;
219      }
220
221   copy("/usr/share/project-meta/licence.d/$licence.txt", "$current_dir/LICENCE.txt")
222      or die "Error: licence copy failed - $!";
223
224   print "Info: LICENCE.txt file create\n";
225   return;
226   }
227
228################################################################
229
230sub cmd_make_copyright {
231   my $meta = YAML::Syck::LoadFile("PROJECT-META.yml");
232
233   my $current_dir = Cwd::getcwd();
234
235   if (-f "$current_dir/COPYRIGHT.txt") {
236      # Test for manual or automatically generated file
237      # Automatically generated file by project-meta
238      my $automatic;
239      open my $fh, '<', "$current_dir/COPYRIGHT.txt" or die $!;
240      for my $line (<$fh>) {
241         $line =~ m/Automatically generated .* project-meta/i and $automatic++;
242         }
243      close $fh;
244
245      if (not $automatic) {
246         print "Warning: COPYRIGHT.txt already exists\n";
247         return;
248         }
249
250      print "Warning: update COPYRIGHT.txt\n";
251      }
252   
253   my $tt = Template->new(
254      INCLUDE_PATH   => '/usr/share/project-meta/template.d',
255      POST_CHOMP     => 1, # Remove space and carriage return after %]
256      );
257   my $msg_format = '';
258   $tt->process('COPYRIGHT.tt',
259      {
260         title       => $meta->{'project'}{'title'},
261         acronym     => $meta->{'project'}{'acronym'},
262         authorlist  => $meta->{'project'}{'authors'},
263         description => $meta->{'project'}{'short-description'},
264         licence     => $meta->{'public-dap'}{'data-licence'},
265         doi         => $meta->{'publication'}{'doi'},
266      }, \$msg_format) || die $tt->error;
267
268   open my $fh,  '>', "$current_dir/COPYRIGHT.txt" or die $!;
269   print $fh "$msg_format\n\n";
270   close $fh;
271   }
272
273################################################################
274
275sub cmd_list_licence {
276   opendir my $dh, '/usr/share/project-meta/licence.d/' or die $!;
277   for my $licence (readdir $dh) {
278      # Keep only file
279      next if not -f "/usr/share/project-meta/licence.d/$licence";
280     
281      # Keep only .txt file
282      next if not $licence =~ m/\.txt$/;
283
284      $licence =~ s/\.txt$//;
285      print "$licence\n";
286      }
287   closedir $dh;
288   }
289
290################################################################
291# documentation
292################################################################
293
294__END__
295
296=head1 NAME
297
298project-meta - opendata project metafile manager
299
300
301=head1 USAGE
302
303 project-meta help
304 project-meta version
305 project-meta check
306 project-meta make-link
307 project-meta make-author
308 project-meta make-licence
309 project-meta make-copyright
310 project-meta make-licence
311 project-meta list-licence
312
313=head1 DESCRIPTION
314
315project-meta is a small tool to maintain a set of open data files.
316
317=head1 COMMANDS
318
319Some command are defined in the source code but are not documented here.
320Theses could be not well defined, not finished, not well tested...
321You can read the source code and use them at your own risk
322(like for all the Klask code).
323
324=head2 check
325
326 project-meta check
327
328Check your F<PROJECT-META.yml> has the good key.
329If your metafile is not a valid YAML file,
330you can use C<yamllint> command to check just it's format.
331
332=head2 make-licence
333
334 project-meta make-licence
335
336Copy the licence file from the project-meta licence database at the current folder with the file name: LICENCE.txt.
337
338The licence is defined in the PROJECT-META.yml specification under the key C<public-dap/data-licence>.
339The list of possible licence is given with the command L<list-licence>.
340
341=head2 list-licence
342
343 project-meta list-licence
344
345Give the list of all the open data licence supported by the project-meta licence database.
346At this time the possible licence are:
347
348 license-ouverte-v2.0
349 open-database-license-v1.0
350
351
352=head1 METAFILE SPECIFICATION
353
354Each project must have an open data metafile which describe the project : C<PROJECT-META.yml>.
355The file is in YAML format because this is a human readable style of text file.
356
357You can find in the project-meta software a C<PROJECT-META.sample.yml> example.
358This one is actually the master reference specification!
359
360
361=head1 BUG
362
363 - make-link: folder/folder
364 - make-link: support multiple doi
365 - metafile: remove prop publication/url
366
367=head1 SEE ALSO
368
369yamllint
370
371
372=head1 AUTHOR
373
374Written by Gabriel Moreau, LEGI UMR5519, CNRS, Grenoble - France
375
376=head1 SPECIAL THANKS
377
378The list of people below did not directly contribute to project-meta's source code
379but provided me with some data, returned bugs
380or helped me in another small task like having new ideas ...
381Maybe I forgot your contribution in recent years,
382please forgive me in advance and send me an e-mail to correct this.
383
384Joel Sommeria, Julien Chauchat, Cyrille Bonamy, Antoine Mathieu.
385
386
387=head1 LICENSE AND COPYRIGHT
388
389Licence GNU GPL version 2 or later and Perl equivalent
390
391Copyright (C) 2017-2018 Gabriel Moreau <Gabriel.Moreau(A)univ-grenoble-alpes.fr>.
Note: See TracBrowser for help on using the repository browser.