aboutsummaryrefslogtreecommitdiff
blob: de809178198f8d0783d569cd0da0f03417a0ebc4 (plain)
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#!/usr/bin/env python

# Global Modules
from subprocess import *
import sys
import re
import os

from tatt.gentooPackage import gentooPackage as gP
import tatt.packageFinder as packageFinder
from tatt.scriptwriter import writeusecombiscript as writeUSE
from tatt.scriptwriter import writerdepscript as writeRdeps
from tatt.scriptwriter import writesucessreportscript as writeSuccess
from tatt.scriptwriter import writecommitscript as writeCommit
from tatt.scriptwriter import writeCleanUpScript as writeCleanup
from tatt.tattConfig import tattConfig as tattConfig
from tatt.job import job as job

##### Generate a global config obj, reading from ~/.tatt #####
config = tattConfig()

######### Main program starts here ###############

### USAGE and OPTIONS ###
from optparse import OptionParser

parser=OptionParser()
parser.add_option("-d", "--depend",
                  help="Determine stable rdeps",
                  dest="depend",
                  action="store_true",
                  default = False)
parser.add_option("-u", "--use", "--usecombis",
                  help="Determine use flag combinations",
                  dest="usecombi",
                  action="store_true",
                  default = False)
parser.add_option("-f", "--file", 
                  help="Input File containing packages",
                  dest="infile",
                  action="store"
                  )
parser.add_option("-j", "--jobname",
                  help="name for the job, prefix of output files",
                  dest="jobname",
                  action="store")
parser.add_option("-b", "--bug",
                  help="do the full program for a given stable request bug",
                  dest="bugnum",
                  # type="int",
                  # We could test this here, but in most cases the bugnumber
                  # is actually used as a string, so we validate further down
                  # and leave it as a string
                  action="store")
parser.add_option("-s", "--success",
                  help="Comment that the program was successfully tested",
                  dest="succbugnum",
                  action="store")
parser.add_option("-r", "--resolve",
                  help="Resolve the given bugnumber, needs a message",
                  dest="resolvenum",
                  action="store")
parser.add_option("-c", "--close",
                  help="Resolve the given bugnumber with closing it, needs to be combined with -r",
                  dest="close",
                  action="store_true")
parser.add_option("-m", "--message",
                  help="Message for bug resolution.",
                  dest="resolvemessage",
                  action="store")
parser.add_option("-v", "--verbose",
                  help="Print informative output.",
                  dest="verbose",
                  action="store_true",
                  default = False)

(options,args) = parser.parse_args()

## Messing with the configuration:
# Save verbosity level
config['verbose']=options.verbose
# Normalize the template dir:
config['template-dir']=os.path.abspath(config['template-dir'])+os.sep
# If given, test if the bugnumber represents an int
try:
    int(options.bugnum)
except ValueError:
    print ("The bugnumber you gave with -b should be an integer.")
    sys.exit(1)
except TypeError:
    # This occurs if bugnum is None, that is, -b was not given
    pass

## If safedir is set, check for the current directory
if config['safedir'] != "":
    if os.getcwd().find(config['safedir']) == -1:
        # Safedir not found
        print ("Your safedir variable is set to '" + config['safedir'] + "',")
        print ("but you are in " + os.getcwd())
        print ("Exiting.")
        sys.exit (1)

## -s and a bugnumber was given ?
if options.succbugnum:
    print("Reporting success for bug number " + options.succbugnum)
    retcode = call(['bugz', 'modify', options.succbugnum, '-c', config['successmessage']])
    if retcode == 0:
        print("Success!");
        sys.exit (0)
    else:
        print("Failure commenting on Bugzilla")
        sys.exit(1)

# get a job object to save things to
myJob = job()

## If -f and a filename have been given:
if options.infile:
    try:
        packfile=open(options.infile, 'r')
    except IOError:
        print("Given filename not found !")
        sys.exit(1)
    packraw = packfile.read()
    packfile.close()
    myJob.packageList = packageFinder.findPackages(packraw, re.compile(config['atom-regexp']))

