def from_comment(cls, env, comment, user=None, notify=True): """ Creates a subscription from a Comment object. """ sub = { 'user': user or comment.author, 'type': comment.type, 'notify': notify, } # Munge attachments if comment.type == 'attachment': sub['path'] = comment.path.split(':')[1] sub['repos'] = '' sub['rev'] = '' # Munge changesets and browser if comment.type in ('changeset', 'browser'): if comment.type == 'browser': sub['path'] = comment.path else: sub['path'] = '' repo = RepositoryManager(env).get_repository(None) try: sub['repos'] = repo.reponame try: _cs = repo.get_changeset(comment.revision) sub['rev'] = _cs.rev except NoSuchChangeset: # Invalid changeset return None finally: repo.close() return cls._from_dict(env, sub)
def for_request(cls, env, req, create=False): """ Return a **single** subscription for a HTTP request. """ reponame = req.args.get('reponame') rm = RepositoryManager(env) repos = rm.get_repository(reponame) path = req.args.get('path') or '' rev = req.args.get('rev') or repos.youngest_rev dict_ = { 'user': req.authname, 'type': req.args.get('realm'), 'path': '', 'rev': '', 'repos': '', } if dict_['type'] == 'attachment': dict_['path'] = path if dict_['type'] == 'changeset': dict_['rev'] = path[1:] dict_['repos'] = repos.reponame if dict_['type'] == 'browser': if len(path) == 0: dict_['path'] = '/' else: dict_['path'] = path[1:] dict_['rev'] = rev dict_['repos'] = repos.reponame return cls._from_dict(env, dict_, create=create)
def _do_changeset_added(self, reponame, *revs): if is_default(reponame): reponame = "" rm = RepositoryManager(self.env) errors = rm.notify("changeset_added", reponame, revs) for error in errors: printout(error)
def expand_macro(self, formatter, name, content, args={}): reponame = args.get('repository') or '' rev = args.get('revision') repos = RepositoryManager(self.env).get_repository(reponame) try: changeset = repos.get_changeset(rev) message = changeset.message rev = changeset.rev resource = repos.resource except Exception: message = content resource = Resource('repository', reponame) if formatter.context.resource.realm == 'ticket': ticket_re = CommitTicketUpdater.ticket_re if not any( int(tkt_id) == int(formatter.context.resource.id) for tkt_id in ticket_re.findall(message)): return tag.p( "(The changeset message doesn't reference this " "ticket)", class_='hint') if ChangesetModule(self.env).wiki_format_messages: return tag.div(format_to_html(self.env, formatter.context.child( 'changeset', rev, parent=resource), message, escape_newlines=True), class_='message') else: return tag.pre(message, class_='message')
def _process_browser_view(self, request): request.perm.require('BROWSER_VIEW') preselected = request.args.get('preselected') if preselected and (preselected + '/').startswith(request.href.browser() + '/'): request.redirect(preselected) elif request.path_info.startswith('/browser') and _valid_github_request(request): path = request.args.get('path', '/') rev = request.args.get('rev', '') if rev.lower() in ('', 'head'): rev = 'master' manager = RepositoryManager(self.env) repository_name, repository, path = manager.get_repository_by_path(path) repository_url = repository.params.get('url', '') if re.match(r'^https?://(?:www\.)?github\.com/', repository_url): url = repository_url.rstrip('/') + '/blob/' + rev + '/' + path request.redirect(url) else: return _old_process_browser_view(self, request) else: return _old_process_browser_view(self, request)
def expand_macro(self, formatter, name, content, args={}): reponame = args.get("repository") or "" rev = args.get("revision") repos = RepositoryManager(self.env).get_repository(reponame) try: changeset = repos.get_changeset(rev) message = changeset.message rev = changeset.rev resource = repos.resource except Exception: message = content resource = Resource("repository", reponame) if formatter.context.resource.realm == "ticket": ticket_re = CommitTicketUpdater.ticket_re if not any(int(tkt_id) == int(formatter.context.resource.id) for tkt_id in ticket_re.findall(message)): return tag.p("(The changeset message doesn't reference this " "ticket)", class_="hint") if ChangesetModule(self.env).wiki_format_messages: return tag.div( format_to_html( self.env, formatter.context.child("changeset", rev, parent=resource), message, escape_newlines=True ), class_="message", ) else: return tag.pre(message, class_="message")
def _do_changeset_modified(self, reponame, *revs): if is_default(reponame): reponame = '' rm = RepositoryManager(self.env) errors = rm.notify('changeset_modified', reponame, revs) for error in errors: printout(error)
def match_request(self, request): """Match requests which are POST, include a 'commit' argument, and point at an existing repo""" if request.method != 'POST': return False repo_name = _get_repo_name(request.path_info) if repo_name is None: return False repo = RepositoryManager(self.env).get_repository(repo_name) if repo is None: return False repo.close() from cgi import parse_qs request.args = parse_qs(request.read()) if request.args.get('commit', request.args.get('payload', None)) is None: return False ## XXX: evil hack to disable CSRF checking (is there a better way?) request._inheaders.insert(0, ('content-type', 'xx')) ## Go! self.log.info('Handling a beanstalk hook callback for repository [%s]' % repo_name) return True
def add_repository(self, name): """Add a repository.""" dir = os.path.join(self.parentpath, name) if not os.path.isabs(dir): raise TracError(_("The repository directory must be absolute")) trunk = os.path.join(dir, 'trunk') branches = os.path.join(dir, 'branches') tags = os.path.join(dir, 'tags') command = '"%(svnadmin)s" create "%(dir)s"; "%(svn)s" mkdir --parents -q -m "Created Folders" "file://%(trunk)s" "file://%(branches)s" "file://%(tags)s"' % { 'svnadmin': self.admin, 'dir': dir, 'svn': self.client, 'trunk': trunk, 'branches': branches, 'tags': tags } process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (result, error) = process.communicate() if error is not None and error != "": if error.find('E165002') > -1: raise TracError(_('The repository "%(name)s" already exists.', name=name)) elif error.find('E000002') > -1 or error.find('E000013') > -1: raise TracError(_("Can't create the repository '%(name)s.' " "Make sure the parent directory '%(parentpath)s' exists " "and the web server has write permissions for it.", name=name, parentpath=self.parentpath)) else: raise TracError(error) if self.hookspath and os.path.exists(self.hookspath): hooksdir = os.path.join(dir, 'hooks/') files = os.listdir(self.hookspath) files = [self.hookspath + '/' + filename for filename in files] for file in files: shutil.copy2(file, hooksdir) rm = RepositoryManager(self.env) rm.reload_repositories()
def _sync(self, reponame, rev, clean): rm = RepositoryManager(self.env) if reponame == '*': if rev is not None: raise TracError(_('Cannot synchronize a single revision ' 'on multiple repositories')) repositories = rm.get_real_repositories() else: if is_default(reponame): reponame = '' repos = rm.get_repository(reponame) if repos is None: raise TracError(_("Repository '%(repo)s' not found", repo=reponame or '(default)')) if rev is not None: repos.sync_changeset(rev) printout(_('%(rev)s resynced on %(reponame)s.', rev=rev, reponame=repos.reponame or '(default)')) return repositories = [repos] for repos in sorted(repositories, key=lambda r: r.reponame): printout(_('Resyncing repository history for %(reponame)s... ', reponame=repos.reponame or '(default)')) repos.sync(self._sync_feedback, clean=clean) for cnt, in self.env.db_query( "SELECT count(rev) FROM revision WHERE repos=%s", (repos.id,)): printout(ngettext('%(num)s revision cached.', '%(num)s revisions cached.', num=cnt)) printout(_('Done.'))
def from_comment(cls, env, comment, user=None, notify=True): """ Creates a subscription from a Comment object. """ sub = { 'user': user or comment.author, 'type': comment.type, 'notify': notify, } # Munge attachments if comment.type == 'attachment': sub['path'] = comment.path.split(':')[1] sub['repos'] = '' sub['rev'] = '' # Munge changesets and browser if comment.type in ('changeset', 'browser'): rm = RepositoryManager(env) reponame, repos, path = rm.get_repository_by_path(comment.path) if comment.type == 'browser': sub['path'] = path else: sub['path'] = '' sub['repos'] = reponame or '(default)' try: _cs = repos.get_changeset(comment.revision) except NoSuchChangeset: # Invalid changeset return None else: sub['rev'] = _cs.rev return cls.from_dict(env, sub)
def _do_seed(self): # Create a subscription for all existing attachments cursor = self.env.get_read_db().cursor() cursor.execute("SELECT DISTINCT type, id FROM attachment") rows = cursor.fetchall() for row in rows: for attachment in Attachment.select(self.env, row[0], row[1]): Subscription.from_attachment(self.env, attachment) # Create a subscription for all existing revisions rm = RepositoryManager(self.env) repos = rm.get_real_repositories() for repo in repos: _rev = repo.get_oldest_rev() while _rev: try: _cs = repo.get_changeset(_rev) Subscription.from_changeset(self.env, _cs) except NoSuchChangeset: pass _rev = repo.next_rev(_rev) # Create a subscription for all existing comments comments = Comments(None, self.env).all() for comment in comments: Subscription.from_comment(self.env, comment)
def _do_changeset_added(self, reponame, first_rev, *revs): if is_default(reponame): reponame = '' rm = RepositoryManager(self.env) errors = rm.notify('changeset_added', reponame, (first_rev, ) + revs) for error in errors: printout(error)
def expand_macro(self, formatter, name, content, args=None): args = args or {} reponame = args.get('repository') or '' rev = args.get('revision') repos = RepositoryManager(self.env).get_repository(reponame) try: changeset = repos.get_changeset(rev) message = changeset.message rev = changeset.rev resource = repos.resource except Exception: message = content resource = Resource('repository', reponame) if formatter.context.resource.realm == 'ticket': ticket_re = CommitTicketUpdater.ticket_re if not any(int(tkt_id) == int(formatter.context.resource.id) for tkt_id in ticket_re.findall(message)): return tag.p(_("(The changeset message doesn't reference this " "ticket)"), class_='hint') if ChangesetModule(self.env).wiki_format_messages: return tag.div(format_to_html(self.env, formatter.context.child('changeset', rev, parent=resource), message, escape_newlines=True), class_='message') else: return tag.pre(message, class_='message')
def _do_seed(self): # Create a subscription for all existing attachments for row in self.env.db_query(""" SELECT DISTINCT type, id FROM attachment """): for attachment in Attachment.select(self.env, row[0], row[1]): Subscription.from_attachment(self.env, attachment) # Create a subscription for all existing revisions rm = RepositoryManager(self.env) repos = rm.get_real_repositories() for repo in repos: _rev = repo.get_oldest_rev() while _rev: try: _cs = repo.get_changeset(_rev) Subscription.from_changeset(self.env, _cs) except NoSuchChangeset: pass _rev = repo.next_rev(_rev) # Create a subscription for all existing comments comments = Comments(None, self.env).all() for comment in comments: Subscription.from_comment(self.env, comment)
def expand_macro(self, formatter, name, content, args={}): reponame = args.get('repository') or '' rev = args.get('revision') repos = RepositoryManager(self.env).get_repository(reponame) try: changeset = repos.get_changeset(rev) message = changeset.message # add review status to commit message ( review = CodeReview(self.env, reponame, rev) status = review.encode(review.status) message += '\n\n{{{#!html \n' message += '<div class="codereviewstatus">' message += ' <div class="system-message %s">' % status.lower() message += ' <p>Code review status: ' message += ' <span>%s</span>' % review.status message += ' </p>' message += ' </div>' message += '</div>' message += '\n}}}' rev = changeset.rev resource = repos.resource except Exception, e: message = content resource = Resource('repository', reponame)
def for_request(cls, env, req, create=False): """ Return a **single** subscription for a HTTP request. """ rm = RepositoryManager(env) dict_ = { 'user': req.authname, 'type': req.args.get('realm'), 'path': '', 'rev': '', 'repos': '', } path = req.args.get('path') or '' if dict_['type'] == 'attachment': dict_['path'] = path if dict_['type'] == 'changeset': parts = [p for p in path.split('/') if p] dict_['rev'] = parts[0] dict_['repos'] = parts[1] if dict_['type'] == 'browser': reponame, repos, path = rm.get_repository_by_path(path) dict_['path'] = '/' if len(path) == 0 else path dict_['rev'] = req.args.get('rev') or '' dict_['repos'] = reponame return cls.from_dict(env, dict_, create=create)
def changeset_added(self, repos, changeset): newchange = changeset repo = RepositoryManager(self.env).repository_dir repdir = repo.split('.git')[0] changes = list(newchange.get_changes()) print '....handling wikipages.......' for change in changes: directory = change[0].split('/')[0] filename = change[0].split('/')[1] pagename = filename.split('.txt')[0] extension = filename.split(pagename)[1] if (directory == 'wiki' and extension == '.txt'): path = repdir + change[0] if change[2] == 'edit' or change[2] == 'add': self.add_wiki_file_to_trac(pagename, path) elif change[2] == 'delete': self.delete_wiki_page_in_trac(pagename) print (filename + ': wikipage removed.') else: print 'Nothing todo.' else: print 'File was no textfile. Keep going.' print '....wikipage handling done......have a nice day :)!'
def _process_changeset_view(self, request): request.perm.require('CHANGESET_VIEW') new = request.args.get('new') new_path = request.args.get('new_path') old = request.args.get('old') repository_name = request.args.get('reponame') # -- support for the revision log ''View changes'' form, # where we need to give the path and revision at the same time if old and '@' in old: old, old_path = old.split('@', 1) if new and '@' in new: new, new_path = new.split('@', 1) manager = RepositoryManager(self.env) if repository_name: repository = manager.get_repository(repository_name) else: repository_name, repository, new_path = manager.get_repository_by_path(new_path) repository_url = repository.params.get('url', '') if _valid_github_request(request) and re.match(r'^https?://(?:www\.)?github\.com/', repository_url): url = repository_url.rstrip('/') + '/' if old: url += 'compare/' + old + '...' + new else: url += 'commit/' + new request.redirect(url) else: return _old_process_changeset_view(self, request)
def _sync(self, reponame, rev, clean): rm = RepositoryManager(self.env) if reponame == '*': if rev is not None: raise TracError(_('Cannot synchronize a single revision ' 'on multiple repositories')) repositories = rm.get_real_repositories() else: if is_default(reponame): reponame = '' repos = rm.get_repository(reponame) if repos is None: raise TracError(_("Repository '%(repo)s' not found", repo=reponame or '(default)')) if rev is not None: repos.sync_changeset(rev) printout(_('%(rev)s resynced on %(reponame)s.', rev=rev, reponame=repos.reponame or '(default)')) return repositories = [repos] db = self.env.get_db_cnx() for repos in sorted(repositories, key=lambda r: r.reponame): printout(_('Resyncing repository history for %(reponame)s... ', reponame=repos.reponame or '(default)')) repos.sync(self._sync_feedback, clean=clean) cursor = db.cursor() cursor.execute("SELECT count(rev) FROM revision WHERE repos=%s", (repos.id,)) for cnt, in cursor: printout(ngettext('%(num)s revision cached.', '%(num)s revisions cached.', num=cnt)) printout(_('Done.'))
def process_request(self, request): payload = request.args.get('payload') if not payload: raise Exception('Payload not found') payload = simplejson.loads(payload) repository_name = payload['repository']['name'] repository = self.env.get_repository(repository_name) if not repository: raise Exception('Repository "%s" not found' % repository_name) # CachedRepository if repository.repos: repository.repos.git.repo.remote('update') # Normal repository else: repository.git.repo.remote('update') manager = RepositoryManager(self.env) revision_ids = [ commit['id'] for commit in payload['commits'] ] try: self.env.log.debug('Adding changesets: %s' % revision_ids) manager.notify('changeset_added', repository_name, revision_ids) except Exception as exception: self.env.log.error(exception) request.send_response(204) request.send_header('Content-Length', 0) request.write('') raise RequestDone
def expand_macro(self, formatter, name, content, args=None): # pylint: disable=too-many-function-args args = args or {} reponame = args.get('repository') or '' rev = args.get('revision') # pylint: disable=no-member repos = RepositoryManager(self.env).get_repository(reponame) try: changeset = repos.get_changeset(rev) message = changeset.message rev = changeset.rev resource = repos.resource except Exception: # pylint: disable=broad-except message = content resource = Resource('repository', reponame) if ChangesetModule(self.env).wiki_format_messages: return tag.div(format_to_html(self.env, formatter.context.child( 'changeset', rev, parent=resource), message, escape_newlines=True), class_='message') else: return tag.pre(message, class_='message')
def _do_changeset_modified(self, reponame, first_rev, *revs): if is_default(reponame): reponame = '' rm = RepositoryManager(self.env) errors = rm.notify('changeset_modified', reponame, (first_rev,) + revs) for error in errors: printerr(error) return 2 if errors else 0
def __init__(self): # Retrieve info for all repositories associated with this project self.authz_file = self.config.get('trac', 'authz_file') rm = RepositoryManager(self.env) all_repos = rm.get_all_repositories() for (reponame, info) in all_repos.iteritems(): self.project_repos.append(reponame) self.env.log.debug("SvnAuthzAdminPlugin: project_repos: '%s'" % self.project_repos)
def render_admin_panel(self, req, cat, page, path_info): req.perm.require('SVNVERIFY_REPORT') rm = RepositoryManager(self.env) all_repos = rm.get_all_repositories() db = self.env.get_read_db() cursor = db.cursor() if path_info: # detailed reponame = not is_default(path_info) and path_info or '' info = all_repos.get(reponame) if info is None: raise TracError(_("Repository '%(repo)s' not found", repo=path_info)) cursor.execute("SELECT type, time, result, log " "FROM svnverify_log WHERE repository_id = %s " "ORDER BY time DESC LIMIT 1", (info['id'],)) row = cursor.fetchone() if row: info['check_type'] = row[0] info['time_checked'] = format_datetime(from_utimestamp(row[1])) info['pretty_status'] = int(row[2]) == 0 and "OK" or "Warning" info['status'] = row[2] info['log'] = row[3] info['prettydir'] = breakable_path(info['dir']) if info['name'] == '': info['name'] = "(default)" return 'svnverify.html', {"info": info} else: repositories = {} for reponame, info in all_repos.iteritems(): if info.get('type',rm.repository_type) == "svn" or (rm.repository_type == 'svn' and info.get('type') == ''): info['prettydir'] = breakable_path(info['dir']) try: r = RepositoryManager(self.env).get_repository(reponame) info['rev'] = r.get_youngest_rev() info['display_rev'] = r.display_rev(info['rev']) except: pass cursor.execute("SELECT type, time, result " "FROM svnverify_log " "WHERE repository_id = %s " "ORDER BY time DESC LIMIT 1", (info['id'],)) row = cursor.fetchone() if row: info['check_type'] = row[0] info['time_checked'] = format_datetime(from_utimestamp(row[1])) info['pretty_status'] = int(row[2]) == 0 and "OK" or "Warning" info['status'] = row[2] repositories[reponame] = info add_stylesheet(req, 'svnverify/css/svnverify.css') return 'svnverifylist.html', {"repositories": repositories}
def _do_list(self): rm = RepositoryManager(self.env) values = [] for (reponame, info) in sorted(rm.get_all_repositories().iteritems()): alias = "" if "alias" in info: alias = info["alias"] or "(default)" values.append((reponame or "(default)", info.get("type", ""), alias, info.get("dir", ""))) print_table(values, [_("Name"), _("Type"), _("Alias"), _("Directory")])
def remove_repository(self, name): """Remove a repository.""" try: dir = os.path.join(self.parentpath, name) shutil.rmtree(dir) rm = RepositoryManager(self.env) rm.reload_repositories() except OSError, why: raise TracError(str(why))
def _do_list(self): rm = RepositoryManager(self.env) values = [] for (reponame, info) in sorted(rm.get_all_repositories().iteritems()): alias = '' if 'alias' in info: alias = info['alias'] or '(default)' values.append((reponame or '(default)', info.get('type', ''), alias, info.get('dir', ''))) print_table(values, [_('Name'), _('Type'), _('Alias'), _('Directory')])
def wiki_page_deleted(self, page): repo = RepositoryManager(self.env).repository_dir repdir = repo.split('.git')[0] os.chdir(repdir + "wiki/") subprocess.call(["git", "rm", repdir + "wiki/" + page.name + ".txt"]) subprocess.call(["git", "commit", "-m", page.name + ".txt removed."]) os.chdir(self.env.path)
def __init__(self, env, req, file): from trac.versioncontrol import RepositoryManager from trac.versioncontrol.web_ui import get_existing_node if hasattr(RepositoryManager, 'get_repository_by_path'): # Trac 0.12 repo, file = RepositoryManager(env).get_repository_by_path(file)[1:3] else: repo = RepositoryManager(env).get_repository(req.authname) obj = get_existing_node(req, repo, file, None) TransformSource.__init__(self, "browser", "source", file, obj)
def wiki_page_added(self, page): repo = RepositoryManager(self.env).repository_dir repdir = repo.split('.git')[0] subprocess.call(["trac-admin", "", "wiki export", page.name, repdir + "wiki/" + "tmp.txt"]) subprocess.call(["mv", repdir + "wiki/" + "tmp.txt", repdir + "wiki/" + page.name + ".txt"]) os.chdir(repdir + "wiki/") subprocess.call(["git", "add", repdir + "wiki/" + page.name + ".txt"]) subprocess.call(["git", "commit", "-m", page.name + ".txt added."]) os.chdir(self.env.path)
def unlink_product(self, reponame): if not isinstance(self.env, ProductEnvironment): return rm = RepositoryManager(self.env.parent) repoid = rm.get_repository_id(reponame) links = self._get_repository_links(repoid) links.remove(self.env.product.prefix) with self.env.db_direct_transaction as db: if len(links) > 0: db("""UPDATE repository SET value=%s WHERE id=%s AND name='product'""", (','.join(links), repoid)) else: db("""DELETE FROM repository WHERE id=%s AND name='product' AND value='%s'""" % (repoid, self.env.product.prefix))
def openProject(self, req, projectname, revision, extensionlist): """ Returns project's connection string and repository file list matched to search criteria. """ # Return values if str(projectname).strip() == '': e = exceptions.Exception raise e("Incorrect project name") if revision.strip() == '': revision = None if extensionlist.strip() == '': extensionlist = None # Find node for the requested path/rev repomgr = RepositoryManager(self.env) repository = repomgr.get_repository(None) projectname = conf.cleanupProjectName(projectname) parts = [] project = Project.get(env_name=projectname) if project: parts.append(self.get_scm_repository_url(project.env_name)) else: return [] try: if revision: revision = repository.normalize_rev(revision) rev_or_latest = revision or repository.youngest_rev getfiles = [] self._getfiles(req, getfiles, repository, '', rev_or_latest) if extensionlist: extensions = extensionlist.split(',') searchresult = [] for file in getfiles: extension = os.path.splitext(str(file))[1].strip('.') if extension in extensions: searchresult.append(file) addfiles = ",".join(searchresult) else: addfiles = ",".join(getfiles) if addfiles: # Append version control files parts.append('versioncontrolfiles|' + addfiles) except Exception: self.log.exception("ProjectsRPC.openProject failed") return parts
def link_product(self, reponame): if not isinstance(self.env, ProductEnvironment): return rm = RepositoryManager(self.env.parent) repoid = rm.get_repository_id(reponame) links = self._get_repository_links(repoid) with self.env.db_direct_transaction as db: if links: links.append(self.env.product.prefix) db("""UPDATE repository SET value=%s WHERE id=%s AND name='product'""", (','.join(links), repoid)) else: db("""INSERT INTO repository (id, name, value) VALUES(%s, 'product', '%s')""" % (repoid, self.env.product.prefix))
def expand_macro(self, formatter, name, content, args=None): # pylint: disable=too-many-function-args args = args or {} reponame = args.get('repository') or '' rev = args.get('revision') # pylint: disable=no-member repos = RepositoryManager(self.env).get_repository(reponame) try: changeset = repos.get_changeset(rev) message = changeset.message rev = changeset.rev resource = repos.resource except Exception: # pylint: disable=broad-except message = content resource = Resource('repository', reponame) config = self.ticket_replace_section fields = {} for key, value in config.options(): idx = key.rfind('.') if idx >= 0: prefix, attribute = key[:idx], key[idx + 1:] field = fields.setdefault(prefix, {}) field[attribute] = config.get(key) else: fields[key] = {'': value} for prefix, field in fields.iteritems(): if not all(k in field for k in ['pattern', 'replace']): self.log.warn( "Ignoring [%s] %s, missing .pattern or .replace" % (self.ticket_replace_section_name, key)) continue subst = {'repository': reponame, 'revision': rev} pattern = field['pattern'].replace('$(', '%(') % subst replace = field['replace'].replace('$(', '%(') % subst message = re.sub(pattern, replace, message) if ChangesetModule(self.env).wiki_format_messages: message = '\n'.join( map(lambda line: "> " + line, message.split('\n'))) return tag.div(format_to_html(self.env, formatter.context.child( 'changeset', rev, parent=resource), message, escape_newlines=True), class_='message') else: return tag.pre(message, class_='message')
def process_request(self, req): global page_version repos = RepositoryManager(self.env).repository_dir repdir = repos.split('.git')[0] dirList = os.listdir(repdir + 'wiki') dirList.sort() count_do = 0 count_no = 0 for sFile in dirList: if sFile.find('.txt') == -1: continue try: filename = os.path.splitext(sFile)[0] if filename not in page_version: page_version[filename] = 0 content = read_file(repdir + 'wiki/' + sFile) page = WikiPage(self.env, filename) page.text = content.decode('unicode-escape') if page_version[filename] != page.version: print (filename + ': local page version does not match online version!') print ('Local version: ' + str(page_version[filename]) + ' <-> online version: ' + str(page.version) + '. Overwrite? (y/n)') user_input = raw_input() if user_input == 'y': page.save(author='me', comment='', remote_addr='127.0.0.1') count_do = count_do + 1 print (filename + ' created/modified as wiki page from version ' + str(page_version[filename]) + ' to version ' + str(page.version)) page_version[filename] = page.version else: print 'Page not created/modified' count_no = count_no + 1 continue else: page.save(author='me', comment='', remote_addr='127.0.0.1') count_do = count_do + 1 print (filename + ' created/modified as wiki page from version ' + str(page_version[filename]) + ' to version ' + str(page.version)) page_version[filename] = page.version except: count_no = count_no + 1 print (filename + ' not modified or changed; remained untouched') continue cont = str(count_do) + ' wiki pages created/modified and ' + str(count_no) + ' untouched' req.send_response(200) req.send_header('Content-Type', 'text/plain') req.send_header('Content-Length', len(cont)) req.end_headers() req.write(cont)
def environment_created(self): """Index the repositories.""" for repos in RepositoryManager(self.env).get_real_repositories(): pretty_name = repos.reponame or '(default)' printout(_(" Indexing '%(name)s' repository", name=pretty_name)) try: repos.sync(self._sync_feedback) except TracError: printerr( _(""" --------------------------------------------------------------------- Warning: couldn't index '%(pretty_name)s' repository. This can happen for a variety of reasons: wrong repository type, no appropriate third party library for this repository type, no repository at the specified repository path... You can nevertheless start using your Trac environment, but you'll need to check your `%(name)s.type` and `%(name)s.dir` option values in the [repositories] section of your trac.ini file. """, pretty_name=pretty_name, name=repos.reponame or '')) else: # Erase to end of line. sys.stdout.write('\033[K') sys.stdout.flush()
def _extend_info(self, reponame, info, editable): """Extend repository info for rendering.""" info['name'] = reponame if info.get('dir') is not None: info['prettydir'] = breakable_path(info['dir']) or '' info['hidden'] = as_bool(info.get('hidden')) info['editable'] = editable if not info.get('alias'): try: repos = RepositoryManager(self.env).get_repository(reponame) youngest_rev = repos.get_youngest_rev() info['rev'] = youngest_rev info['display_rev'] = repos.display_rev(youngest_rev) except Exception: pass return info
def _extend_info(self, reponame, info, editable): """Extend repository info for rendering.""" info["name"] = reponame if info.get("dir") is not None: info["prettydir"] = breakable_path(info["dir"]) or "" info["hidden"] = as_bool(info.get("hidden")) info["editable"] = editable if not info.get("alias"): try: repos = RepositoryManager(self.env).get_repository(reponame) youngest_rev = repos.get_youngest_rev() info["rev"] = youngest_rev info["display_rev"] = repos.display_rev(youngest_rev) except Exception: pass return info
def processCommitHook(self, req): self.env.log.debug("processCommitHook") status = self.closestatus if not status: status = 'closed' if self.autofetch: repodir = RepositoryManager(self.env).repository_dir if not os.path.isabs(repodir): repodir = os.path.join(self.env.path, repodir) # TODO: This was the previous code, the repo options is probably unecessary now. # repodir = "%s/%s" % (self.repo, reponame) self.env.log.debug("Autofetching: %s" % repodir) repo = Git(repodir) try: self.env.log.debug("Fetching repo %s" % self.repo) repo.execute(['git', 'fetch']) try: self.env.log.debug("Resyncing local repo") self.env.get_repository('').sync() except: self.env.log.error("git sync failed!") except: self.env.log.error("git fetch failed!") data = req.args.get('payload') if data: jsondata = simplejson.loads(data) reponame = jsondata['repository']['name'] for i in jsondata['commits']: self.hook.process(i, status, self.enable_revmap,reponame)
def source(self, req, args): arg = re.compile(":|@").split(args) if len(arg) < 2: raise TracError('[[Usage: BibAdd(source:file[@rev])') elif len(arg) == 2: revision = None else: revision = arg[2] file = arg[1] if version < 0.12: repos = self.env.get_repository() path = file else: (reponame, repos, path) = RepositoryManager(self.env).get_repository_by_path(file) # load the file from the repository bib = repos.get_node(path, revision) file = bib.get_content() text = file.read() return _extract(text)
def get_repository(self, authname=None): """Return the version control repository configured for this environment. @param authname: user name for authorization """ return RepositoryManager(self).get_repository(authname)
def _update_tickets(self, req, review): """Updates the tickets referenced by the given review's changeset with a comment of field changes. Field changes and command execution may occur if specified in trac.ini and the review's changeset is the last one of the ticket.""" status = review.encode(review.status).lower() summary = review.summaries[-1] # build comment if summary['status']: comment = "Code review set to %(status)s" % summary else: comment = "Code review comment" summary['_ref'] = review.changeset if review.repo: summary['_ref'] += '/' + review.repo comment += " for [%(_ref)s]:\n\n%(summary)s" % summary # find and update tickets # TODO: handle when there's no explicitly named repo repo = RepositoryManager(self.env).get_repository(review.repo) changeset = repo.get_changeset(review.changeset) ticket_re = CommitTicketUpdater.ticket_re tickets = ticket_re.findall(changeset.message) invoked = False for ticket in tickets: tkt = Ticket(self.env, ticket) # determine ticket changes changes = {} if self._is_complete(ticket, tkt, review, failed_ok=True): changes = self._get_ticket_changes(tkt, status) # update ticket if there's a review summary or ticket changes if summary['summary'] or changes: for field, value in changes.items(): tkt[field] = value tkt.save_changes(author=summary['reviewer'], comment=comment) # check to invoke command if not invoked and self._is_complete(ticket, tkt, review): self._execute_command(status) invoked = True return tickets
def shutdown(self, tid=None): """Close the environment.""" RepositoryManager(self).shutdown(tid) DatabaseManager(self).shutdown(tid) if tid is None: self.log.removeHandler(self._log_handler) self._log_handler.flush() self._log_handler.close() del self._log_handler
def add_repository(self, name): """Add a repository.""" dir = os.path.join(self.parentpath, name) if not os.path.isabs(dir): raise TracError(_("The repository directory must be absolute")) trunk = os.path.join(dir, 'trunk') branches = os.path.join(dir, 'branches') tags = os.path.join(dir, 'tags') command = '"%(svnadmin)s" create "%(dir)s"; "%(svn)s" mkdir --parents -q -m "Created Folders" "file://%(trunk)s" "file://%(branches)s" "file://%(tags)s"' % { 'svnadmin': self.admin, 'dir': dir, 'svn': self.client, 'trunk': trunk, 'branches': branches, 'tags': tags } process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (result, error) = process.communicate() if error is not None and error != "": if error.find('E165002') > -1: raise TracError( _('The repository "%(name)s" already exists.', name=name)) elif error.find('E000002') > -1 or error.find('E000013') > -1: raise TracError( _( "Can't create the repository '%(name)s.' " "Make sure the parent directory '%(parentpath)s' exists " "and the web server has write permissions for it.", name=name, parentpath=self.parentpath)) else: raise TracError(error) if self.hookspath and os.path.exists(self.hookspath): hooksdir = os.path.join(dir, 'hooks/') files = os.listdir(self.hookspath) files = [self.hookspath + '/' + filename for filename in files] for file in files: shutil.copy2(file, hooksdir) rm = RepositoryManager(self.env) rm.reload_repositories()
def _process_repository(self, name, kind, absurl): rm = RepositoryManager(self.env) repo, remote = self._find_repository(rm, name, kind, absurl) if repo is None: self.env.log.warn('BitbucketSync: Cannot find a %s repository named "%s"' ' and origin "%s"' % (kind, name, absurl)) elif kind == 'hg': self._process_hg_repository(rm, repo, remote) else: #elif kind == 'git': self._process_git_repository(rm, repo, remote)
def shutdown(self, tid=None): """Close the environment.""" RepositoryManager(self).shutdown(tid) # FIXME: Shared DB so IMO this should not happen ... at least not here #DatabaseManager(self).shutdown(tid) if tid is None: self.log.removeHandler(self._log_handler) self._log_handler.flush() self._log_handler.close() del self._log_handler
def render_admin_panel(self, req, category, page, path_info): if not isinstance(self.env, ProductEnvironment): return super(ProductRepositoryAdminPanel, self).render_admin_panel(req, category, page, path_info) req.perm.require('VERSIONCONTROL_ADMIN') db_provider = self.env[DbRepositoryProvider] if req.method == 'POST' and db_provider: if req.args.get('remove'): repolist = req.args.get('sel') if repolist: if isinstance(repolist, basestring): repolist = [ repolist, ] for reponame in repolist: db_provider.unlink_product(reponame) elif req.args.get('addlink') is not None and db_provider: reponame = req.args.get('repository') db_provider.link_product(reponame) req.redirect(req.href.admin(category, page)) # Retrieve info for all product repositories rm_product = RepositoryManager(self.env) rm_product.reload_repositories() all_product_repos = rm_product.get_all_repositories() repositories = dict( (reponame, self._extend_info(reponame, info.copy(), True)) for (reponame, info) in all_product_repos.iteritems()) types = sorted([''] + rm_product.get_supported_types()) # construct a list of all repositores not linked to this product rm = RepositoryManager(self.env.parent) all_repos = rm.get_all_repositories() unlinked_repositories = dict([ (k, all_repos[k]) for k in sorted(set(all_repos) - set(all_product_repos)) ]) data = { 'types': types, 'default_type': rm_product.repository_type, 'repositories': repositories, 'unlinked_repositories': unlinked_repositories } return 'repository_links.html', data