Showing only posts with topic "ditz" [.rss for this topic]. See all posts.

Google textfile auto-titleing

If you search for “ditz readme” on the Googles, the correct result, which is a text file and not an HTML page, appears with the title “DitzãŪREADME”. This is probably because there’s a link to it titled as such in this Japanese description of a Ditz emacs mode. Apparently Google prefers that title over the link just called “README” on the the Ditz main page.

Ditz 0.4, and the magic of Ruby DSLs

I’ve just released Ditz 0.4. The big-ticket item in this release is the plugin system, which makes it very easy to tweak Ditz’s models, views and controllers. There’s an included git plugin which does some nice things like linking git commits and git branches to individual Ditz issues.

The new bash completion is pretty nice too. The completion code has been reworked a bit and now ties in very nicely with the argument processing. Check out this code from the Ditz’s controller (operator.rb, for those following along from your repo):

operation :start, "Start work on an issue", :unstarted_issue
def start project, config, issue
  ## ...
end

Just by calling the operation method, we get:

  • Argument checking. There must be one argument to ‘ditz start’, and it must be an unstarted issue. Any violations are handled nicely for us without having to invoke the method.
  • Help messages in ‘ditz help’ and ‘ditz help start’.
  • Argument completion. Running ’ditz start ’ outputs a list of possible completions for a command (in this case, all unstarted issues) and then exits. Shell completion scripts can parse this output and present it to you when you hit tab.

So that’s a little DSL that I think turned out well.

Writing a plugin is also nicely DSLified. Here are some examples from plugin/git.rb:

class Issue
 field :git_branch, :ask => false

 def git_commits
   ## ...
 end
end

Here we reopen the Issue class and add a field called git_branch, and we specify that the UI shouldn’t ask for this field when an issue is created, since I decided that would be too annoying. (We’ll see how we allow the user to explicitly set it below.) We also add a method that’s responsible for actually getting the commits out of git.

Since our configuration file is just a Ditz model object, we can do the same thing to add the configuration parameters we need:

class Config
  field :git_commit_url_prefix,
    :prompt =>"URL prefix (if any) to link git commits to"
  field :git_branch_url_prefix,
    :prompt => "URL prefix (if any) to link git branches to"
end

We’ll use those two fields to add some links when we generate HTML.

Adding commands to Ditz’s controller is just as easy. Just reopen the class:

class Operator
 operation :set_branch, "Set the git feature branch of an issue",
           :issue, :maybe_string
 def set_branch project, config, issue, maybe_string
   ## ...
 end
end

So now we have a set-branch command that takes an issue name, and an optional branch name. And it’s a first-class citizen alongside every other command: shows up in the help page, has argument auto-completion, etc.

Finally, let’s see how we modify the views. One thing we’d like to see is the git branch for an issue, if it’s been set.

class ScreenView
 add_to_view :issue_summary do |issue, config|
   " Git branch: #{issue.git_branch || 'none'}\n"
 end
end

Here we’ve opened up the ScreenView class (which is used for generating the screen output, as opposed to the HTML output) and added a closure to the summary section, which prints out the value of the model field we added above. The HTML version is similar:

class HtmlView
  add_to_view :issue_summary do |issue, config|
    next unless issue.git_branch
    [{ :issue => issue,
       :url_prefix => config.git_branch_url_prefix }, <<EOS]
  Git branch:
<tr>
  <td class='attrname'>Git branch:</td>
  <td class='attrval'>
    <%= url_prefix ?
      link_to([url_prefix, issue.git_branch].join,
        issue.git_branch) :
      h(issue.git_branch) %>
  </td>
</tr>
EOS
  end
end

The HTML generation returns ERB, and a hash of variables necessary for resolving it. (In this case we could also have used string substitution, but that’s not always the case—you might want to make use of variables that are only available at generation time.) Note that it also makes use of some of the convenient helper functions (like link_to and h), which I’ve helpfully defined for you in html.rb.

So that’s how to modify ditz’s models, views and controllers in one easy go. You can add fields and helper methods to model objects (including the configuration object), you can add commands to the controller, and you can add view elements to the screen and HTML output.

For reference, the complete source code to the git plugin is here.

ditz git integration plugin, in git

I’ve fleshed out ditz plugin architecture and just added a plugin that ties it more closely to git. With this plugin enabled, you can tie issues to feature branches and automatically get a list of commits on that branch (until they’re merged into master, at which point that becomes impossible, thanks to the magic of git).

Here’s an example: Sup’s configurable colors issue.

With these changes, Ditz is now firmly in the MVC camp. The models are created from yaml objects on disk; the views are an HTML renderer (using ERB) and a screen renderer (using puts technology), and the controller is the previously-mentioned operator.rb.

If you look at the plugin code you see that it need to modify all three of these components. It adds fields to the Issue and Config objects, it adds output to the HTML and screen views, and it adds commands to the controller. The fact that it can do this in a few lines of code is pretty sweet.