Martin Schröder avatar Martin Schröder committed d2ab018

initial work

Comments (0)

Files changed (1)

+#!/usr/bin/env python
+
+import os
+import sys
+import yaml
+import hashlib
+import subprocess
+import zipfile
+import urllib2
+import re
+import shutil
+import shlex
+import fnmatch
+
+# Configuration
+breh_localtion = os.path.expanduser("/tmp/breh")
+sources_location = os.path.expanduser("~/.breh/sources")
+
+def download(source, target, blocksize = 8192):
+		with open(target, 'wb') as f:
+			u = urllib2.urlopen(source)
+			while True:
+			    buffer = u.read(blocksize)
+			    if not buffer:
+				break	
+			    f.write(buffer)
+			    
+def pathLength(p):
+	return len([x for x in p.split(os.sep) if x is not ''])
+	
+def copytree(src, dst, exclude=[]):
+	for e in exclude:
+		if fnmatch.fnmatch(src,e):
+			return
+		
+	dst_dir = os.path.dirname(dst)
+	if not os.path.exists(dst_dir):
+		os.makedirs(dst_dir)
+	
+	if os.path.isdir(src):
+	    for item in os.listdir(src):
+		s = os.path.join(src, item)
+		d = os.path.join(dst, item)
+		copytree(s, d, exclude)
+	else:
+		shutil.copy(src, dst)
+
+class Source:
+	def __init__(self, type, url, branch=None, exclude=None, prepare=None):
+		self.__type = type
+		self.__url = url
+		self.__branch = branch
+		
+		if exclude is None:
+			self.__exclude = []
+		elif isinstance(exclude, list):
+			self.__exclude = exclude
+		else:
+			self.__exclude = [exclude]
+			
+		if(self.__type == 'svn'):
+			self.__exclude.append("*/.svn")
+		elif(self.__type == 'git'):
+			self.__exclude.append(".git*")
+			
+		if prepare is None:
+			self.__prepare = []
+		elif isinstance(exclude, list):
+			self.__prepare = prepare
+		else:
+			self.__prepare = [prepare]
+	
+	def getLocation(self):
+		return os.path.join(sources_location, self.getHash())
+	
+	def getHash(self):
+		return hashlib.sha1(self.__url).hexdigest()[:16]
+		
+	def fetch(self):
+		if(self.type == 'svn'):
+			self.__fetch_svn()
+		elif(self.type == 'git'):
+			self.__fetch_git()
+		elif(self.type == 'zip'):
+			self.__fetch_zip()
+		else:
+			raise Exception("No known source type: %s" % self.type)
+	
+	def __fetch_svn(self):
+		if not os.path.exists(self.getLocation()):
+			os.makedirs(self.getLocation())
+			cmd = 'svn checkout --force "%s" "%s"' % (self.__url, \
+				self.getLocation())
+			print cmd
+			subprocess.check_call(cmd, shell = True)
+		else:
+			cmd = 'svn update --force "%s"' % (self.getLocation())
+			print cmd
+			subprocess.check_call(cmd, shell = True)
+	
+	def __fetch_git(self):
+		if not os.path.exists(self.getLocation()):
+			os.makedirs(self.getLocation())
+			cmd = 'git clone --quiet "%s" "%s"' % (self.__url, \
+				self.getLocation())
+			print cmd
+			subprocess.check_call(cmd, shell = True)
+		else:
+			cmd = 'git --git-dir="%s" fetch --quiet "%s"' % (\
+				os.path.join(self.getLocation(), ".git"),
+				self.__url)
+			print cmd
+			subprocess.check_call(cmd, shell = True)
+		
+		if self.branch is not None:
+			cmd = 'git --git-dir="%s" --work-tree="%s" '\
+			'checkout --quiet --force "%s"' % (\
+					os.path.join(self.getLocation(), ".git"),
+					self.getLocation(),
+					self.__branch)
+			print cmd
+			subprocess.check_call(cmd, shell = True)
+	
+	def __fetch_zip(self):
+		if not os.path.exists(self.getLocation()):
+			os.makedirs(self.getLocation())
+		file_name = self.__url.split('/')[-1]
+		local_path = os.path.join(breh_localtion,file_name)
+		
+		download(self.url,local_path)
+		
+		with zipfile.ZipFile(local_path, 'r') as zf:
+			files = zf.namelist()
+			pre = os.path.commonprefix(files)
+			
+			# exclude dirs
+			files = [x for x in files if x[-1] != '/']
+			
+			for zfilename in files:
+				dfilename = os.path.join(self.getLocation(), \
+					zfilename[len(pre):])
+				
+				upperdirs = os.path.dirname(dfilename)
+				if upperdirs and not os.path.exists(upperdirs):
+				    os.makedirs(upperdirs)
+				
+				with open(dfilename, "w") as f:
+					with zf.open(zfilename) as source_file:
+						shutil.copyfileobj(source_file, f)
+		
+	def copyMemberTo(self, member, target):
+		pass
+	
+	def getExclude(self):
+		return self.__exclude
+		
+	def prepare(self):
+		for prepare_command in self.__prepare:
+			print self.getLocation(), prepare_command
+			p = subprocess.Popen(shlex.split(prepare_command), \
+				cwd=self.getLocation())
+			p.wait()
+				
+			
+		
+# Check existence of breh.yaml
+if not os.path.exists("breh.yaml"):
+	print >>sys.stderr, "breh.yaml not found"
+	exit(1)
+	
+with open("breh.yaml") as f:
+	configuration = yaml.safe_load(f)
+	
+# Read sources
+sources = {}
+for name, data in configuration['sources'].iteritems():
+	sources[name]=(Source(**data))
+	
+# Make breh dir
+if not os.path.exists(breh_localtion):
+	os.makedirs(breh_localtion)
+
+# Fetch sources
+"""for name, source in sources.iteritems():
+	print "Fetching ", name
+	source.fetch()"""
+	
+# Prepare sources
+for name, source in sources.iteritems():
+	print "Preparing ", name
+	source.prepare()
+	
+# Sort files by path length
+files = configuration['files'].items();
+files.sort(cmp=lambda x,y: cmp(pathLength(x[0]),pathLength(y[0])))
+
+current_breh_localtion = os.path.join(breh_localtion, \
+	hashlib.sha1(os.getcwd()).hexdigest()[:16])
+
+if os.path.exists(current_breh_localtion):
+	shutil.rmtree(current_breh_localtion)
+
+for f, sf in files:
+	source_name, source_path = sf.split(":", 1)
+	try:
+		source = sources[source_name]
+	except KeyError:
+		print >>sys.stderr, "source %s not found (in rule %s)" % (\
+			source_name, sf)
+		
+	if f.startswith("/"):
+		f = f[1:]
+	
+	source_path = os.path.join(source.getLocation(), source_path)
+	target_path = os.path.join(current_breh_localtion, f)
+	
+	
+	if not os.path.exists(os.path.dirname(target_path)):
+		os.makedirs(os.path.dirname(target_path))
+	
+	exclude = map(lambda x: os.path.join(source.getLocation(), x), \
+			source.getExclude())
+	copytree(source_path, target_path, exclude)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.