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

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