Archive for the 'Trac' Category

WordPress Plugin Execution Order

Sunday, December 31st, 2006

I just spent the last few hours trying to figure out what was wrong with my new WordPress plugin. My plugin requires another plugin and what was happening was WordPress was running my plugin first. This was the source of the problem and it took me awhile to figure that out. Then I had to figure out how to force WordPress to run my plugin first. I tried a code solution but there isn’t any way to tell WordPress in the code to run one plugin before the other. Then I tried modifying their order in the database but WordPress kept rewriting the row I would change. So then I thought, alphabetical ordering. I don’t want to have to rename my plugin just because of some stupid limitation of the WordPress plugin architecture. I noticed that it was running the plugins that had their own subdirectories first and then it would execute plugins that were just single files inside the plugins directory. Bingo. I removed the directory I had put my plugin from and just dumped it right in the plugins directory. Now it works beautifully. It was troubling me because I already had the plugin working on another blog (before I made the subdirectory modification) and was scratching my head why it wasn’t working here. Its all simple in retrospect.

Publish Revert Trac Plugin

Friday, November 10th, 2006

I’ve made a lot of pretty useful changes to Trac and I’m wrapping them all up in a Publish Revert Trac Plugin.

The basic functionality of Trac to manage the development process is missing a few things.

  1. It doesn’t associate subversion revisions with a ticket
  2. There is no way to easily publish just the files that are related to a ticket

These two things are exactly what my plugin addresses. It uses a post-commit hook in subversion to associate revisions with tickets. A developer just needs to reference the ticket in their commit message and the post-commit hook associates the revision number to the ticket. We use this because when we finish a ticket we want to know what to publish to our production server. This functionality already works and its really saved a lot of time being able to see all the files and the correct revision numbers we need to update when a ticket is ready to publish.

What I’m working on now is a Publish/Revert button to this plugin. It will allow us to simply press a button to publish or revert changes to your production environment. This will save even more time since you won’t have to manually do an svn update. Mistakes happen and we’ve screwed things up on production a few times because of using svn update incorrectly. With the publish and revert buttons, you will be able to save the headache of updating your production environment.

Trac SetChangeset Plugin

Thursday, May 25th, 2006

I’ve created a Trac plugin that associates tickets with their changesets. The way you’d have to do this before was to setup a subversion post-commit hook that would add a comment with the changeset number. My changes add the changeset to a database table and when you’re viewing the ticket summary you can see all the changesets for that ticket. The really cool part of the plugin is that when you click on an ‘All’ link it goes through all the changesets and lists all the unique files that have been modified by all the changesets for the ticket. This is extremely useful when pushing updates to production because all we need to do is see only what files we need to update by clicking on ‘All’. Trac itself doesn’t offer this type of functionality which is why people made the post-commit comment hack. Now, with my plugin you can easily associate changesets with a ticket and easily see the set of changesets. My plugin isn’t actually complete because I hacked together some things before I realized making a plugin was the way to go. It works for me now so I don’t have much motivation to wrap it up for everyone else. If anyone is interested in this please just email me and I’ll try to complete the plugin and post a link to it on my site.

Trac Design Spec Modification

Friday, September 30th, 2005

It took me about 3 hours to dig into the Trac code and learn enough Python to hack together a way to create a Design Spec snapshot using Trac. The problem is that we’re using the Trac wiki as our main information warehouse now. We wanted a way to be able to take a page in the wiki and create a snapshot of it to be added to a design specification. That way, at any one release we have a snapshot of the wiki pages that explain everything about it.

Since Trac already takes care of version control, it wasn’t too hard to conceptuallize that we just wanted another wiki page called DesignSpec that would just have a list of links to specific versions of different wiki pages. The design spec itself would then be version controlled as normal and we can just associate software release 0.0.1 with DesignSpec version 45. So, really all we needed was a quick way to add a link to the design spec from all the wiki pages.

I just added another button next to the Edit button that says Add to DesignSpec. The code that does the work is pretty simple:

if addToDS:
self.perm.assert_permission (perm.WIKI_MODIFY)
self.req.hdf.setValue('wiki.action', 'addToDS')
self.DS = WikiPage("DesignSpec", version, self.perm, self.db)
self.DS.set_content(self.DS.text + " * [http://ourIP" + self.env.href.wiki(self.page.name, self.page.version) + " " + self.page.name + "]\n")
self.DS.commit(author, comment, self.req.remote_addr)
self.req.redirect(self.env.href.wiki("DesignSpec"))

I’m just glad we don’t have lines of code watchers out there that for some reason or another equate productivity with how many lines of code you write. It would be hard to justify 7 lines of code taking 3 hours to write.

Python Collapsible Title Index

Tuesday, September 27th, 2005

Here is my Trac modification to have collapsible title indexing. I used this http://www.vladdy.net/Demos/Tree.html as the base. The following is my new execute method in TitleIndex.py:

[source language=":python"]
def execute(hdf, args, env):
db = env.get_db_cnx()
cursor = db.cursor()

prefix = None
if args:
prefix = args.replace(‘\”, ‘\’\”)

sql = ‘SELECT DISTINCT name FROM wiki ‘
if prefix:
sql += ‘WHERE name LIKE \’%s%%\’ ‘ % prefix
sql += ‘ORDER BY name’
cursor.execute(sql)

buf = StringIO()

# find common prefixes
lastPrefix = ”
prefixArray = []
while 1:
row = cursor.fetchone()
if row == None:
break
if lastPrefix == ”:
lastPrefix = row[0]
else:
newPrefix = findcommonstart([lastPrefix, row[0]])
if len(newPrefix) >= 4:
lastPrefix = newPrefix
else:
prefixArray += [lastPrefix]
lastPrefix = row[0]

cursor.execute(sql) # this should be copied instead of doing another DB query
# print out indecies
buf.write(‘<ul id="root">’)
currentPrefix = 0
row = cursor.fetchone()
if row == None:
return buf.getValue()

while currentPrefix < len(prefixArray):
buf.write(‘<li><div>%s</div>’ % prefixArray[currentPrefix])
buf.write(‘</ul><ul>’)
prefix = findcommonstart([prefixArray[currentPrefix],row[0]])
while len(prefix) >= 4:
buf.write(‘<li>&lt;a href="%s">’ % env.href.wiki(row[0]))
buf.write(row[0])
buf.write(‘</li>\n’)
row = cursor.fetchone()
if row == None:
break
prefix = findcommonstart([prefixArray[currentPrefix],row[0]])
buf.write(‘</ul>’)
currentPrefix = currentPrefix + 1
buf.write(”)

return buf.getvalue()
[/source]