~ubuntu-branches/ubuntu/quantal/astk/quantal

« back to all changes in this revision

Viewing changes to configuration/util.py

  • Committer: Bazaar Package Importer
  • Author(s): Christophe Trophime
  • Date: 2010-04-25 16:43:13 UTC
  • Revision ID: james.westby@ubuntu.com-20100425164313-0s0wtsmbiewbdz53
Tags: upstream-1.8.0
ImportĀ upstreamĀ versionĀ 1.8.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
 
 
3
import os
 
4
import re
 
5
import time
 
6
import difflib
 
7
from stat import ST_MODE
 
8
from subprocess     import Popen, PIPE, STDOUT
 
9
from distutils      import log, file_util, dir_util
 
10
 
 
11
 
 
12
def execute(cmd, env=None):
 
13
   """Executes a command and returns its output."""
 
14
   p = Popen(cmd, stdout=PIPE, stderr=STDOUT, close_fds=True, env=env)
 
15
   return p.communicate()[0]
 
16
 
 
17
 
 
18
def less_than_version(vers1, vers2):
 
19
   return version2tuple(vers1) < version2tuple(vers2)
 
20
 
 
21
 
 
22
def version2tuple(vers_string):
 
23
   """1.7.9alpha --> (1, 7, 9, 'alpha'), 1.8 --> (1, 8, 0, 'final')"""
 
24
   tupl0 = vers_string.split('.')
 
25
   val = []
 
26
   for v in tupl0:
 
27
      m = re.search('(^[0-9]+)(.*)', v)
 
28
      if m:
 
29
         val.append(int(m.group(1)))
 
30
         if m.group(2):
 
31
            val.append(m.group(2).replace('-', '').replace('_', '').strip())
 
32
      else:
 
33
         val.append(v)
 
34
   val.extend([0]*(3-len(val)))
 
35
   if type(val[-1]) in (int, long):
 
36
      val.append('final')
 
37
   return tuple(val)
 
38
 
 
39
 
 
40
def get_function(functions, vers):
 
41
   """Return the function to be used starting from version...
 
42
   functions = (
 
43
      ('0.0.0', f1),
 
44
      ('1.7.5', f2),
 
45
      ('1.8.0', f3)
 
46
   )
 
47
   """
 
48
   tv, func = functions[0]
 
49
   for vi, fi in functions[1:]:
 
50
      if less_than_version(vers, vi):
 
51
         break
 
52
      func = fi
 
53
   return func
 
54
 
 
55
 
 
56
def prefix2etc(prefix):
 
57
   if prefix == "/usr":
 
58
      return "/etc"
 
59
   else:
 
60
      return os.path.join(prefix, 'etc')
 
61
 
 
62
 
 
63
def move_tree(src, dirs_and_files, dest, preserve_symlinks=0, dry_run=0):
 
64
   """Moves dirs_and_files from src to dest
 
65
   (put dirs first to create destination dirs for files).
 
66
   """
 
67
   dir_util.create_tree(dest, dirs_and_files, dry_run=dry_run)
 
68
   for obj in dirs_and_files:
 
69
      src_i = os.path.join(src, obj)
 
70
      dst_i = os.path.join(dest, obj)
 
71
      log.debug("move_tree %s to %s" , src_i, dst_i)
 
72
      if not os.path.exists(src_i) and not os.path.islink(src_i):
 
73
         log.info("not found: %s", src_i)
 
74
         continue
 
75
      if os.path.islink(src_i):
 
76
         link_dest = os.readlink(src_i)
 
77
         log.info("linking %s -> %s", dst_i, link_dest)
 
78
         if not dry_run:
 
79
            os.symlink(link_dest, dst_i)
 
80
            os.remove(src_i)
 
81
      elif os.path.isdir(src_i):
 
82
         dir_util.copy_tree(src_i, dst_i, preserve_symlinks=preserve_symlinks, dry_run=dry_run)
 
83
         remove_tree(src_i, dry_run=dry_run)
 
84
      else:
 
85
         file_util.move_file(src_i, dst_i, dry_run=dry_run)
 
86
 
 
87
 
 
88
def remove_tree(directory, verbose=0, dry_run=0, empty_dirs=0):
 
89
   """Same as dir_util.remove_tree + try to remove parent directories if they are empty."""
 
90
   dir_util.remove_tree(directory, verbose, dry_run)
 
91
   if not empty_dirs:
 
92
      return
 
93
   dsplit = directory.split(os.sep)
 
94
   if dsplit[0] != '':
 
95
      return
 
96
   while len(dsplit) > 1:
 
97
      dsplit[0] = os.sep
 
98
      full = os.path.join(*dsplit)
 
99
      if os.path.exists(full):
 
100
         try:
 
101
            os.rmdir(full)
 
102
            log.debug("removed: %s", full)
 
103
         except:
 
104
            break
 
105
      del dsplit[-1]
 
106
 
 
107
 
 
108
def remove_empty_dirs(fromdir):
 
109
   """Removes all empty dirs"""
 
110
   for base, dirs, files in os.walk(fromdir, topdown=False):
 
111
      try:
 
112
         os.rmdir(base)
 
113
      except:
 
114
         pass
 
115
 
 
116
 
 
117
def re_search(filename, regexp, flags=0):
 
118
   """Search for regexp in the content of 'filename'."""
 
