blob: 5c1fa4102aa693fb8e31303e0786355846f48b20 [file] [log] [blame]
epoger@google.com27442af2011-12-29 21:13:08 +00001'''
2Copyright 2011 Google Inc.
3
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6'''
7
epoger@google.com20ad5ac2012-01-17 21:26:05 +00008import fnmatch
9import os
epoger@google.com27442af2011-12-29 21:13:08 +000010import re
11import subprocess
12
13PROPERTY_MIMETYPE = 'svn:mime-type'
14
15class Svn:
16
17 def __init__(self, directory):
18 """Set up to manipulate SVN control within the given directory.
19
20 @param directory
21 """
22 self._directory = directory
23
24 def _RunCommand(self, args):
25 """Run a command (from self._directory) and return stdout as a single
26 string.
27
28 @param args a list of arguments
29 """
epoger@google.com20ad5ac2012-01-17 21:26:05 +000030 print 'RunCommand: %s' % args
epoger@google.com27442af2011-12-29 21:13:08 +000031 proc = subprocess.Popen(args, cwd=self._directory,
epoger@google.com20ad5ac2012-01-17 21:26:05 +000032 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
33 (stdout, stderr) = proc.communicate()
34 if proc.returncode is not 0:
35 raise Exception('command "%s" failed in dir "%s": %s' %
36 (args, self._directory, stderr))
epoger@google.com27442af2011-12-29 21:13:08 +000037 return stdout
38
epoger@google.com20ad5ac2012-01-17 21:26:05 +000039 def Checkout(self, url, path):
40 """Check out a working copy from a repository.
41 Returns stdout as a single string.
42
43 @param url URL from which to check out the working copy
44 @param path path (within self._directory) where the local copy will be
45 written
46 """
47 return self._RunCommand(['svn', 'checkout', url, path])
48
epoger@google.com27442af2011-12-29 21:13:08 +000049 def GetNewFiles(self):
50 """Return a list of files which are in this directory but NOT under
51 SVN control.
52 """
53 stdout = self._RunCommand(['svn', 'status'])
epoger@google.comd6256552012-01-10 14:10:34 +000054 new_regex = re.compile('^\?.....\s+(.+)$', re.MULTILINE)
55 files = new_regex.findall(stdout)
56 return files
57
58 def GetNewAndModifiedFiles(self):
59 """Return a list of files in this dir which are newly added or modified,
60 including those that are not (yet) under SVN control.
61 """
62 stdout = self._RunCommand(['svn', 'status'])
63 new_regex = re.compile('^[AM\?].....\s+(.+)$', re.MULTILINE)
epoger@google.com27442af2011-12-29 21:13:08 +000064 files = new_regex.findall(stdout)
65 return files
66
epoger@google.com2e0a0612012-05-25 19:48:05 +000067 def GetModifiedFiles(self):
68 """Return a list of files in this dir which are under SVN control, and
69 have been modified.
70 """
71 stdout = self._RunCommand(['svn', 'status'])
72 new_regex = re.compile('^M.....\s+(.+)$', re.MULTILINE)
73 files = new_regex.findall(stdout)
74 return files
75
epoger@google.com27442af2011-12-29 21:13:08 +000076 def AddFiles(self, filenames):
77 """Adds these files to SVN control.
78
79 @param filenames files to add to SVN control
80 """
epoger@google.com20ad5ac2012-01-17 21:26:05 +000081 self._RunCommand(['svn', 'add'] + filenames)
epoger@google.com27442af2011-12-29 21:13:08 +000082
83 def SetProperty(self, filenames, property_name, property_value):
84 """Sets a svn property for these files.
85
86 @param filenames files to set property on
87 @param property_name property_name to set for each file
88 @param property_value what to set the property_name to
89 """
epoger@google.com20ad5ac2012-01-17 21:26:05 +000090 if filenames:
91 self._RunCommand(
92 ['svn', 'propset', property_name, property_value] + filenames)
93
94 def SetPropertyByFilenamePattern(self, filename_pattern,
95 property_name, property_value):
96 """Sets a svn property for all files matching filename_pattern.
97
98 @param filename_pattern set the property for all files whose names match
99 this Unix-style filename pattern (e.g., '*.jpg')
100 @param property_name property_name to set for each file
101 @param property_value what to set the property_name to
102 """
103 all_files = os.listdir(self._directory)
epoger@google.com0f645b62012-05-22 19:14:01 +0000104 matching_files = sorted(fnmatch.filter(all_files, filename_pattern))
epoger@google.com20ad5ac2012-01-17 21:26:05 +0000105 self.SetProperty(matching_files, property_name, property_value)
epoger@google.com2e0a0612012-05-25 19:48:05 +0000106
107 def ExportBaseVersionOfFile(self, file_within_repo, dest_path):
108 """Retrieves a copy of the base version (what you would get if you ran
109 'svn revert') of a file within the repository.
110
111 @param file_within_repo path to the file within the repo whose base
112 version you wish to obtain
113 @param dest_path destination to which to write the base content
114 """
115 self._RunCommand(['svn', 'export', '--revision', 'BASE',
116 file_within_repo, dest_path])