util.py 4.7 KB
Newer Older
1
#  Copyright (c) 2006 by Aurelien Foret <orelien@chez.com>
Allan McRae's avatar
Allan McRae committed
2
#  Copyright (c) 2006-2022 Pacman Development Team <pacman-dev@lists.archlinux.org>
3
#
4
5
6
7
8
9
10
11
12
13
14
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
15
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17
18


import os
19
import re
Dan McGee's avatar
Dan McGee committed
20
import hashlib
21

Andrew Gregory's avatar
Andrew Gregory committed
22
23
import tap

24
SELFPATH    = os.path.abspath(os.path.dirname(__file__))
25
26
27
28

# ALPM
PM_ROOT     = "/"
PM_DBPATH   = "var/lib/pacman"
Xavier Chantry's avatar
Xavier Chantry committed
29
PM_SYNCDBPATH = "var/lib/pacman/sync"
30
PM_LOCK     = "var/lib/pacman/db.lck"
31
32
PM_CACHEDIR = "var/cache/pacman/pkg"
PM_EXT_PKG  = ".pkg.tar.gz"
33
PM_HOOKDIR  = "etc/pacman.d/hooks"
34
35
36
37
38
39
40
41
42
43
44
45

# Pacman
PACCONF     = "etc/pacman.conf"

# Pactest
TMPDIR      = "tmp"
SYNCREPO    = "var/pub"
LOGFILE     = "var/log/pactest.log"

verbose = 0

def vprint(msg):
46
    if verbose:
Andrew Gregory's avatar
Andrew Gregory committed
47
        tap.diag(msg)
48
49
50
51
52

#
# Methods to generate files
#

Dan McGee's avatar
Dan McGee committed
53
54
55
56
57
58
59
60
61
def getfileinfo(filename):
    data = {
        'changed': False,
        'isdir': False,
        'islink': False,
        'link': None,
        'hasperms': False,
        'perms': None,
    }
62
    if filename[-1] == "*":
Dan McGee's avatar
Dan McGee committed
63
        data["changed"] = True
64
65
66
        filename = filename.rstrip("*")
    if filename.find(" -> ") != -1:
        filename, link = filename.split(" -> ")
Dan McGee's avatar
Dan McGee committed
67
68
        data["islink"] = True
        data["link"] = link
69
70
    elif filename.find("|") != -1:
        filename, perms = filename.split("|")
Dan McGee's avatar
Dan McGee committed
71
72
        data["hasperms"] = True
        data["perms"] = int(perms, 8)
73
    if filename[-1] == "/":
Dan McGee's avatar
Dan McGee committed
74
        data["isdir"] = True
75

Dan McGee's avatar
Dan McGee committed
76
77
    data["filename"] = filename
    return data
78

Dan McGee's avatar
Dan McGee committed
79
80
81
82
83
84
85
def mkfile(base, name, data=""):
    info = getfileinfo(name)
    filename = info["filename"]

    path = os.path.join(base, filename)
    if info["isdir"]:
        if not os.path.isdir(path):
86
            os.makedirs(path, 0o755)
87
        return path
Dan McGee's avatar
Dan McGee committed
88
89
90

    dir_path = os.path.dirname(path)
    if dir_path and not os.path.isdir(dir_path):
91
        os.makedirs(dir_path, 0o755)
Dan McGee's avatar
Dan McGee committed
92
93
94

    if info["islink"]:
        os.symlink(info["link"], path)
95
    else:
Dan McGee's avatar
Dan McGee committed
96
97
98
99
100
        writedata(path, data)

    if info["perms"]:
        os.chmod(path, info["perms"])

101
102
    return path

Dan McGee's avatar
Dan McGee committed
103
104
105
def writedata(filename, data):
    if isinstance(data, list):
        data = "\n".join(data)
106
    fd = open(filename, "w")
Dan McGee's avatar
Dan McGee committed
107
108
109
110
111
    if data:
        fd.write(data)
        if data[-1] != "\n":
            fd.write("\n")
    fd.close()
112
113

def mkcfgfile(filename, root, option, db):
114
115
    # Options
    data = ["[options]"]
116
    for key, value in option.items():
117
        data.extend(["%s = %s" % (key, j) for j in value])
118

119
    # Repositories
120
121
    # sort by repo name so tests can predict repo order, rather than be
    # subjects to the whims of python dict() ordering
122
    for key in sorted(db.keys()):
123
        if key != "local":
124
            value = db[key]
125
126
127
128
            data.append("[%s]\n" % (value.treename))
            data.append("SigLevel = %s\n" % (value.getverify()))
            if value.syncdir:
                data.append("Server = file://%s" % (os.path.join(root, SYNCREPO, value.treename)))
129
            for optkey, optval in value.option.items():
130
                data.extend(["%s = %s" % (optkey, j) for j in optval])
131

Dan McGee's avatar
Dan McGee committed
132
    mkfile(root, filename, "\n".join(data))
133
134
135
136
137
138
139


#
# MD5 helpers
#

def getmd5sum(filename):
140
141
    if not os.path.isfile(filename):
        return ""
142
    fd = open(filename, "rb")
Dan McGee's avatar
Dan McGee committed
143
    checksum = hashlib.md5()
144
    while 1:
Dan McGee's avatar
Dan McGee committed
145
        block = fd.read(32 * 1024)
146
147
148
149
        if not block:
            break
        checksum.update(block)
    fd.close()
Dan McGee's avatar
Dan McGee committed
150
    return checksum.hexdigest()
151
152

def mkmd5sum(data):
Dan McGee's avatar
Dan McGee committed
153
    checksum = hashlib.md5()
Dave Reisner's avatar
Dave Reisner committed
154
    checksum.update(("%s\n" % data).encode('utf8'))
Dan McGee's avatar
Dan McGee committed
155
    return checksum.hexdigest()
156
157
158
159
160
161


#
# Miscellaneous
#

162
163
164
def which(filename, path=None):
    if not path:
        path = os.environ["PATH"].split(os.pathsep)
165
166
167
168
169
170
    for p in path:
        f = os.path.join(p, filename)
        if os.access(f, os.F_OK):
            return f
    return None

171
def grep(filename, pattern):
172
173
174
175
176
    pat = re.compile(pattern)
    myfile = open(filename, 'r')
    for line in myfile:
        if pat.search(line):
            myfile.close()
Aaron Griffin's avatar
Aaron Griffin committed
177
            return True
178
    myfile.close()
Aaron Griffin's avatar
Aaron Griffin committed
179
    return False
180

Dan McGee's avatar
Dan McGee committed
181
182
def mkdir(path):
    if os.path.isdir(path):
183
        return
Dan McGee's avatar
Dan McGee committed
184
185
    elif os.path.isfile(path):
        raise OSError("'%s' already exists and is not a directory" % path)
186
    os.makedirs(path, 0o755)