119
   log.debug("search regular expression %r in %s", regexp, filename)
 
120
   if not os.path.isfile(filename):
 
121
      log.debug("not found: %s", filename)
 
122
      return None
 
123
   expr = re.compile(regexp, flags)
 
124
   content = open(filename, 'r').read()
 
125
   res = expr.search(content)
 
126
   return res
 
127
 
 
128
 
 
129
def check_and_store(dico, match, lvar):
 
130
   """Check match.groups() and store them in dico[*var]."""
 
131
   log.debug("check_var: variables=%r", lvar)
 
132
   if match is None:
 
133
      return
 
134
   if type(lvar) not in (tuple, list):
 
135
      lvar = [lvar,]
 
136
   inter = min(len(lvar), len(match.groups()))
 
137
   log.debug("           values=%r", match.groups())
 
138
   for i in range(inter):
 
139
      var, value = lvar[i], match.group(i+1).strip()
 
140
      if re.search('\?[A-Z_0-9]+\?', value):
 
141
         log.info("%s is not configured (%r)", var, value)
 
142
         continue
 
143
      dico[var] = value
 
144
 
 
145
 
 
146
# copy from asrun.utils
 
147
def read_rcfile(ficrc, destdict):
 
148
   """Read a ressource file and store variables to 'destdict'.
 
149
   """
 
150
   f = open(ficrc, 'r')
 
151
   for line in f:
 
152
      if not re.search('^[ ]*#', line):
 
153
         mat = re.search('([-a-z_A-Z0-9]+) *: *(.*)', line.strip())
 
154
         if mat:
 
155
            key   = mat.group(1)
 
156
            value = mat.group(2).strip()
 
157
            # try to convert numbers and boolean values
 
158
            try:
 
159
               if value.isdigit():
 
160
                  value = int(value)
 
161
               else:
 
162
                  value = float(value)
 
163
            except ValueError:
 
164
               if value in ('True', 'False'):
 
165
                  value = eval(value)
 
166
            # repeatable ? (space separated)
 
167
            if destdict.has_key(key) and key in ('vers', 'noeud'):
 
168
               value = str(destdict[key])+' '+str(value)
 
169
            destdict[key] = value
 
170
   f.close()
 
171
 
 
172
 
 
173
def replace_rcfile(ficrc, values):
 
174
   """Changes the values of fields of 'ficrc' using 'values' dict.
 
175
   """
 
176
   content = open(ficrc, 'r').read()
 
177
   for field, value in values.items():
 
178
      try:
 
179
         searched    = '^%s *: *(.*)$' % field
 
180
         replacement = '%s : %s' % (field, value)
 
181
         # particular treatment for repeatable fields
 
182
         if field == 'noeud':    # only one occurrence in content, but may have more values
 
183
            replacement = os.linesep.join(['%s : %s' % (field, vali) for vali in value.split()])
 
184
         elif field == 'vers':
 
185
            searched = '^%s$' % re.escape('#?vers : VVV?')
 
186
            replacement = os.linesep.join(['#?vers : VVV?'] \
 
187
                           + ['%s : %s' % (field, vali) for vali in value.split()])
 
188
         regexp = re.compile(searched, re.MULTILINE)
 
189
         content = regexp.sub(replacement, content, re.MULTILINE)
 
190
      except: # skip invalid regexp (probably not a real field)
 
191
         pass
 
192
   open(ficrc, 'w').write(content)
 
193
 
 
194
 
 
195
def print_diff(fromfile, tofile):
 
196
   fromdate = time.ctime(os.stat(fromfile).st_mtime)
 
197
   todate = time.ctime(os.stat(tofile).st_mtime)
 
198
   fromlines = open(fromfile, 'U').readlines()
 
199
   tolines = open(tofile, 'U').readlines()
 
200
 
 
201
   diff = difflib.unified_diff(fromlines, tolines, fromfile, tofile,
 
202
                                    fromdate, todate)
 
203
   return ''.join(diff)
 
204
 
 
205
 
 
206
def backup_name(filename, ext, hidden=True):
 
207
   """From 'filename' + '.ext' returns '.ext-filename' if hidden is True, 'filename.ext' else."""
 
208
   if ext[0] != '.':
 
209
      ext = '.' + ext
 
210
   dirname, basename = os.path.split(filename)
 
211
   if hidden:
 
212
      basename = ext + '-' + basename
 
213
   else:
 
214
      basename = basename + ext
 
215
   return os.path.join(dirname, basename)
 
216
 
 
217
 
 
218
def chmod_scripts(files):
 
219
   if type(files) not in (list, tuple):
 
220
      files = [files,]
 
221
   for filename in files:
 
222
      mode = ((os.stat(filename)[ST_MODE]) | 0555) & 07777
 
223
      log.info("changing mode of %s to %o", filename, mode)
 
224
      os.chmod(filename, mode)
 
225
 
 
226
 
 
227
# unittest
 
228
def _test_get_function():
 
229
   ff = ( ('0.0.0', 'func < 1.7.5'), ('1.7.5', 'func >= 1.7.5'), ('1.8.0', 'func >= 1.8.0') )
 
230
   for v in ('1.2.3', '1.7.4', '1.7.5', '1.7.99', '1.8', '1.8.01', 'unknown'):
 
231
      print v, '-->', get_function(ff, v)
 
232