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