## -b and a bugnumber was given ?
if options.bugnum:
    print("Bugnumber:  " + options.bugnum)
    myJob.bugnumber=options.bugnum
    p1 = Popen(['bugz', 'get', myJob.bugnumber, '-n'], stdout=PIPE)
    # This returns a bytes encoded string, but we need standard utf-8
    # to use a string object via its buffer API. -> decode.
    bugraw = p1.communicate()[0].decode('utf-8')
    bugtitle = [l for l in bugraw.splitlines() if 'Title' in l][0]
    if re.search('KEYWORDREQ', bugraw):
        # This is a keywording bug:
        print ("Keywording bug detected.")
        myJob.type="keyword"
    elif re.search('STABLEREQ', bugraw):
        # Stablebug
        print ("Stabilization bug detected.")
        myJob.type="stable"
    else:
        print ("Could not detect bug's type, is the 'Keywords' field set?")
        sys.exit(1)
    # If myJob.packageList is still empty we search in the bug-title
    if myJob.packageList==None:
        myJob.packageList = packageFinder.findPackages(bugtitle, re.compile(config['atom-regexp']))

# joint code for -f and -b
##########################

if not myJob.packageList==None:
    ## Assigning jobname
    if options.jobname:
        myJob.name = options.jobname
    elif options.infile:
        myJob.name = options.infile
    else:
        myJob.name = myJob.packageList[0].packageName()
    print ("Jobname: " + myJob.name)
    ## Determine jobtype

    for p in myJob.packageList:
        print("Found the following package atom : " + p.packageString())

    # Unmasking:
    try:
        unmaskfile=open(config['unmaskfile'], 'r+')
    except IOError:
        print ("Your unmaskfile was not found, I will create it as")
        print (config['unmaskfile'])
        try:
            unmaskfile=open(config['unmaskfile'], 'w')
            unmaskfile.write(" ")
            unmaskfile.close()
        except IOError:
            # If we can't write to the file, then it should be configured differently
            print (" ".join(["Can not write to ",config['unmaskfile']]))
            print ("Maybe you don't have permission or the location is invalid.")
            print (" ".join(["Is",os.path.split(config['unmaskfile'])[0],"a writeable directory?"]))
            print ("Probably you want to configure a different unmaskfile")
            print ("in your ~/.tatt.  Exiting")
            sys.exit(1)
        unmaskfile=open(config['unmaskfile'], 'r+')

    unmaskfileContent = unmaskfile.read()
    for p in myJob.packageList:
        # Test if unmaskfile already contains the atom
        if re.search(p.packageString(), unmaskfileContent):
            print (p.packageString() + " already in "+config['unmaskfile'])
        else:
            unmaskfile.write(p.packageString())
            if myJob.type=="stable":
                pass
            elif myJob.type=="keyword":
                unmaskfile.write(" ** ")
            else:
                print ("Uh Oh, no job.type? Tell tomka@gentoo.org to fix this!")
            unmaskfile.write("  # Job " + myJob.name + "\n")
            print ("Unmasked " + p.packageString()+ " in "+config['unmaskfile'])
    unmaskfile.close()
    ## Write the scripts
    writeUSE(myJob, config)
    writeRdeps(myJob, config)
    writeCleanup (myJob, config)
    ## Config and Successscript can only be written if we have a bugnumber
    if myJob.bugnumber:
        writeSuccess(myJob, config)
        writeCommit(myJob, config)
    sys.exit (0)

# Code for resolving bugs (-r and -m)
#####################################
if options.resolvenum:
    if not options.resolvemessage:
        print("Please call with a message per -m")
        sys.exit (1)
    print("Resolving bug number " + options.resolvenum)
    calllist = ['bugz', 'modify', options.resolvenum, '-c', options.resolvemessage, '--remove-cc', config['arch']+"@gentoo.org"]
    if options.close:
        calllist = calllist + ['--fixed']
    retcode = call(calllist)
    if retcode == 0:
        print("Success!");
        sys.exit (0)
    else:
        print("Failure accessing bugzilla.")
        sys.exit(1)


## If we arrive here then a package atom should be given
try:
    myJob.packageList=[gP(args[0])]
    myJob.name=myJob.packageList[0].packageName()
except IndexError:
    print("Please call with complete package atom (including version) as argument.")
    sys.exit (1)

if options.depend:
    writeRdeps(myJob, config)

if options.usecombi:
    writeUSE(myJob, config)

## That's all folks ##