1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 from __future__ import with_statement
17
18 import os
19 import copy
20 import stat
21 from twisted.python import usage, runtime
22
24 def print_error(error_message):
25 print "%s\ninvalid buildmaster directory '%s'" % (error_message, dir)
26
27 buildbot_tac = os.path.join(dir, "buildbot.tac")
28 try:
29 contents = open(buildbot_tac).read()
30 except IOError, exception:
31 print_error("error reading '%s': %s" % \
32 (buildbot_tac, exception.strerror))
33 return False
34
35 if "Application('buildmaster')" not in contents:
36 print_error("unexpected content in '%s'" % buildbot_tac)
37 return False
38
39 return True
40
42 configFile = os.path.abspath(os.path.join(basedir, defaultName))
43 if os.path.exists(configFile):
44 return configFile
45
46 tacFile = os.path.join(basedir, 'buildbot.tac')
47 if os.path.exists(tacFile):
48
49 tacGlobals = {}
50 execfile(tacFile, tacGlobals)
51 return tacGlobals["configfile"]
52
53 return configFile
54
56
57
58
59
60 buildbotOptions = None
61
62
63 requiredOptions = []
64
66
67
68
69
70
71
72 cls = self.__class__
73 if hasattr(cls, 'optParameters'):
74 old_optParameters = cls.optParameters
75 cls.optParameters = op = copy.deepcopy(cls.optParameters)
76 if self.buildbotOptions:
77 optfile = self.optionsFile = self.loadOptionsFile()
78 for optfile_name, option_name in self.buildbotOptions:
79 for i in range(len(op)):
80 if (op[i][0] == option_name
81 and optfile_name in optfile):
82 op[i] = list(op[i])
83 op[i][2] = optfile[optfile_name]
84 usage.Options.__init__(self, *args)
85 if hasattr(cls, 'optParameters'):
86 cls.optParameters = old_optParameters
87
89 """Find the .buildbot/options file. Crawl from the current directory
90 up towards the root, and also look in ~/.buildbot . The first directory
91 that's owned by the user and has the file we're looking for wins.
92 Windows skips the owned-by-user test.
93
94 @rtype: dict
95 @return: a dictionary of names defined in the options file. If no
96 options file was found, return an empty dict.
97 """
98
99 here = _here or os.path.abspath(os.getcwd())
100
101 if runtime.platformType == 'win32':
102
103 from win32com.shell import shellcon, shell
104 appdata = shell.SHGetFolderPath(0, shellcon.CSIDL_APPDATA, 0, 0)
105 home = os.path.join(appdata, "buildbot")
106 else:
107 home = os.path.expanduser("~/.buildbot")
108
109 searchpath = []
110 toomany = 20
111 while True:
112 searchpath.append(os.path.join(here, ".buildbot"))
113 next = os.path.dirname(here)
114 if next == here:
115 break
116 here = next
117 toomany -= 1
118 if toomany == 0:
119 print ("I seem to have wandered up into the infinite glories "
120 "of the heavens. Oops.")
121 break
122
123 searchpath.append(home)
124
125 localDict = {}
126
127 for d in searchpath:
128 if os.path.isdir(d):
129 if runtime.platformType != 'win32':
130 if os.stat(d)[stat.ST_UID] != os.getuid():
131 print "skipping %s because you don't own it" % d
132 continue
133 optfile = os.path.join(d, "options")
134 if os.path.exists(optfile):
135 try:
136 with open(optfile, "r") as f:
137 options = f.read()
138 exec options in localDict
139 except:
140 print "error while reading %s" % optfile
141 raise
142 break
143
144 for k in localDict.keys():
145 if k.startswith("__"):
146 del localDict[k]
147 return localDict
148
149 - def postOptions(self):
150 missing = [ k for k in self.requiredOptions if self[k] is None ]
151 if missing:
152 if len(missing) > 1:
153 msg = 'Required arguments missing: ' + ', '.join(missing)
154 else:
155 msg = 'Required argument missing: ' + missing[0]
156 raise usage.UsageError(msg)
157
159
160 """SubcommandOptions Mixin to handle subcommands that take a basedir
161 argument"""
162
164 if len(args) > 0:
165 self['basedir'] = args[0]
166 else:
167
168 self['basedir'] = os.getcwd()
169 if len(args) > 1:
170 raise usage.UsageError("I wasn't expecting so many arguments")
171
172 - def postOptions(self):
173
174
175 self['basedir'] = os.path.abspath(os.path.expanduser(self['basedir']))
176