~ubuntu-branches/ubuntu/trusty/subversion/trusty-proposed

« back to all changes in this revision

Viewing changes to tools/dev/wc-ng/populate-pristine.py

  • Committer: Package Import Robot
  • Author(s): Andy Whitcroft
  • Date: 2012-06-21 15:36:36 UTC
  • mfrom: (0.4.13 sid)
  • Revision ID: package-import@ubuntu.com-20120621153636-amqqmuidgwgxz1ly
Tags: 1.7.5-1ubuntu1
* Merge from Debian unstable.  Remaining changes:
  - Create pot file on build.
  - Build a python-subversion-dbg package.
  - Build-depend on python-dbg.
  - Build-depend on default-jre-headless/-jdk.
  - Do not apply java-build patch.
  - debian/rules: Manually create the doxygen output directory, otherwise
    we get weird build failures when running parallel builds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
 
 
3
# Licensed to the Apache Software Foundation (ASF) under one
 
4
# or more contributor license agreements.  See the NOTICE file
 
5
# distributed with this work for additional information
 
6
# regarding copyright ownership.  The ASF licenses this file
 
7
# to you under the Apache License, Version 2.0 (the
 
8
# "License"); you may not use this file except in compliance
 
9
# with the License.  You may obtain a copy of the License at
 
10
#
 
11
#   http://www.apache.org/licenses/LICENSE-2.0
 
12
#
 
13
# Unless required by applicable law or agreed to in writing,
 
14
# software distributed under the License is distributed on an
 
15
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 
16
# KIND, either express or implied.  See the License for the
 
17
# specific language governing permissions and limitations
 
18
# under the License.
 
19
 
 
20
"""
 
21
A script that takes a .svn/pristine/ hierarchy, with its existing
 
22
.svn/wc.db database, and populates the database's PRISTINE table
 
23
accordingly.  (Use 'svn cleanup' to remove unreferenced pristines.)
 
24
 
 
25
Usage:
 
26
 
 
27
  %s /path/to/wc [...]
 
28
"""
 
29
 
 
30
# TODO: resolve the NotImplemented() in __main__
 
31
 
 
32
# TODO: increment refcount upon collision
 
33
# TODO: add <given file>, not just argv[1]/.svn/pristine/??/*
 
34
 
 
35
import hashlib
 
36
import os
 
37
import re
 
38
import sqlite3
 
39
import sys
 
40
 
 
41
# ### This could require any other format that has the same PRISTINE schema
 
42
# ### and semantics.
 
43
FORMAT = 22
 
44
BUFFER_SIZE = 4 * 1024
 
45
 
 
46
class UnknownFormat(Exception):
 
47
  def __init__(self, formatno):
 
48
    self.formatno = formatno
 
49
 
 
50
def open_db(wc_path):
 
51
  wc_db = os.path.join(wc_path, '.svn', 'wc.db')
 
52
  conn = sqlite3.connect(wc_db)
 
53
  curs = conn.cursor()
 
54
  curs.execute('pragma user_version;')
 
55
  formatno = int(curs.fetchone()[0])
 
56
  if formatno > FORMAT:
 
57
    raise UnknownFormat(formatno)
 
58
  return conn
 
59
 
 
60
_sha1_re = re.compile(r'^[0-9a-f]{40}$')
 
61
 
 
62
def md5_of(path):
 
63
  fd = os.open(path, os.O_RDONLY)
 
64
  ctx = hashlib.md5()
 
65
  while True:
 
66
    s = os.read(fd, BUFFER_SIZE)
 
67
    if len(s):
 
68
      ctx.update(s)
 
69
    else:
 
70
      os.close(fd)
 
71
      return ctx.hexdigest()
 
72
 
 
73
INSERT_QUERY = """
 
74
  INSERT OR REPLACE
 
75
  INTO pristine(checksum,compression,size,refcount,md5_checksum)
 
76
  VALUES (?,?,?,?,?)
 
77
"""
 
78
 
 
79
def populate(wc_path):
 
80
  conn = open_db(wc_path)
 
81
  sys.stdout.write("Updating '%s': " % wc_path)
 
82
  for dirname, dirs, files in os.walk(os.path.join(wc_path, '.svn/pristine/')):
 
83
    # skip everything but .svn/pristine/xx/
 
84
    if os.path.basename(os.path.dirname(dirname)) == 'pristine':
 
85
      sys.stdout.write("'%s', " % os.path.basename(dirname))
 
86
      for f in filter(lambda x: _sha1_re.match(x), files):
 
87
        fullpath = os.path.join(dirname, f)
 
88
        conn.execute(INSERT_QUERY,
 
89
                     ('$sha1$'+f, None, os.stat(fullpath).st_size, 1,
 
90
                      '$md5 $'+md5_of(fullpath)))
 
91
      # periodic transaction commits, for efficiency
 
92
      conn.commit()
 
93
  else:
 
94
    sys.stdout.write(".\n")
 
95
 
 
96
if __name__ == '__main__':
 
97
  raise NotImplemented("""Subversion does not know yet to avoid fetching
 
98
  a file when a file with matching sha1 appears in the PRISTINE table.""")
 
99
 
 
100
  paths = sys.argv[1:]
 
101
  if not paths:
 
102
    paths = ['.']
 
103
  for wc_path in paths:
 
104
    try:
 
105
      populate(wc_path)
 
106
    except UnknownFormat, e:
 
107
      sys.stderr.write("Don't know how to handle '%s' (format %d)'\n"
 
108
                       % (wc_path, e.formatno))