[pygnulib] .gitignore
[gnulib.git] / gnulib-tool.py
blob8137ea3eb410881b87718fcc44d5d6635c40c90d
1 #!/usr/bin/python
3 # Copyright (C) 2002-2012 Free Software Foundation, Inc.
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # This program is meant for authors or maintainers which want to import
20 # modules from gnulib into their packages.
23 #===============================================================================
24 # Define global imports
25 #===============================================================================
26 import os
27 import re
28 import sys
29 import codecs
30 import random
31 import shutil
32 import argparse
33 import subprocess as sp
34 from pprint import pprint
35 from pygnulib import constants
36 from pygnulib import classes
39 #===============================================================================
40 # Define global constants
41 #===============================================================================
42 PYTHON3 = constants.PYTHON3
43 APP = constants.APP
44 DIRS = constants.DIRS
45 ENCS = constants.ENCS
46 UTILS = constants.UTILS
47 FILES = constants.FILES
48 MODES = constants.MODES
49 TESTS = constants.TESTS
50 compiler = constants.compiler
51 joinpath = constants.joinpath
52 cleaner = constants.cleaner
53 string = constants.string
54 isabs = os.path.isabs
55 isdir = os.path.isdir
56 isfile = os.path.isfile
57 normpath = os.path.normpath
58 relpath = os.path.relpath
61 #===============================================================================
62 # Define main part
63 #===============================================================================
64 def main():
65 # Reset arguments
66 mode = None
67 destdir = None
68 localdir = None
69 modcache = None
70 verbose = None
71 auxdir = None
72 modules = None
73 avoids = None
74 sourcebase = None
75 m4base = None
76 pobase = None
77 docbase = None
78 testsbase = None
79 tests = None
80 libname = None
81 lgpl = None
82 makefile = None
83 libtool = None
84 conddeps = None
85 macro_prefix = None
86 podomain = None
87 witness_c_macro = None
88 vc_files = None
89 dryrun = None
90 errors = None
92 info = classes.GLInfo()
93 parser = argparse.ArgumentParser(
94 prog=constants.APP['name'],
95 usage='gnulib-tool.py --help',
96 add_help=False)
97 # help
98 parser.add_argument('-h', '--help', '--hel', '--he', '--h',
99 dest='help',
100 default=None,
101 action='store_true')
102 # version
103 parser.add_argument('--version', '--versio', '--versi', '--vers',
104 dest='version',
105 default=None,
106 action='store_true')
107 # list
108 parser.add_argument('-l', '--list', '--lis',
109 dest='mode_list',
110 default=None,
111 action='store_true')
112 # find
113 parser.add_argument('-f', '--find', '--fin', '--fi', '--f',
114 dest='mode_find',
115 default=None,
116 nargs='*')
117 # import
118 parser.add_argument('-i', '--import',
119 dest='mode_import',
120 default=None,
121 nargs='+')
122 # add-import
123 parser.add_argument('-a', '--add-import',
124 dest='mode_add_import',
125 default=None,
126 nargs='+')
127 # remove-import
128 parser.add_argument('-r', '--remove-import',
129 dest='mode_remove_import',
130 default=None,
131 nargs='+')
132 # update
133 parser.add_argument('-u', '--update',
134 dest='mode_update',
135 default=None,
136 action='store_true')
137 # create-testdir
138 parser.add_argument('-td', '--create-testdir',
139 dest='mode_create_testdir',
140 default=None,
141 nargs='*')
142 # create-megatestdir
143 parser.add_argument('-mtd', '--create-megatestdir',
144 dest='mode_create_megatestdir',
145 default=None,
146 nargs='*')
147 # test
148 parser.add_argument('-t', '--test',
149 dest='mode_test',
150 default=None,
151 nargs='*')
152 # megatest
153 parser.add_argument('-mt', '--megatest', '--megates', '--megate', '--megat',
154 '--mega', '--meg', '--me', '--m',
155 dest='mode_megatest',
156 default=None,
157 nargs='*')
158 # copy-file
159 parser.add_argument('-c', '--copy-file',
160 dest='mode_copy_file',
161 default=None,
162 nargs='+')
163 # extract-*
164 parser.add_argument('-xD', '--extract-description',
165 dest='mode_xdescription',
166 default=None,
167 nargs='*')
168 parser.add_argument('-xc', '--extract-comment',
169 dest='mode_xcomment',
170 default=None,
171 nargs='*')
172 parser.add_argument('-xs', '--extract-status',
173 dest='mode_xstatus',
174 default=None,
175 nargs='*')
176 parser.add_argument('-xn', '--extract-notice',
177 dest='mode_xnotice',
178 default=None,
179 nargs='*')
180 parser.add_argument('-xa', '--extract-applicability',
181 dest='mode_xapplicability',
182 default=None,
183 nargs='*')
184 parser.add_argument('-xf', '--extract-filelist',
185 dest='mode_xfilelist',
186 default=None,
187 nargs='*')
188 parser.add_argument('-xd', '--extract-dependencies',
189 dest='mode_xdependencies',
190 default=None,
191 nargs='*')
192 parser.add_argument('-xac', '--extract-autoconf-snippet',
193 dest='mode_xautoconf',
194 default=None,
195 nargs='*')
196 parser.add_argument('-xam', '--extract-automake-snippet',
197 dest='mode_xautomake',
198 default=None,
199 nargs='*')
200 parser.add_argument('-xi', '--extract-include-directive',
201 dest='mode_xinclude',
202 default=None,
203 nargs='*')
204 parser.add_argument('-xl', '--extract-link-directive',
205 dest='mode_xlink',
206 default=None,
207 nargs='*')
208 parser.add_argument('-xL', '--extract-license',
209 dest='mode_xlicense',
210 default=None,
211 nargs='*')
212 parser.add_argument('-xm', '--extract-maintainer',
213 dest='mode_xmaintainer',
214 default=None,
215 nargs='*')
216 # destdir
217 parser.add_argument('-d', '--destdir',
218 dest='destdir',
219 default=None,
220 nargs=1)
221 # localdir
222 parser.add_argument('-ld', '--local-dir',
223 dest='localdir',
224 default=None,
225 nargs=1)
226 # verbose
227 parser.add_argument('-v', '--verbose',
228 default=0,
229 action='count')
230 # quiet
231 parser.add_argument('-q', '--quiet',
232 default=0,
233 action='count')
234 # dryrun
235 parser.add_argument('--dry-run',
236 dest='dryrun',
237 default=None,
238 action='store_true')
239 # inctests
240 parser.add_argument('--with-tests',
241 dest='inctests',
242 default=None,
243 action='store_true')
244 # obsolete
245 parser.add_argument('--with-obsolete',
246 dest='obsolete',
247 default=None,
248 action='store_true')
249 # c++-tests
250 parser.add_argument('--with-c++-tests',
251 dest='cxx',
252 default=None,
253 action='store_true')
254 # longrunning-tests
255 parser.add_argument('--with-longrunning-tests',
256 dest='longrunning',
257 default=None,
258 action='store_true')
259 # privileged-tests
260 parser.add_argument('--with-privileged-tests',
261 dest='privileged',
262 default=None,
263 action='store_true')
264 # unportable-tests
265 parser.add_argument('--with-unportable-tests',
266 dest='unportable',
267 default=None,
268 action='store_true')
269 # all-tests
270 parser.add_argument('--with-all-tests',
271 dest='alltests',
272 default=None,
273 action='store_true')
274 # auxdir
275 parser.add_argument('--aux-dir',
276 dest='auxdir',
277 default=None,
278 nargs=1)
279 # libname
280 parser.add_argument('--lib',
281 dest='libname',
282 default=None,
283 nargs=1)
284 # sourcebase
285 parser.add_argument('-sb', '--source-base',
286 dest='sourcebase',
287 default=None,
288 nargs=1)
289 # m4base
290 parser.add_argument('-mb', '--m4-base',
291 dest='m4base',
292 default=None,
293 nargs=1)
294 # pobase
295 parser.add_argument('-pb', '--po-base',
296 dest='pobase',
297 default=None,
298 nargs=1)
299 # docbase
300 parser.add_argument('-db', '--doc-base',
301 dest='docbase',
302 default=None,
303 nargs=1)
304 # testsbase
305 parser.add_argument('-tb', '--tests-base',
306 dest='testsbase',
307 default=None,
308 nargs=1)
309 # lgpl
310 parser.add_argument('--lgpl',
311 dest='lgpl',
312 default=False,
313 type=int,
314 nargs='?')
315 # avoids
316 parser.add_argument('--avoid',
317 dest='avoids',
318 default=None,
319 nargs='+')
321 # Parse the given arguments.
322 cmdargs = parser.parse_args()
324 # Determine when user tries to combine modes.
325 args = [
326 cmdargs.mode_list,
327 cmdargs.mode_import,
328 cmdargs.mode_add_import,
329 cmdargs.mode_remove_import,
330 cmdargs.mode_update,
331 cmdargs.mode_create_testdir,
332 cmdargs.mode_create_megatestdir,
333 cmdargs.mode_test,
334 cmdargs.mode_megatest,
335 cmdargs.mode_copy_file,
336 cmdargs.mode_xdescription,
337 cmdargs.mode_xcomment,
338 cmdargs.mode_xstatus,
339 cmdargs.mode_xnotice,
340 cmdargs.mode_xapplicability,
341 cmdargs.mode_xfilelist,
342 cmdargs.mode_xdependencies,
343 cmdargs.mode_xautoconf,
344 cmdargs.mode_xautomake,
345 cmdargs.mode_xinclude,
346 cmdargs.mode_xlink,
347 cmdargs.mode_xlicense,
348 cmdargs.mode_xmaintainer,
350 overflow = [arg for arg in args if arg]
351 if len(overflow) > 1:
352 message = 'gnulib-tool: Unable to combine different modes of work.\n'
353 message += 'Try \'gnulib-tool --help\' for more information.\n'
354 sys.stderr.write(message)
355 sys.exit(1)
357 # Determine selected mode.
358 if cmdargs.help != None:
359 print(info.usage())
360 sys.exit(0)
361 if cmdargs.version != None:
362 message = '''gnulib-tool (%s %s)%s\n%s\n%s\n\nWritten by %s.''' % \
363 (info.package(), info.date(), info.version(), info.copyright(),
364 info.license(), info.authors())
365 print(message)
366 sys.exit(0)
367 if cmdargs.mode_list != None:
368 mode = 'list'
369 if cmdargs.mode_import != None:
370 mode = 'import'
371 modules = list(cmdargs.mode_import)
372 if cmdargs.mode_add_import != None:
373 mode = 'add-import'
374 modules = list(cmdargs.mode_add_import)
375 if cmdargs.mode_remove_import != None:
376 mode = 'remove-import'
377 modules = list(cmdargs.mode_remove_import)
378 if cmdargs.mode_update != None:
379 mode = 'update'
380 if cmdargs.mode_create_testdir != None:
381 mode = 'create-testdir'
382 modules = list(cmdargs.mode_create_testdir)
383 if cmdargs.mode_create_megatestdir != None:
384 mode = 'create-megatestdir'
385 modules = list(cmdargs.mode_create_megatestdir)
386 if cmdargs.mode_test != None:
387 mode = 'test'
388 modules = list(cmdargs.mode_test)
389 if cmdargs.mode_megatest != None:
390 mode = 'megatest'
391 modules = list(cmdargs.mode_megatest)
392 if cmdargs.mode_xdescription != None:
393 mode = 'extract-description'
394 modules = list(cmdargs.mode_xdescription)
395 if cmdargs.mode_xcomment != None:
396 mode = 'extract-comment'
397 modules = list(cmdargs.mode_xcomment)
398 if cmdargs.mode_xstatus != None:
399 mode = 'extract-status'
400 modules = list(cmdargs.mode_xstatus)
401 if cmdargs.mode_xnotice != None:
402 mode = 'extract-notice'
403 modules = list(cmdargs.mode_xnotice)
404 if cmdargs.mode_xapplicability != None:
405 mode = 'extract-applicability'
406 modules = list(cmdargs.mode_xapplicability)
407 if cmdargs.mode_xfilelist != None:
408 mode = 'extract-filelist'
409 modules = list(cmdargs.mode_xfilelist)
410 if cmdargs.mode_xautoconf != None:
411 mode = 'extract-autoconf-snippet'
412 modules = list(cmdargs.mode_xautoconf)
413 if cmdargs.mode_xautomake != None:
414 mode = 'extract-automake-snippet'
415 modules = list(cmdargs.mode_xautomake)
416 if cmdargs.mode_xdependencies != None:
417 mode = 'extract-dependencies'
418 modules = list(cmdargs.mode_xdependencies)
419 if cmdargs.mode_xinclude != None:
420 mode = 'extract-include-directive'
421 modules = list(cmdargs.mode_xinclude)
422 if cmdargs.mode_xlink != None:
423 mode = 'extract-link-directive'
424 modules = list(cmdargs.mode_xlink)
425 if cmdargs.mode_xlicense != None:
426 mode = 'extract-license'
427 modules = list(cmdargs.mode_xlicense)
428 if cmdargs.mode_xmaintainer != None:
429 mode = 'extract-maintainer'
430 modules = list(cmdargs.mode_xmaintainer)
431 if cmdargs.mode_copy_file != None:
432 mode = 'copy-file'
433 if len(cmdargs.mode_copy_file) > 2:
434 message = '%s: *** ' % constants.APP['name']
435 message += 'invalid number of arguments for --%s' % mode
436 message += '\n%s: *** Exit.\n' % constants.APP['name']
437 sys.stderr.write(message)
438 sys.exit(1)
439 files = list(cmdargs.mode_copy_file)
441 # Determine specific settings.
442 destdir = cmdargs.destdir
443 if destdir != None:
444 destdir = cmdargs.destdir[0]
445 localdir = cmdargs.localdir
446 if localdir != None:
447 localdir = cmdargs.localdir[0]
448 libname = cmdargs.libname
449 if libname != None:
450 libname = cmdargs.libname[0]
451 auxdir = cmdargs.auxdir
452 if auxdir != None:
453 auxdir = cmdargs.auxdir[0]
454 sourcebase = cmdargs.sourcebase
455 if sourcebase != None:
456 sourcebase = cmdargs.sourcebase[0]
457 m4base = cmdargs.m4base
458 if m4base != None:
459 m4base = cmdargs.m4base[0]
460 pobase = cmdargs.pobase
461 if pobase != None:
462 pobase = cmdargs.pobase[0]
463 testsbase = cmdargs.testsbase
464 if testsbase != None:
465 testsbase = cmdargs.testsbase[0]
466 dryrun = cmdargs.dryrun
467 verbose = -cmdargs.quiet +cmdargs.verbose
468 inctests = cmdargs.inctests
469 flags = [cmdargs.inctests, cmdargs.obsolete, cmdargs.cxx,
470 cmdargs.longrunning, cmdargs.privileged, cmdargs.unportable,
471 cmdargs.alltests]
472 testflags = list()
473 for flag in flags:
474 index = flags.index(flag)
475 if flag != None:
476 if flag:
477 if index == 0:
478 testflags += [constants.TESTS['tests']]
479 elif index == 1:
480 testflags += [constants.TESTS['obsolete']]
481 elif index == 2:
482 testflags += [constants.TESTS['cxx-tests']]
483 elif index == 3:
484 testflags += [constants.TESTS['longrunning-tests']]
485 elif index == 4:
486 testflags += [constants.TESTS['privileged-tests']]
487 elif index == 5:
488 testflags += [constants.TESTS['unportable-tests']]
489 elif index == 6:
490 testflags += [constants.TESTS['all-tests']]
491 lgpl = cmdargs.lgpl
492 if lgpl == None:
493 lgpl = True
494 avoids = cmdargs.avoids
496 # Create pygnulib configuration.
497 config = classes.GLConfig\
499 destdir=destdir,
500 localdir=localdir,
501 m4base=m4base,
502 auxdir=auxdir,
503 modules=modules,
504 avoids=avoids,
505 sourcebase=sourcebase,
506 pobase=pobase,
507 docbase=docbase,
508 testsbase=testsbase,
509 testflags=testflags,
510 libname=libname,
511 lgpl=lgpl,
512 makefile=makefile,
513 libtool=libtool,
514 conddeps=conddeps,
515 macro_prefix=macro_prefix,
516 podomain=podomain,
517 witness_c_macro=witness_c_macro,
518 vc_files=vc_files,
519 modcache=modcache,
520 verbose=verbose,
521 dryrun=dryrun,
524 # Canonicalize the inctests variable.
525 if inctests == None:
526 if mode in ['import', 'add-import', 'remove-import', 'update']:
527 config.disableTestFlag(TESTS['tests'])
528 elif mode in ['create-testdir', 'create-megatestdir', 'test', 'megatest']:
529 config.enableTestFlag(TESTS['tests'])
531 # Work in the given mode.
532 if mode in ['list']:
533 modulesystem = classes.GLModuleSystem(config)
534 listing = modulesystem.list()
535 result = '\n'.join(listing)
536 os.rmdir(config['tempdir'])
537 print(result)
539 elif mode in ['import', 'add-import', 'remove-import', 'update']:
540 mode = MODES[mode]
541 if not destdir:
542 destdir = '.'
543 config.setDestDir(destdir)
545 if mode == MODES['import']:
546 # Set variables to default values.
547 if not sourcebase:
548 sourcebase = 'lib'
549 if not m4base:
550 m4base = 'm4'
551 if not docbase:
552 docbase = 'doc'
553 if not testsbase:
554 testsbase = 'tests'
555 if not macro_prefix:
556 macro_prefix = 'gl'
557 config.setSourceBase(sourcebase)
558 config.setM4Base(m4base)
559 config.setDocBase(docbase)
560 config.setTestsBase(testsbase)
561 config.setMacroPrefix(macro_prefix)
563 # Perform GLImport actions.
564 importer = classes.GLImport(config, mode)
565 filetable, transformers = importer.prepare()
566 importer.execute(filetable, transformers)
568 else: # if mode != MODE['--import']
569 if m4base:
570 if not isfile(joinpath(destdir, m4base, 'gnulib-cache.m4')):
571 if not sourcebase:
572 sourcebase = 'lib'
573 if not docbase:
574 docbase = 'doc'
575 if not testsbase:
576 testsbase = 'tests'
577 if not macro_prefix:
578 macro_prefix = 'gl'
579 config.setSourceBase(sourcebase)
580 config.setM4Base(m4base)
581 config.setDocBase(docbase)
582 config.setTestsBase(testsbase)
583 config.setMacroPrefix(macro_prefix)
584 # Perform GLImport actions.
585 importer = classes.GLImport(config, mode)
586 filetable, transformers = importer.prepare()
587 importer.execute(filetable, transformers)
588 else: # if not m4base
589 m4dirs = list()
590 dirisnext = bool()
591 filepath = joinpath(destdir, 'Makefile.am')
592 if isfile(filepath):
593 with codecs.open(filepath, 'rb', 'UTF-8') as file:
594 data = file.read()
595 data = data.split('ACLOCAL_AMFLAGS')[1]
596 data = data[data.find('=')+1:data.find('\n')]
597 aclocal_amflags = data.split()
598 for aclocal_amflag in aclocal_amflags:
599 if dirisnext:
600 if not isabs(aclocal_amflag):
601 m4dirs += [aclocal_amflag]
602 else: # if not dirisnext
603 if aclocal_amflag == '-I':
604 dirisnext = True
605 else: # if aclocal_amflag != '-I'
606 dirisnext = False
607 else: # if not isfile(filepath)
608 filepath = joinpath(destdir, 'aclocal.m4')
609 if isfile(filepath):
610 pattern = constants.compiler(r'm4_include\(\[(.*?)\]\)')
611 with codecs.open(filepath, 'rb', 'UTF-8') as file:
612 m4dirs = pattern.findall(file.read())
613 m4dirs = [os.path.dirname(m4dir) for m4dir in m4dirs]
614 m4dirs = \
615 [ # Begin filtering
616 m4dir for m4dir in m4dirs \
617 if isfile(joinpath(destdir, m4dir, 'gnulib-cache.m4'))
618 ] # Finish filtering
619 m4dirs = sorted(set(m4dirs))
620 if len(m4dirs) == 0:
621 # First use of gnulib in a package.
622 # Any number of additional modules can be given.
623 if not sourcebase:
624 sourcebase = 'lib'
625 m4base = 'm4'
626 if not docbase:
627 docbase = 'doc'
628 if not testsbase:
629 testsbase = 'tests'
630 if not macro_prefix:
631 macro_prefix = 'gl'
632 config.setSourceBase(sourcebase)
633 config.setM4Base(m4base)
634 config.setDocBase(docbase)
635 config.setTestsBase(testsbase)
636 config.setMacroPrefix(macro_prefix)
637 # Perform GLImport actions.
638 importer = classes.GLImport(config, mode)
639 filetable, transformers = importer.prepare()
640 importer.execute(filetable, transformers)
641 elif len(m4dirs) == 1:
642 m4base = m4dirs[-1]
643 config.setM4Base(m4base)
644 # Perform GLImport actions.
645 importer = classes.GLImport(config, mode)
646 filetable, transformers = importer.prepare()
647 importer.execute(filetable, transformers)
648 else: # if len(m4dirs) > 1
649 for m4base in m4dirs:
650 config.setM4Base(m4base)
651 # Perform GLImport actions.
652 importer = classes.GLImport(config, mode)
653 filetable, transformers = importer.prepare()
654 importer.execute(filetable, transformers)
656 elif mode == 'create-testdir':
657 if not destdir:
658 message = '%s: *** ' % constants.APP['name']
659 message += 'please specify --dir option'
660 message += '\n%s: *** Exit.\n' % constants.APP['name']
661 sys.stderr.write(message)
662 sys.exit(1)
663 if not auxdir:
664 auxdir = 'build-aux'
665 config.setAuxDir(auxdir)
666 testdir = classes.GLTestDir(config, destdir)
667 testdir.execute()
669 elif mode == 'create-megatestdir':
670 if not destdir:
671 message = '%s: *** ' % constants.APP['name']
672 message += 'please specify --dir option'
673 message += '\n%s: *** Exit.\n' % constants.APP['name']
674 sys.stderr.write(message)
675 sys.exit(1)
676 if not auxdir:
677 auxdir = 'build-aux'
678 config.setAuxDir(auxdir)
679 testdir = classes.GLMegaTestDir(config, destdir)
680 testdir.execute()
682 elif mode == 'test':
683 if not destdir:
684 destdir = 'testdir %04d' % random.randrange(0, 9999)
685 if not auxdir:
686 auxdir = 'build-aux'
687 config.setAuxDir(auxdir)
688 testdir = classes.GLTestDir(config, destdir)
689 testdir.execute()
690 os.chdir(destdir)
691 os.mkdir('build')
692 os.chdir('build')
693 try: # Try to execute commands
694 sp.call(['../configure'])
695 sp.call([UTILS['make']])
696 sp.call([UTILS['make'], 'check'])
697 sp.call([UTILS['make'], 'distclean'])
698 except Exception as error:
699 sys.exit(1)
700 args = ['find', '.', '-type', 'f', '-print']
701 remaining = sp.check_output(args).decode(ENCS['shell'])
702 lines = [line.strip() for line in remaining.split('\n') if line.strip()]
703 remaining = ' '.join(lines)
704 if remaining:
705 message = 'Remaining files: %s\n' % remaining
706 message += 'gnulib-tool: *** Stop.\n'
707 sys.stderr.write(message)
708 sys.exit(1)
709 os.chdir('../..')
710 sp.call(['rm', '-rf', destdir], shell=False)
712 elif mode == 'megatest':
713 if not destdir:
714 destdir = 'testdir %04d' % random.randrange(0, 9999)
715 if not auxdir:
716 auxdir = 'build-aux'
717 config.setAuxDir(auxdir)
718 testdir = classes.GLMegaTestDir(config, destdir)
719 testdir.execute()
720 os.chdir(destdir)
721 os.mkdir('build')
722 os.chdir('build')
723 sp.call(['../configure'])
724 sp.call([UTILS['make']])
725 sp.call([UTILS['make'], 'check'])
726 sp.call([UTILS['make'], 'distclean'])
727 args = ['find', '.', '-type', 'f', '-print']
728 remaining = sp.check_output(args).decode(ENCS['shell'])
729 lines = [line.strip() for line in remaining.split('\n') if line.strip()]
730 remaining = ' '.join(lines)
731 if remaining:
732 message = 'Remaining files: %s\n' % remaining
733 message += 'gnulib-tool: *** Stop.\n'
734 sys.stderr.write(message)
735 sys.exit(1)
736 os.chdir('../..')
737 sp.call(['rm', '-rf', destdir], shell=False)
739 elif mode == 'extract-description':
740 modulesystem = classes.GLModuleSystem(config)
741 modules = [modulesystem.find(module) for module in modules]
742 for module in modules:
743 print(module.getDescription())
745 elif mode == 'extract-comment':
746 modulesystem = classes.GLModuleSystem(config)
747 modules = [modulesystem.find(module) for module in modules]
748 for module in modules:
749 print(module.getComment())
751 elif mode == 'extract-status':
752 modulesystem = classes.GLModuleSystem(config)
753 modules = [modulesystem.find(module) for module in modules]
754 for module in modules:
755 status = module.getStatus()
756 print('\n'.join(status))
758 elif mode == 'extract-notice':
759 modulesystem = classes.GLModuleSystem(config)
760 modules = [modulesystem.find(module) for module in modules]
761 for module in modules:
762 print(module.getNotice())
764 elif mode == 'extract-applicability':
765 modulesystem = classes.GLModuleSystem(config)
766 modules = [modulesystem.find(module) for module in modules]
767 for module in modules:
768 print(module.getApplicability())
770 elif mode == 'extract-filelist':
771 modulesystem = classes.GLModuleSystem(config)
772 modules = [modulesystem.find(module) for module in modules]
773 for module in modules:
774 files = module.getFiles()
775 print('\n'.join(files))
777 elif mode == 'extract-dependencies':
778 result = string()
779 if avoids:
780 message = '%s: *** ' % constants.APP['name']
781 message += 'cannot combine --avoid and --extract-dependencies\n'
782 message += '%s: *** Exit.\n' % constants.APP['name']
783 sys.stderr.write(message)
784 sys.exit(1)
785 modulesystem = classes.GLModuleSystem(config)
786 modules = [modulesystem.find(module) for module in modules]
787 for module in modules:
788 dependencies = module.getDependencies()
789 if dependencies:
790 for depmodule, condition in dependencies:
791 if condition == None:
792 result += '%s\n' % str(depmodule)
793 else: # if condition != None
794 result += '%s\t%s' % (str(depmodule), condition)
795 print(result)
797 elif mode == 'extract-autoconf-snippet':
798 modulesystem = classes.GLModuleSystem(config)
799 modules = [modulesystem.find(module) for module in modules]
800 for module in modules:
801 print(module.getAutoconfSnippet())
803 elif mode == 'extract-automake-snippet':
804 modulesystem = classes.GLModuleSystem(config)
805 modules = [modulesystem.find(module) for module in modules]
806 for module in modules:
807 print(module.getAutomakeSnippet())
809 elif mode == 'extract-include-directive':
810 modulesystem = classes.GLModuleSystem(config)
811 modules = [modulesystem.find(module) for module in modules]
812 for module in modules:
813 print(module.getInclude())
815 elif mode == 'extract-link-directive':
816 modulesystem = classes.GLModuleSystem(config)
817 modules = [modulesystem.find(module) for module in modules]
818 for module in modules:
819 print(module.getLink())
821 elif mode == 'extract-license':
822 modulesystem = classes.GLModuleSystem(config)
823 modules = [modulesystem.find(module) for module in modules]
824 for module in modules:
825 print(module.getLicense())
827 elif mode == 'extract-maintainer':
828 modulesystem = classes.GLModuleSystem(config)
829 modules = [modulesystem.find(module) for module in modules]
830 for module in modules:
831 print(module.getMaintainer())
833 elif mode == 'extract-tests-module':
834 modulesystem = classes.GLModuleSystem(config)
835 modules = [modulesystem.find(module) for module in modules]
836 for module in modules:
837 if module.getTestsModule():
838 print(module.getTestsName())
840 elif mode == 'copy-file':
841 srcpath = files[0]
842 if len(files) == 2:
843 dest = files[1]
844 else: # if len(files) != 2
845 dest = '.'
846 if type(srcpath) is bytes:
847 srcpath = srcpath.decode(ENCS['default'])
848 if type(dest) is bytes:
849 dest = dest.decode(ENCS['default'])
850 if not auxdir:
851 auxdir = 'build-aux'
852 if not sourcebase:
853 sourcebase = 'lib'
854 if not m4base:
855 m4base = 'm4'
856 if not docbase:
857 docbase = 'doc'
858 if not testsbase:
859 testsbase = 'tests'
860 config.setAuxDir(auxdir)
861 config.setSourceBase(sourcebase)
862 config.setM4Base(m4base)
863 config.setDocBase(docbase)
864 config.setTestsBase(testsbase)
865 filesystem = classes.GLFileSystem(config)
866 lookedup, flag = filesystem.lookup(srcpath)
867 if isdir(dest):
868 destdir = string(dest)
869 if srcpath.startswith('build-aux/'):
870 destpath = constants.substart('build-aux/', '%s/' % auxdir, srcpath)
871 elif srcpath.startswith('doc/'):
872 destpath = constants.substart('doc/', '%s/' % docbase, srcpath)
873 elif srcpath.startswith('lib/'):
874 destpath = constants.substart('lib/', '%s/' % sourcebase, srcpath)
875 elif srcpath.startswith('m4/'):
876 destpath = constants.substart('m4/', '%s/' % m4base, srcpath)
877 elif srcpath.startswith('tests/'):
878 destpath = constants.substart('tests/', '%s/' % testsbase, srcpath)
879 elif srcpath.startswith('tests=lib/'):
880 destpath = constants.substart('tests=lib/', '%s/' % testsbase, srcpath)
881 elif srcpath.startswith('top/'):
882 destpath = constants.substart('top/', '', srcpath)
883 else: # either case
884 destpath = srcpath
885 else: # if not isdir(destpath)
886 destdir = os.path.dirname(destpath)
887 destpath = os.path.basename(destpath)
888 # Create the directory for destfile.
889 dirname = os.path.dirname(joinpath(destdir, destpath))
890 if not config['dryrun']:
891 if dirname and not isdir(dirname):
892 try: # Try to create directories
893 os.makedirs(dirname)
894 except Exception as error:
895 pass
896 # Copy the file.
897 assistant = classes.GLFileAssistant(config)
898 tmpfile = assistant.tmpfilename(destpath)
899 shutil.copy(lookedup, tmpfile)
900 already_present = True
901 assistant.setOriginal(srcpath)
902 assistant.setRewritten(destpath)
903 if isfile(joinpath(destdir, destpath)):
904 # The file already exists.
905 assistant.update(lookedup, flag, tmpfile, already_present)
906 else: # if not isfile(joinpath(destdir, destpath))
907 # Install the file.
908 # Don't protest if the file should be there but isn't: it happens
909 # frequently that developers don't put autogenerated files under version
910 # control.
911 assistant.add(lookedup, flag, tmpfile)
912 if isfile(tmpfile):
913 os.remove(tmpfile)
915 else:
916 message = '%s: *** ' % constants.APP['name']
917 message += 'no mode specified'
918 message += '\n%s: *** Exit.\n' % constants.APP['name']
919 sys.stderr.write(message)
920 sys.exit(1)
922 if __name__ == '__main__':
923 try: # Try to execute
924 main()
925 except BaseException as error:
926 errmode = 0 # gnulib-style errors
927 errno = error.errno
928 errinfo = error.errinfo
929 if errmode == 0:
930 message = '%s: *** ' % constants.APP['name']
931 if errinfo == None:
932 errinfo = string()
933 if errno == 1:
934 message += 'file %s not found' % errinfo
935 elif errno == 2:
936 message += 'patch file %s didn\'t apply cleanly' % errinfo
937 elif errno == 3:
938 message += 'cannot find %s - make sure ' % errinfo
939 message += 'you run gnulib-tool from within your package\'s directory'
940 elif errno == 4:
941 message += 'minimum supported autoconf version is 2.59. Try adding'
942 message += 'AC_PREREQ([%s])' % constants.DEFAULT_AUTOCONF_MINVERSION
943 message += ' to your configure.ac.'
944 elif errno == 5:
945 "%s is expected to contain gl_M4_BASE([%s])" % \
946 (repr(os.path.join(errinfo, 'gnulib-comp.m4')), repr(errinfo))
947 elif errno == 6:
948 message += 'missing --source-base option'
949 elif errno == 7:
950 message += 'missing --doc-base option. --doc-base has been introduced '
951 message += 'on 2006-07-11; if your last invocation of \'gnulib-tool '
952 message += '--import\' is before that date, you need to run'
953 message += '\'gnulib-tool --import\' once, with a --doc-base option.'
954 elif errno == 8:
955 message += 'missing --tests-base option'
956 elif errno == 9:
957 message += 'missing --lib option'
958 elif errno == 10:
959 message = 'gnulib-tool: option --conditional-dependencies is not '
960 message += 'supported with --with-tests\n'
961 elif errno == 11:
962 incompatibilities = string()
963 message += 'incompatible license on modules:%s' % constants.NL
964 for pair in errinfo:
965 incompatibilities += pair[0]
966 incompatibilities += ' %s' % pair[1]
967 incompatibilities += constants.NL
968 tempname = tempfile.mktemp()
969 with codecs.open(tempname, 'wb', 'UTF-8') as file:
970 file.write(incompatibilities)
971 sed_table = 's,^\\([^ ]*\\) ,\\1' +' ' *51 +',\n'
972 sed_table += 's,^\\(' +'.'*49 +'[^ ]*\) *,' +' '*17 +'\\1 ,'
973 args = ['sed', '-e', sed_table, tempname]
974 incompatibilities = sp.check_output(args).decode(ENCS['default'])
975 message += incompatibilities
976 os.remove(tempname)
977 elif errno == 12:
978 message += 'refusing to do nothing'
979 elif errno in [13, 14, 15, 16, 17]:
980 message += 'failed'
981 elif errno == 19:
982 message += 'could not create destination directory: %s' % errinfo
983 if errno != 10:
984 message += '\n%s: *** Exit.\n' % constants.APP['name']
985 sys.stderr.write(message)
986 sys.exit(1)