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

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