1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
import argparse
from dataclasses import dataclass
import io
import os
import sys
from typing import List, TextIO
from . import DESCRIPTION, VERSION
__all__ = [
'parse',
'Args',
]
parser = argparse.ArgumentParser(
description=f'{DESCRIPTION} - version {VERSION}',
)
parser.add_argument('--environment-overrides', '-e',
action='store_true',
help='Cause environment variables, including those with null values, to override macro assignments '
'within makefiles.')
parser.add_argument('--makefile', '--file', '-f',
action='append',
type=argparse.FileType('r'),
help="Specify a different makefile (or '-' for standard input).")
parser.add_argument('--ignore-errors', '-i',
action='store_true',
help='Ignore error codes returned by invoked commands.')
parser.add_argument('--keep-going', '-k',
action='store_true',
help='Continue to update other targets that do not depend on the current target if a non-ignored '
'error occurs while executing the commands to bring a target up-to-date.')
parser.add_argument('--dry-run', '--just-print', '--recon', '-n',
action='store_true',
help="Write commands that would be executed on standard output, but do not execute them (but "
"execute lines starting with '+').")
parser.add_argument('--print-everything', '--print-data-base', '-p',
action='store_true',
help='Write to standard output the complete set of macro definitions and target descriptions.')
parser.add_argument('--question', '-q',
action='store_true',
help='Return a zero exit value if the target file is up-to-date; otherwise, return an exit value '
'of 1.')
parser.add_argument('--no-builtin-rules', '-r',
action='store_false',
dest='builtin_rules',
help='Clear the suffix list and do not use the built-in rules.')
parser.add_argument('--no-keep-going', '--stop', '-S',
action='store_false',
dest='keep_going',
help='Terminate make if an error occurs while executing the commands to bring a target up-to-date '
'(default behavior, required by POSIX to be also a flag for some reason).')
parser.add_argument('--silent', '--quiet', '-s',
action='store_true',
help='Do not write makefile command lines or touch messages to standard output before executing.')
parser.add_argument('--touch', '-t',
action='store_true',
help='Update the modification time of each target as though a touch target had been executed.')
parser.add_argument('targets_or_macros',
nargs='*',
metavar='target_or_macro',
help='Target name or macro definition.')
@dataclass()
class Args:
environment_overrides: bool
makefile: List[TextIO]
ignore_errors: bool
keep_going: bool
dry_run: bool
print_everything: bool
question: bool
builtin_rules: bool
silent: bool
touch: bool
targets_or_macros: List[str]
def __init__(self, parsed_args: argparse.Namespace):
self.environment_overrides = parsed_args.environment_overrides
if parsed_args.makefile is not None and len(parsed_args.makefile) > 0:
self.makefile = parsed_args.makefile
else:
try:
self.makefile = [open('./makefile', 'r')]
except FileNotFoundError:
self.makefile = [open('./Makefile', 'r')]
self.ignore_errors = parsed_args.ignore_errors
self.keep_going = parsed_args.keep_going
self.dry_run = parsed_args.dry_run
self.print_everything = parsed_args.print_everything
self.question = parsed_args.question
self.builtin_rules = parsed_args.builtin_rules
self.silent = parsed_args.silent
self.touch = parsed_args.touch
self.targets_or_macros = parsed_args.targets_or_macros
def parse(cli_args: List[str] = None, env_makeflags: str = None) -> Args:
if cli_args is None:
cli_args = sys.argv[1:]
if env_makeflags is None:
env_makeflags = os.environ.get('MAKEFLAGS', '')
# per POSIX, we accept option letters without a leading -, so to simplify we prepend a - now
# TODO allow macro definitions in MAKEFLAGS
if len(env_makeflags) > 0 and not env_makeflags.startswith('-'):
env_makeflags = '-' + env_makeflags
if len(env_makeflags) > 0:
all_args = [env_makeflags, *cli_args]
else:
all_args = cli_args
return Args(parser.parse_args(all_args))
# TODO test any of this
|