-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathbitsBuild
More file actions
executable file
·173 lines (145 loc) · 5.06 KB
/
bitsBuild
File metadata and controls
executable file
·173 lines (145 loc) · 5.06 KB
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#!/usr/bin/env python3
"""bits build driver.
Entry point for all ``bits`` sub-commands (build, clean, deps, doctor, init,
architecture, version, analytics). ``bitsDeps`` and ``bitsDoctor`` are thin
wrappers that exec this script with the matching sub-command prepended.
"""
# Standard library
import atexit
import logging
import os
import sys
import traceback
from os.path import exists, expanduser
# Internal
from bits_helpers import __version__
from bits_helpers.analytics import (askForAnalytics, decideAnalytics,
disable_analytics, enable_analytics,
report_event, report_exception,
report_screenview)
from bits_helpers.args import doParseArgs
from bits_helpers.build import doBuild
from bits_helpers.clean import doClean
from bits_helpers.cleanup import doCleanup
from bits_helpers.deps import doDeps
from bits_helpers.doctor import doDoctor
from bits_helpers.init import doInit
from bits_helpers.publish import doPublish
from bits_helpers.verify import doVerify
from bits_helpers.status import doStatus
from bits_helpers.log import debug, error, info, logger
from bits_helpers.utilities import detectArch
# Google Analytics property for bits usage reporting.
_ANALYTICS_TRACKING_ID = "UA-77346950-1"
def doMain(args, parser):
"""Dispatch the requested sub-command after applying environment overrides.
Called once argument parsing is complete. Sets locale/environment variables
that affect downstream shell commands, then delegates to the appropriate
``do*`` function.
"""
if not hasattr(args, "architecture"):
args.architecture = detectArch()
# Force a predictable locale and clear variables that can interfere with
# shell command output parsing (e.g. localised error messages, BASH_ENV
# sourcing a non-errexit-safe bashrc at NERSC).
os.environ.update({
"LANG": "C",
"LANGUAGE": "C",
"LC_ALL": "C",
"LC_COLLATE": "C",
"LC_CTYPE": "C",
"LC_MESSAGES": "C",
"LC_MONETARY": "C",
"LC_NUMERIC": "C",
"LC_TIME": "C",
"GREP_OPTIONS": "",
"BASH_ENV": "",
"BITS_ARCHITECTURE": args.architecture,
})
report_screenview(args.action)
# Move to the specified working directory before doing anything else.
if hasattr(args, "chdir"):
try:
os.chdir(os.path.expanduser(args.chdir))
debug("Current working directory is %s", os.getcwd())
except OSError as e:
error("Cannot change to directory %r: %s", args.chdir, e)
sys.exit(1)
if args.action in ("version", None):
print("bits version: {version} ({arch})".format(
version=__version__ or "unknown", arch=args.architecture or "unknown"))
sys.exit(0)
if args.action == "doctor":
doDoctor(args, parser)
if args.action == "deps":
sys.exit(0 if doDeps(args, parser) else 1)
if args.action == "clean":
doClean(workDir=args.workDir, architecture=args.architecture,
aggressiveCleanup=args.aggressiveCleanup, dryRun=args.dryRun)
sys.exit(0)
if args.action == "cleanup":
doCleanup(args, parser)
sys.exit(0)
if args.action == "init":
doInit(args)
sys.exit(0)
if args.action == "build":
doBuild(args, parser)
sys.exit(0)
if args.action == "publish":
doPublish(args, parser)
sys.exit(0)
if args.action == "verify":
doVerify(args, parser)
# doVerify calls sys.exit() internally, but be explicit
sys.exit(0)
if args.action == "status":
doStatus(args, parser)
sys.exit(0)
if __name__ == "__main__":
args, parser = doParseArgs()
logger.setLevel(logging.DEBUG if args.debug else logging.INFO)
os.environ["BITS_ANALYTICS_ID"] = _ANALYTICS_TRACKING_ID
os.environ["BITS_VERSION"] = __version__ or ""
if args.action == "analytics":
if args.state == "off":
disable_analytics()
else:
enable_analytics()
sys.exit(0)
if args.action == "architecture":
arch = detectArch()
print(arch if arch else "<unknown>")
sys.exit(0)
# Analytics are currently disabled globally; the opt-in prompt below is
# preserved in case it is re-enabled in the future.
os.environ["BITS_NO_ANALYTICS"] = "1"
try:
# The profiler is activated by passing --profile on the command line.
# cProfile and friends are imported here to keep startup fast in the
# common (non-profiling) case.
useProfiler = "--profile" in sys.argv
if useProfiler:
import cProfile
import pstats
from io import StringIO
print("profiler started")
pr = cProfile.Profile()
pr.enable()
def profiler():
pr.disable()
print("profiler stopped")
s = StringIO()
ps = pstats.Stats(pr, stream=s).sort_stats("time")
ps.print_stats()
print(s.getvalue())
atexit.register(profiler)
doMain(args, parser)
except KeyboardInterrupt:
info("Interrupted by user (Ctrl-C)")
report_event("user", "ctrlc")
sys.exit(1)
except Exception as e:
traceback.print_exc()
report_exception(e)
sys.exit(1)