def git_commit(args): if len(args) == 3: try: repo = Gittle('.') print repo.commit(name=args[1],email=args[2],message=args[0]) except: print 'Error: {0}'.format(sys.exc_value) else: print command_help['commit']
def gitPush(): logging.info('*** Versioning files and pushing to remote repository ***') destinations = [dataDestination, PDFdestination] remotes = ['dataRemote', 'PDFRemote'] for d, r in zip(destinations, remotes): repo = Gittle(d, origin_uri=config.get('Git', r)) repo.stage(repo.pending_files) repo.commit(message=commitMessage) repo.push()
class MyGit: def __init__(self, gitdir): self.git = Gittle(gitdir) def add(self, files, message): self.git.commit(message=message, files=files) def rm(self, files, message): self.git.rm(files) self.git.commit(message=message)
class Git(object): @classmethod def is_dir_git_repo(cls, directory): return os.system("git rev-parse --is-inside-work-tree") == 0 def __init__(self, gitpath): self._gitpath = gitpath try: self._gittle = Gittle(gitpath) except dulwich.errors.NotGitRepository: raise NoTesseraRepoError() @property def git_dir(self): """ Returns the git dir. """ return self._gittle.git_dir def is_working(self): """ Checks if git is working """ return self._gittle.is_working def commit_repo(self, tesserae, message): """ Commits the git tessera files. """ return self._gittle.commit(message=message, files=[os.path.relpath(tesserae.configpath, self._gitpath)]) def add_tessera(self, tessera): """ Commits a Tessera created by the create() method to the repository. """ return self._gittle.commit(message="tessera created: %s" % tessera.title, files=[os.path.relpath(tessera.tessera_file, self._gitpath), os.path.relpath(tessera.info_file, self._gitpath)]) def update_tessera(self, tessera): """ Commits an updated Tessera to the repository. """ return self._gittle.commit(message="tessera updated: %s" % tessera.title, files=[os.path.relpath(tessera.tessera_file, self._gitpath), os.path.relpath(tessera.info_file, self._gitpath)]) def rm_tessera(self, tessera): """ Removes a tessera and commits to git repository. """ files = [str(os.path.relpath(tessera.tessera_file, self._gitpath)), str(os.path.relpath(tessera.info_file, self._gitpath))] self._gittle.rm(files) return self._gittle.commit(message="tessera removed: %s" % tessera.title, files=files)
class GPassGit: #Creates a Git object def __init__(self, repoPath): self.repoPath = repoPath self.repo = None if self.isRepoSet(): self.repo = Gittle(self.repoPath) #Check For Git Repo def isRepoSet(self): if os.path.isfile(self.repoPath + '/.git/config'): return True return False def init(self, repoPath): self.repo = Gittle.init(repoPath) print("Created Repo") def add(self, filePath): self.repo.stage([filePath]) def commit(self, user, em, msg): self.repo.commit( name=user, email=em, message=msg ) # Authentication with RSA private key def auth(self, key): key_file = open(key) repo.auth(pkey=key_file) def push(self, key): self.auth(key) self.repo.push() def pull(self, key): self.auth(key) self.repo.pull() def acp(self, filepath, user, em, msg): self.add(filepath) self.commit(user, em, msg) self.push(key)
def GitUpload(file, Name, Email, Password, Repository, Message="Some uploads"): origin_uris = Repository if not origin_uris.startswith(Name): origin_uris = Name + "/" + origin_uris if not origin_uris.startswith("https://github.com/"): origin_uris = "https://github.com/" + origin_uris if not origin_uris.endswith(".git"): origin_uris = origin_uris + ".git" path = os.getcwd() # Gittle.clone() 会将当前目录下的文件下载到本地,并初始化git工作路径,上传文件正常 # repo = Gittle.clone("https://github.com/fengfeng0918/gittle.git", path) # Gittle.init() 初始化git工作路径,并没有将远程仓库信息拉到本地,上传(push)文件时会将远程库清空 # repo = Gittle.init(path,origin_uri="https://github.com/fengfeng0918/gittle.git") # git init 以下流程正常!!! if not os.path.exists(".git"): local_repo = Gittle.init(path) # local_repo = Gittle.clone(origin_uris,path) bares = False #不会删除远端,重写本地 else: local_repo = Repo(path) bares = True # 不会删除远端,不重写本地 repo = Gittle(local_repo, origin_uris) repo.fetch(bare=bares) # Stage file if not isinstance(file, list): file = [file] repo.stage(file) # Commiting repo.commit(name=Name, email=Email, message=Message, files=file) # add remote repo.add_remote('origin', origin_uris) # Push repo.auth(username=Name, password=Password) # Auth for pushing repo.push()
class GitGittle(BaseGit): def __init__(self): self.repo = None def git_init(self): try: # Init repository logger.debug("Local repository path:{}, Git server url: {}".format( conf.git.local_repository_path, conf.git.git_server_url)) self.repo = Gittle(conf.git.local_repository_path, origin_uri=conf.git.git_server_url) logger.info("Pulling from git..") # Update local working copy self.repo.pull() logger.info("GitGittle - Git is up to date !") except Exception as exc: logger.error( "GitGittle - Failed to initialize Git. Reason: {}".format( exc.message)) raise GitInitError(exc.message) def git_upload_changes(self): commit_id = "" try: logger.info("Commit changes in progress ..") # Stage modified files self.repo.stage(self.repo.pending_files) commit_message = conf.git.commit_message_format.format( self.repo.added_files) # Commit the change commit_id = self.repo.commit(conf.git.commit_user, conf.git.commit_email, commit_message) logger.info("Commit details: commit_user:{}, commit_email:{}, " "commit_message:{}, commit_id:{}".format( conf.git.commit_user, conf.git.commit_email, commit_message, commit_id)) # Push to repository self.repo.push() except Exception as exc: logger.error("GitGittle - Filed to upload file to git.") raise GitUploadError("Failed to upload file to Git") return commit_id def validate_git(self): pass
class MyGit: def __init__(self, gitdir): self.git = Gittle(gitdir) def add(self, files, message): self.git.commit(message=message, files=files) def rm(self, files, message): self.git.rm(files) self.git.commit(message=message) def read_author(self, tessera_path): author = "unknown" author_time = 0; walker = self.git.repo.get_walker(paths=[tessera_path]) try: c = iter(walker).next().commit except StopIteration: print "git: author not found in %s" % tessera_path else: author = c.author author_time = c.author_time return (author, author_time)
def git_pull(self, TMP_DIR, CODE_DIR): ''' git pull code use commit id tag you code lastest = [info['sha'] for info in repo.commit_info()[1:3]] print((repo.diff(*lastest, diff_type='classic'))) ''' print("========%s: git pull for env:test=========" % self.PRO_NAME) repo = Gittle(self.CODE_DIR, self.REPO_URL) command = 'cd %s && git pull' % self.CODE_DIR os.system('command') COMMIT_ID = repo.commit()[0:-30] CVER = "%s_%s_%s" % (self.PRO_NAME, self.CTIME, COMMIT_ID) CODE_TMP = '%s/%s' % (TMP_DIR, CVER) shutil.copytree(CODE_DIR, CODE_TMP) echo_info("git pull success") return CVER
class Wiki(HookMixin): path = None base_path = '/' default_ref = 'master' default_committer_name = 'Anon' default_committer_email = '*****@*****.**' index_page = 'home' gittle = None repo = None def __init__(self, path): try: self.gittle = Gittle(path) except NotGitRepository: self.gittle = Gittle.init(path) # Dulwich repo self.repo = self.gittle.repo self.path = path def __repr__(self): return "Wiki: %s" % self.path def _get_user(self, username, email): if not username: username = self.default_committer_name if not email: email = self.default_committer_email return username, email def _cache_key(self, name, sha='HEAD'): return 'page/%s[%s]' % (name, sha) def revert_page(self, name, commit_sha, message, username, email): """Revert page to passed commit sha1 :param name: Name of page to revert. :param commit_sha: Commit Sha1 to revert to. :param message: Commit message. :param username: Committer name. :param email: Committer email. :return: Git commit sha1 """ page = self.get_page(name, commit_sha) if not page: raise PageNotFound('Commit not found') if not message: commit_info = gittle.utils.git.commit_info( self.gittle[commit_sha.encode('latin-1')]) message = commit_info['message'] return self.write_page(name, page['data'], message=message, username=username, email=email) def write_page(self, name, content, message=None, create=False, username=None, email=None): """Write page to git repo :param name: Name of page. :param content: Content of page. :param message: Commit message. :param create: Perform git add operation? :param username: Commit Name. :param email: Commit Email. :return: Git commit sha1. """ cname = to_canonical(name) filename = cname_to_filename(cname) dirname = posixpath.join(self.path, posixpath.dirname(filename)) if not os.path.exists(dirname): os.makedirs(dirname) with open(self.path + "/" + filename, 'w') as f: f.write(content) if create: self.gittle.add(filename) if not message: message = "Updated %s" % name username, email = self._get_user(username, email) ret = self.gittle.commit(name=username, email=email, message=message, files=[filename]) cache.delete(self._cache_key(cname)) return ret def rename_page(self, old_name, new_name, username=None, email=None, message=None): """Rename page. :param old_name: Page that will be renamed. :param new_name: New name of page. :param username: Committer name :param email: Committer email :return: str -- Commit sha1 """ old_filename, new_filename = map(cname_to_filename, [old_name, new_name]) if old_filename not in self.gittle.index: # old doesn't exist return None if old_filename == new_filename: return if new_filename in self.gittle.index: # file is being overwritten, but that is ok, it's git! pass username, email = self._get_user(username, email) if not message: message = "Moved %s to %s" % (old_name, new_name) os.rename(os.path.join(self.path, old_filename), os.path.join(self.path, new_filename)) self.gittle.add(new_filename) self.gittle.rm(old_filename) commit = self.gittle.commit(name=username, email=email, message=message, files=[old_filename, new_filename]) cache.delete_many(self._cache_key(old_name), self._cache_key(new_name)) return commit def delete_page(self, name, username=None, email=None, message=None): """Delete page. :param name: Page that will be deleted :param username: Committer name :param email: Committer email :return: str -- Commit sha1 """ username, email = self._get_user(username, email) if not message: message = "Deleted %s" % name filename = cname_to_filename(name) # gittle.rm won't actually remove the file, have to do it ourselves os.remove(os.path.join(self.path, filename)) self.gittle.rm(filename) commit = self.gittle.commit(name=username, email=email, message=message, files=[filename]) cache.delete_many(self._cache_key(name)) return commit def get_page(self, name, sha='HEAD'): """Get page data, partials, commit info. :param name: Name of page. :param sha: Commit sha. :return: dict """ cached = cache.get(self._cache_key(name, sha)) if cached: return cached # commit = gittle.utils.git.commit_info(self.repo[sha]) filename = cname_to_filename(name).encode('utf8') sha = sha.encode('latin-1') try: data = self.gittle.get_commit_files(sha, paths=[filename]).get(filename) if not data: return None partials = {} if data.get('data'): meta = self.get_meta(data['data']) if meta and 'import' in meta: for partial_name in meta['import']: partials[partial_name] = self.get_page(partial_name) data['partials'] = partials data['info'] = self.get_history(name, limit=1)[0] cache.set(self._cache_key(name, sha), data) return data except KeyError: # HEAD doesn't exist yet return None def get_meta(self, content): """Get metadata from page if any. :param content: Page content :return: dict """ if not content.startswith("---"): return None meta_end = re.search("\n(\.{3}|\-{3})", content) if not meta_end: return None try: return yaml.safe_load(content[0:meta_end.start()]) except Exception as e: return {'error': e.message} def compare(self, name, old_sha, new_sha): """Compare two revisions of the same page. :param name: Name of page. :param old_sha: Older sha. :param new_sha: Newer sha. :return: str - Raw markup with styles """ # TODO: This could be effectively done in the browser old = self.get_page(name, sha=old_sha) new = self.get_page(name, sha=new_sha) return ghdiff.diff(old['data'], new['data']) def get_index(self): """Get repo index of head. :return: list -- List of dicts """ rv = [] index = self.repo.open_index() for name in index: rv.append( dict(name=filename_to_cname(name), filename=name, ctime=index[name].ctime[0], mtime=index[name].mtime[0], sha=index[name].sha, size=index[name].size)) return rv def get_history(self, name, limit=100): """Get page history. :param name: Name of page. :param limit: Limit history size. :return: list -- List of dicts """ if not len(self.repo.open_index()): # Index is empty, no commits return [] file_path = cname_to_filename(name) versions = [] walker = self.repo.get_walker(paths=[file_path], max_entries=limit) for entry in walker: change_type = None for change in entry.changes(): if change.old.path == file_path: change_type = change.type elif change.new.path == file_path: change_type = change.type author_name, author_email = entry.commit.author.rstrip('>').split( '<') versions.append( dict(author=author_name.strip(), author_email=author_email, time=entry.commit.author_time, message=entry.commit.message, sha=entry.commit.id, type=change_type)) return versions
class Wiki(HookMixin): path = None base_path = '/' default_ref = 'master' default_committer_name = 'Anon' default_committer_email = '*****@*****.**' index_page = 'home' gittle = None repo = None def __init__(self, path): try: self.gittle = Gittle(path) except NotGitRepository: self.gittle = Gittle.init(path) # Dulwich repo self.repo = self.gittle.repo self.path = path def __repr__(self): return "Wiki: %s" % self.path def revert_page(self, name, commit_sha, message, username): page = self.get_page(name, commit_sha) if not page: # Page not found return None commit_info = gittle.utils.git.commit_info(self.gittle[commit_sha.encode('latin-1')]) message = commit_info['message'] return self.write_page(name, page['data'], message=message, username=username) def write_page(self, name, content, message=None, create=False, username=None, email=None): def escape_repl(m): if m.group(1): return "```" + escape(m.group(1)) + "```" def unescape_repl(m): if m.group(1): return "```" + unescape(m.group(1)) + "```" cname = to_canonical(name) # prevents p tag from being added, we remove this later content = '<div>' + content + '</div>' content = re.sub(r"```(.*?)```", escape_repl, content, flags=re.DOTALL) tree = lxml.html.fromstring(content) cleaner = Cleaner(remove_unknown_tags=False, kill_tags=set(['style']), safe_attrs_only=False) tree = cleaner.clean_html(tree) content = lxml.html.tostring(tree, encoding='utf-8', method='html') # remove added div tags content = content[5:-6] # FIXME this is for block quotes, doesn't work for double ">" content = re.sub(r"(\n>)", "\n>", content) content = re.sub(r"(^>)", ">", content) # Handlebars partial ">" content = re.sub(r"\{\{>(.*?)\}\}", r'{{>\1}}', content) # Handlebars, allow {{}} inside HTML links content = content.replace("%7B", "{") content = content.replace("%7D", "}") content = re.sub(r"```(.*?)```", unescape_repl, content, flags=re.DOTALL) filename = cname_to_filename(cname) with open(self.path + "/" + filename, 'w') as f: f.write(content) if create: self.gittle.add(filename) if not message: message = "Updated %s" % name if not username: username = self.default_committer_name if not email: email = self.default_committer_email ret = self.gittle.commit(name=username, email=email, message=message, files=[filename]) cache.delete(cname) return ret def rename_page(self, old_name, new_name, user=None): old_filename, new_filename = map(cname_to_filename, [old_name, new_name]) if old_filename not in self.gittle.index: # old doesn't exist return None if new_filename in self.gittle.index: # file is being overwritten, but that is ok, it's git! pass os.rename(os.path.join(self.path, old_filename), os.path.join(self.path, new_filename)) self.gittle.add(new_filename) self.gittle.rm(old_filename) self.gittle.commit(name=getattr(user, 'username', self.default_committer_name), email=getattr(user, 'email', self.default_committer_email), message="Moved %s to %s" % (old_name, new_name), files=[old_filename, new_filename]) cache.delete_many(old_filename, new_filename) def get_page(self, name, sha='HEAD'): cached = cache.get(name) if cached: return cached # commit = gittle.utils.git.commit_info(self.repo[sha]) filename = cname_to_filename(name).encode('latin-1') sha = sha.encode('latin-1') try: data = self.gittle.get_commit_files(sha, paths=[filename]).get(filename) if not data: return None partials = {} if data.get('data'): meta = self.get_meta(data['data']) if meta and 'import' in meta: for partial_name in meta['import']: partials[partial_name] = self.get_page(partial_name) data['partials'] = partials data['info'] = self.get_history(name, limit=1)[0] return data except KeyError: # HEAD doesn't exist yet return None def get_meta(self, content): if not content.startswith("---"): return None meta_end = re.search("\n(\.{3}|\-{3})", content) if not meta_end: return None try: return yaml.safe_load(content[0:meta_end.start()]) except Exception as e: return {'error': e.message} def compare(self, name, old_sha, new_sha): old = self.get_page(name, sha=old_sha) new = self.get_page(name, sha=new_sha) return ghdiff.diff(old['data'], new['data']) def get_index(self): rv = [] index = self.repo.open_index() for name in index: rv.append(dict(name=filename_to_cname(name), filename=name, ctime=index[name].ctime[0], mtime=index[name].mtime[0], sha=index[name].sha, size=index[name].size)) return rv def get_history(self, name, limit=100): file_path = cname_to_filename(name) versions = [] walker = self.repo.get_walker(paths=[file_path], max_entries=limit) for entry in walker: change_type = None for change in entry.changes(): if change.old.path == file_path: change_type = change.type elif change.new.path == file_path: change_type = change.type author_name, author_email = entry.commit.author.split('<') versions.append(dict( author=author_name.strip(), time=entry.commit.author_time, message=entry.commit.message, sha=entry.commit.id, type=change_type)) return versions
class Wiki(HookMixin): path = None base_path = '/' default_ref = 'master' default_committer_name = 'Anon' default_committer_email = '*****@*****.**' index_page = 'home' gittle = None repo = None def __init__(self, path): try: self.gittle = Gittle(path) except NotGitRepository: self.gittle = Gittle.init(path) # Dulwich repo self.repo = self.gittle.repo self.path = path def __repr__(self): return "Wiki: %s" % self.path def _get_user(self, username, email): if not username: username = self.default_committer_name if not email: email = self.default_committer_email return username, email def revert_page(self, name, commit_sha, message, username, email): """Revert page to passed commit sha1 :param name: Name of page to revert. :param commit_sha: Commit Sha1 to revert to. :param message: Commit message. :param username: Committer name. :param email: Committer email. :return: Git commit sha1 """ page = self.get_page(name, commit_sha) if not page: raise PageNotFound('Commit not found') if not message: commit_info = gittle.utils.git.commit_info(self.gittle[commit_sha.encode('latin-1')]) message = commit_info['message'] return self.write_page(name, page['data'], message=message, username=username, email=email) def write_page(self, name, content, message=None, create=False, username=None, email=None): """Write page to git repo :param name: Name of page. :param content: Content of page. :param message: Commit message. :param create: Perform git add operation? :param username: Commit Name. :param email: Commit Email. :return: Git commit sha1. """ cname = to_canonical(name) filename = cname_to_filename(cname) namespace_path = os.path.join(self.path, os.path.split(filename)[0]) if not os.path.exists(namespace_path): os.makedirs(namespace_path) with open(self.path + "/" + filename, 'w') as f: f.write(content) if create: self.gittle.add(filename) if not message: message = "Updated %s" % name username, email = self._get_user(username, email) ret = self.gittle.commit(name=username, email=email, message=message, files=[filename]) cache.delete(cname) return ret def rename_page(self, old_name, new_name, username=None, email=None, message=None): """Rename page. :param old_name: Page that will be renamed. :param new_name: New name of page. :param username: Committer name :param email: Committer email :return: str -- Commit sha1 """ old_filename, new_filename = map(cname_to_filename, [old_name, new_name]) if old_filename not in self.gittle.index: # old doesn't exist return None if new_filename in self.gittle.index: # file is being overwritten, but that is ok, it's git! pass username, email = self._get_user(username, email) if not message: message = "Moved %s to %s" % (old_name, new_name) os.rename(os.path.join(self.path, old_filename), os.path.join(self.path, new_filename)) self.gittle.add(new_filename) self.gittle.rm(old_filename) commit = self.gittle.commit(name=username, email=email, message=message, files=[old_filename, new_filename]) cache.delete_many(old_name, new_name) return commit def delete_page(self, name, username=None, email=None, message=None): """Delete page. :param name: Page that will be deleted :param username: Committer name :param email: Committer email :return: str -- Commit sha1 """ username, email = self._get_user(username, email) if not message: message = "Deleted %s" % name filename = cname_to_filename(name) self.gittle.rm(filename) commit = self.gittle.commit(name=username, email=email, message=message, files=[str(filename)]) cache.delete_many(name) return commit def get_page(self, name, sha='HEAD'): """Get page data, partials, commit info. :param name: Name of page. :param sha: Commit sha. :return: dict """ cached = cache.get(name) if cached: return cached # commit = gittle.utils.git.commit_info(self.repo[sha]) filename = cname_to_filename(name).encode('latin-1') sha = sha.encode('latin-1') namespace_path = os.path.join(self.path, os.path.splitext(filename)[0]) namespace_cname = to_canonical(os.path.splitext(filename)[0]) if not os.path.exists(os.path.join(self.path, filename)) and os.path.isdir(namespace_path): files = ["[%s](%s_%s)" % (x, namespace_cname, filename_to_cname(x)) for x in os.listdir(namespace_path)] print(files) return {'data': "# Namespace %s \n\n This is an automatically generated list of pages in this namespace.\n\n %s" % (os.path.splitext(filename)[0], '\n'.join(files))} try: data = self.gittle.get_commit_files(sha, paths=[filename]).get(filename) if not data: return None partials = {} if data.get('data'): meta = self.get_meta(data['data']) if meta and 'import' in meta: for partial_name in meta['import']: partials[partial_name] = self.get_page(partial_name) data['partials'] = partials data['info'] = self.get_history(name, limit=1)[0] return data except KeyError: # HEAD doesn't exist yet return None def get_meta(self, content): """Get metadata from page if any. :param content: Page content :return: dict """ if not content.startswith("---"): return None meta_end = re.search("\n(\.{3}|\-{3})", content) if not meta_end: return None try: return yaml.safe_load(content[0:meta_end.start()]) except Exception as e: return {'error': e.message} def compare(self, name, old_sha, new_sha): """Compare two revisions of the same page. :param name: Name of page. :param old_sha: Older sha. :param new_sha: Newer sha. :return: str - Raw markup with styles """ # TODO: This could be effectively done in the browser old = self.get_page(name, sha=old_sha) new = self.get_page(name, sha=new_sha) return ghdiff.diff(old['data'], new['data']) def get_index(self): """Get repo index of head. :return: list -- List of dicts """ rv = [] index = self.repo.open_index() for name in index: rv.append(dict(name=filename_to_cname(name), filename=name, ctime=index[name].ctime[0], mtime=index[name].mtime[0], sha=index[name].sha, size=index[name].size)) return rv def get_history(self, name, limit=100): """Get page history. :param name: Name of page. :param limit: Limit history size. :return: list -- List of dicts """ if not len(self.repo.open_index()): # Index is empty, no commits return [] file_path = cname_to_filename(name) versions = [] walker = self.repo.get_walker(paths=[file_path], max_entries=limit) for entry in walker: change_type = None for change in entry.changes(): if change.old.path == file_path: change_type = change.type elif change.new.path == file_path: change_type = change.type author_name, author_email = entry.commit.author.split('<') versions.append(dict( author=author_name.strip(), time=entry.commit.author_time, message=entry.commit.message, sha=entry.commit.id, type=change_type)) return versions
class Wiki(HookMixin): path = None base_path = '/' default_ref = 'master' default_committer_name = 'Anon' default_committer_email = '*****@*****.**' index_page = 'home' gittle = None repo = None def __init__(self, path): try: self.gittle = Gittle(path) except NotGitRepository: self.gittle = Gittle.init(path) # Dulwich repo self.repo = self.gittle.repo self.path = path def __repr__(self): return "Wiki: %s" % self.path def commit(self, name, email, message, files): """Commit to the underlying git repo. :param name: Committer name :param email: Committer email :param message: Commit message :param files: list of file names that should be committed :return: """ # Dulwich and gittle seem to want us to encode ourselves at the moment. see #152 if isinstance(name, unicode): name = name.encode('utf-8') if isinstance(email, unicode): email = email.encode('utf-8') if isinstance(message, unicode): message = message.encode('utf-8') return self.gittle.commit(name=name, email=email, message=message, files=files) def get_page(self, name, sha='HEAD'): """Get page data, partials, commit info. :param name: Name of page. :param sha: Commit sha. :return: dict """ return WikiPage(name, self, sha=sha) def get_index(self): """Get repo index of head. :return: list -- List of dicts """ rv = [] index = self.repo.open_index() for name in index: rv.append(dict(name=filename_to_cname(name), filename=name, ctime=index[name].ctime[0], mtime=index[name].mtime[0], sha=index[name].sha, size=index[name].size)) return rv
class GitCommands(object): def __init__(self): self.gitdir = "." self.git = Gittle(self.gitdir) Tessera._tesserae = os.path.relpath("%s/.tesserae" % self.gitdir) def cmd_init(self, args): if len(args) != 0: stderr.write("git tessera init takes no arguments\n") return False #if self.git.is_dirty(): #stderr.write("repo is dirty\n") #return False if os.path.exists(Tessera._tesserae): stderr.write("git tesserae directory already exists: %s\n" % Tessera._tesserae) return False os.mkdir(Tessera._tesserae) files = [] t = "%s/template" % Tessera._tesserae shutil.copyfile("%s/config/template" % os.path.dirname(os.path.realpath(__file__)), t) files.append(t) t = "%s/status" % Tessera._tesserae shutil.copyfile("%s/config/status" % os.path.dirname(os.path.realpath(__file__)), t) files.append(t) t = "%s/types" % Tessera._tesserae shutil.copyfile("%s/config/types" % os.path.dirname(os.path.realpath(__file__)), t) files.append(t) self.git_add(files, "tessera: initialized") return True def cmd_ls(self, args): gt = GitTessera() tesserae = gt.ls(args) for t in tesserae: print t.summary() return True def cmd_show(self, args): if len(args) != 1: stderr.write("git tessera show takes identifier as argument\n") return False gt = GitTessera() t = gt.get(args[0]) if not t: return False short = t.summary() length = len(short) print "=" * length print short print "=" * length print t.content return True def cmd_edit(self, args): if len(args) < 1: stderr.write("git tessera edit takes one or more identifier as argument\n") return False tessera_paths = [] for key in args: tessera_path = None found = False for i in os.listdir(Tessera._tesserae): tessera_path = "%s/%s" % (Tessera._tesserae, i) if not stat.S_ISDIR(os.lstat(tessera_path).st_mode): continue if i.split('-')[0] == key or i == key: found = True break if not found: stderr.write("git tessera %s not found\n" % key) return False tessera_paths.append(tessera_path) tessera_files = ["%s/tessera" % x for x in tessera_paths] p = Popen(["sensible-editor"] + tessera_files) p.communicate() p.wait() #if self.git.is_dirty(): for tessera_path in tessera_paths: t = Tessera(tessera_path) self.git_add("%s/tessera" % tessera_path, "tessera updated: %s" % t.title) return True def cmd_create(self, args): if len(args) < 1: stderr.write("git tessera create needs arguments\n") return False #if self.git.is_dirty(): # stderr.write("repo is dirty\n") # return False if args: title = " ".join(args) else: title = "tessera title goes here" uuid = uuid1() tessera_path = "%s/%s" % (Tessera._tesserae, uuid) tessera_file = "%s/tessera" % tessera_path os.mkdir(tessera_path) fin = open("%s/template" % Tessera._tesserae, "r") fout = open(tessera_file, "w") for line in fin.readlines(): if line == "@title@\n": line = "# %s\n" % title fout.write(line) fin.close() fout.close() p = Popen(["sensible-editor", tessera_file]) p.communicate() p.wait() t = Tessera(tessera_path) self.git_add(tessera_file, "tessera created: %s" % t.get_attribute("title")) return True def cmd_remove(self, args): if len(args) != 1: stderr.write("git tessera remove takes identifier as argument\n") return False #if self.git.is_dirty(): #stderr.write("repo is dirty\n") #return False key = args[0] tessera_file = None tessera_path = None for i in os.listdir(Tessera._tesserae): tessera_path = "%s/%s" % (Tessera._tesserae, i) if not stat.S_ISDIR(os.lstat(tessera_path).st_mode): continue if i.split('-')[0] == key or i == key: tessera_file = "%s/tessera" % tessera_path break if not tessera_file: stderr.write("git tessera %s not found\n" % key) return False t = Tessera(tessera_path) stdout.write("remove tessera %s: %s ? [Y/n] " % (key, t.get_attribute("title"))) try: answer = stdin.readline().strip() except KeyboardInterrupt: return False if not answer or answer.lower() == "y": files = ["%s/%s" % (tessera_path, x) for x in os.listdir(tessera_path)] self.git_rm(files, "tessera removed: %s" % t.get_attribute("title")) from shutil import rmtree rmtree(tessera_path) def cmd_serve(self, args): from tesseraweb import TesseraWeb web = TesseraWeb() web.serve() def cmd_tag(self, args): if len(args) != 2: stderr.write("git tessera show takes identifier as argument and new tag\n") return False key = args[0] for i in os.listdir(Tessera._tesserae): tessera_path = "%s/%s" % (Tessera._tesserae, i) if not stat.S_ISDIR(os.lstat(tessera_path).st_mode): continue if i.split('-')[0] == key or i == key: break if not tessera_path: stderr.write("git tessera %s not found\n" % key) return False t = Tessera(tessera_path) t.add_tag(args[1]) self.git_add(t.filename, "tessera updated: add tag %s to %s" % (args[1], t.get_attribute("title"))) return True def git_add(self, files, message): stderr.write("staging %s" % files) self.git.commit(message=message, files=files) def git_rm(self, files, message): self.git.rm(files) self.git.commit(message=message)