<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Technosorcery Networks - Home</title>
  <id>tag:technosorcery.net,2010:mephisto/</id>
  <generator version="0.8.0" uri="http://mephistoblog.com">Mephisto Drax</generator>
  <link href="http://technosorcery.net/feed" rel="self" type="application/atom+xml"/>
  <link href="http://technosorcery.net/" rel="alternate" type="text/html"/>
  <updated>2010-02-22T01:57:10Z</updated>
  <entry xml:base="http://technosorcery.net/">
    <author>
      <name>jhelwig</name>
    </author>
    <id>tag:technosorcery.net,2010-02-08:66</id>
    <published>2010-02-08T01:50:00Z</published>
    <updated>2010-02-22T01:57:10Z</updated>
    <category term="Development"/>
    <category term="Git"/>
    <category term="development"/>
    <category term="git"/>
    <link href="http://technosorcery.net/2010/2/8/fun-with-the-upcoming-1-7-release-of-git" rel="alternate" type="text/html"/>
    <title>Fun with the upcoming 1.7 release of Git: rebase --interactive --autosquash</title>
<content type="html">
            &lt;p&gt;The upcoming Git 1.7 has a &lt;em&gt;lot&lt;/em&gt; of really nice improvements, and new
features.  One of the big new features is the &lt;code&gt;--autosquash&lt;/code&gt; argument
for &lt;code&gt;git rebase --interactive&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;If you&#8217;re anything like me, then you commit a &lt;em&gt;lot&lt;/em&gt;, while you&#8217;re
working on something, and use &lt;code&gt;git rebase --interactive&lt;/code&gt; judiciously to
clean up all these incremental commits into a presentable format.  If
you&#8217;re a bit more like me, then you&#8217;ll often end up doing multiple
&lt;code&gt;git rebase --interactive&lt;/code&gt; passes to split commits apart, and squash them
back into other commits.&lt;/p&gt;


	&lt;p&gt;Git just gained the ability to make this a little faster.  If you know
what commit you want to squash something in to you can commit it with a
message of &#8220;squash! $other_commit_subject&#8221;.  Then if you run
&lt;code&gt;git rebase --interactive --autosquash commitish&lt;/code&gt;, the line will automatically
be set as &lt;code&gt;squash&lt;/code&gt;, and placed below the commit with the subject of
&lt;code&gt;$other_commit_subject&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;For example:&lt;/p&gt;




  &lt;div class=&quot;code shell-unix-generic&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;$ vim Foo.txt
$ git commit -am &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;Change all the 'Bar's to 'Foo's&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
[topic 8374d8e] Change all the &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;Bar&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;s to &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;Foo&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;s
 1 files changed, 2 insertions(+), 2 deletions(-)
$ vim Bar.txt
$ git commit -am &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;Change all the 'Foo's to 'Bar's&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
[topic 2d12ce8] Change all the &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;Foo&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;s to &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;Bar&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;s
 1 files changed, 1 insertions(+), 1 deletions(-)
$ vim Foo.txt
$ git commit -am &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;squash! Change all the 'Bar's&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
[topic 259a7e6] squash&lt;span class=&quot;Keyword&quot;&gt;!&lt;/span&gt; Change all the &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;Bar&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;s
 1 files changed, 2 insertions(+), 1 deletions(-)
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;


	&lt;p&gt;If we run &lt;code&gt;git rebase --interactive --autosquash origin/master&lt;/code&gt; from
here, the pick-list will look like this:&lt;/p&gt;




  &lt;div class=&quot;code plain_text&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;pick 8374d8e Change all the 'Bar's to 'Foo's
squash 259a7e6 squash! Change all the 'Bar's
pick 2d12ce8 Change all the 'Foo's to 'Bar's

# Rebase b6bee12..259a7e6 onto b6bee12
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like &amp;quot;squash&amp;quot;, but discard this commit's log message
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;


	&lt;p&gt;When you get to the &lt;code&gt;squash&lt;/code&gt;, you&#8217;ll have a commit message like:&lt;/p&gt;




  &lt;div class=&quot;code plain_text&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;# This is a combination of 2 commits.
# The first commit's message is:

Change all the 'Bar's to 'Foo's

# This is the 2nd commit message:

squash! Change all the 'Bar's

# Please enter the commit message for your ch anges. Lines starting
# with '#' will be ignored, and an empty mess age aborts the commit.
# Not currently on any branch.
# Changes to be committed:
#    modified:   Foo.txt
#
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;


	&lt;p&gt;If you were paying attention earlier to the pick-list, you&#8217;ll notice that
there&#8217;s also a &lt;code&gt;fixup&lt;/code&gt; command available.  If we had specified &lt;code&gt;fixup!&lt;/code&gt;,
instead of &lt;code&gt;squash!&lt;/code&gt; as the commit message&#8217;s prefix, then the pick list would
have ended up as:&lt;/p&gt;




  &lt;div class=&quot;code plain_text&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;pick 8374d8e Change all the 'Bar's to 'Foo's
fixup cfc6e54 fixup! Change all the 'Bar's
pick 2d12ce8 Change all the 'Foo's to 'Bar's

# Rebase b6bee12..cfc6e54 onto b6bee12
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like &amp;quot;squash&amp;quot;, but discard this commit's log message
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;


	&lt;p&gt;With the following in your editor for the combined commit message:&lt;/p&gt;




  &lt;div class=&quot;code plain_text&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;# This is a combination of 2 commits.
# The first commit's message is:

Change all the 'Bar's to 'Foo's

# The 2nd commit message will be skipped:

#    fixup! Change all the 'Bar's

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# Not currently on any branch.
# Changes to be committed:
#    modified:   README.markdown
#
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;

Notice that the &lt;code&gt;fixup!&lt;/code&gt; commit&#8217;s message is already commented out.  You can just save out the message as-is, and your original commit message will be kept.  Very handy for including changes when you realize that you forgot to add part of an earlier commit.

	&lt;p&gt;Here&#8217;s a few aliases I have setup to make all this easier:&lt;/p&gt;




  &lt;div class=&quot;code ini&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;&lt;span class=&quot;EntityNameSection&quot;&gt;&lt;span class=&quot;EntityNameSection&quot;&gt;[&lt;/span&gt;alias&lt;span class=&quot;EntityNameSection&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;Keyword&quot;&gt;fixup&lt;/span&gt; = !sh -c &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;git commit -m &lt;span class=&quot;Constant&quot;&gt;\&amp;quot;&lt;/span&gt;fixup! $(git log -1 --format=&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;\\&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;%s&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;Constant&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt; $@)&lt;span class=&quot;Constant&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt; -
    &lt;span class=&quot;Keyword&quot;&gt;squash&lt;/span&gt; = !sh -c &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;git commit -m &lt;span class=&quot;Constant&quot;&gt;\&amp;quot;&lt;/span&gt;squash! $(git log -1 --format=&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;\\&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;%s&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;Constant&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt; $@)&lt;span class=&quot;Constant&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt; -
    &lt;span class=&quot;Keyword&quot;&gt;ri&lt;/span&gt; = rebase --interactive --autosquash
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;


	&lt;p&gt;Here&#8217;s how they would be used in our previous example:&lt;/p&gt;




  &lt;div class=&quot;code shell-unix-generic&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;$ vim Foo.txt
$ git commit -am &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;Change all the 'Bar's to 'Foo's&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
[topic 8374d8e] Change all the &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;Bar&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;s to &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;Foo&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;s
 1 files changed, 2 insertions(+), 2 deletions(-)
$ vim Bar.txt
$ git commit -am &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;Change all the 'Foo's to 'Bar's&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
[topic 2d12ce8] Change all the &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;Foo&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;s to &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;Bar&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;s
 1 files changed, 1 insertions(+), 1 deletions(-)
$ vim Foo.txt
$ git add Foo.txt
$ git squash HEAD~2
[topic 259a7e6] squash&lt;span class=&quot;Keyword&quot;&gt;!&lt;/span&gt; Change all the &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;Bar&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;s to &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;Foo&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;s
 1 files changed, 2 insertions(+), 1 deletions(-)
$ git ri origin/master
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;


	&lt;p&gt;Similarly, &lt;code&gt;git fixup HEAD~2&lt;/code&gt; would create a &lt;code&gt;fixup!&lt;/code&gt; commit to be used with &lt;code&gt;git rebase --interactive --autosquash&lt;/code&gt; (Aliased as: &lt;code&gt;git ri&lt;/code&gt;).&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Edit 2010-02-13:&lt;/strong&gt; Fix alias examples.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://technosorcery.net/">
    <author>
      <name>jhelwig</name>
    </author>
    <id>tag:technosorcery.net,2009-10-07:14</id>
    <published>2009-10-07T06:03:00Z</published>
    <updated>2009-10-07T06:04:34Z</updated>
    <category term="Development"/>
    <category term="capistrano"/>
    <category term="completion"/>
    <category term="shell"/>
    <category term="zsh"/>
    <link href="http://technosorcery.net/2009/10/7/capistrano-completion-in-zsh" rel="alternate" type="text/html"/>
    <title>Capistrano completion in zsh</title>
<summary type="html">&lt;p&gt;I&#8217;ve decided to try out zsh for a while, and while I already get completions for most everything I want, out of the box, I am missing completions for Capistrano tasks.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;I&#8217;ve decided to try out zsh for a while, and while I already get completions for most everything I want, out of the box, I am missing completions for Capistrano tasks.&lt;/p&gt;
&lt;p&gt;I&#8217;ve decided to try out zsh for a while, and while I already get completions for most everything I want, out of the box, I am missing completions for Capistrano tasks.&lt;/p&gt;


	&lt;p&gt;I had been using &lt;a href=&quot;http://www.brynary.com/2007/5/3/tab-completion-for-capistrano-tasks-in-bash&quot;&gt;brynary&#8217;s Bash Capistrano completion script&lt;/a&gt;.  I was able to find &lt;a href=&quot;http://www.mail-archive.com/capistrano@googlegroups.com/msg00994.html&quot;&gt;a mailing list post&lt;/a&gt; about setting up Capistrano task completions for zsh, but it didn&#8217;t quite work for me. (&lt;code&gt;show_tasks&lt;/code&gt; isn&#8217;t a valid task.)  I also didn&#8217;t like throwing the &lt;code&gt;.cap_tasks&lt;/code&gt; file in the top-level of the project.  I already had a &lt;code&gt;~/.zsh_cache/&lt;/code&gt; directory for caching zsh&#8217;s completions, so I decided to modify the script I found to put the cache file there, instead.&lt;/p&gt;




  &lt;div class=&quot;code shell-unix-generic&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;&lt;span class=&quot;Entity&quot;&gt;_cap_does_task_list_need_generating&lt;/span&gt; () {
  &lt;span class=&quot;Keyword&quot;&gt;if&lt;/span&gt; [ &lt;span class=&quot;Keyword&quot;&gt;!&lt;/span&gt; -f cap_tasks ]&lt;span class=&quot;Keyword&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;then&lt;/span&gt; return 0&lt;span class=&quot;Keyword&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;else&lt;/span&gt;
    accurate=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;$(&lt;/span&gt;stat -f%m &lt;span class=&quot;Keyword&quot;&gt;~&lt;/span&gt;/.zsh_cache/cap_tasks-&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;$(&lt;/span&gt;echo &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;PWD&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;|&lt;/span&gt; sha512sum&lt;span class=&quot;String&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
    changed=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;$(&lt;/span&gt;stat -f%m config/deploy.rb&lt;span class=&quot;String&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
    return &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;$(&lt;/span&gt;expr &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;accurate&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&amp;gt;=&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;changed&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;fi&lt;/span&gt;
}

&lt;span class=&quot;Entity&quot;&gt;_cap&lt;/span&gt; () {
  &lt;span class=&quot;Keyword&quot;&gt;if&lt;/span&gt; [ -f config/deploy.rb ]&lt;span class=&quot;Keyword&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;then&lt;/span&gt;
    &lt;span class=&quot;Keyword&quot;&gt;if&lt;/span&gt; _cap_does_task_list_need_generating&lt;span class=&quot;Keyword&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;then&lt;/span&gt;
      cap -T &lt;span class=&quot;Keyword&quot;&gt;|&lt;/span&gt; grep &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;^cap&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;|&lt;/span&gt; cut -d&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt; -f2 &lt;span class=&quot;Keyword&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;~&lt;/span&gt;/.zsh_cache/cap_tasks-&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;$(&lt;/span&gt;echo &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;PWD&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;|&lt;/span&gt; sha512sum&lt;span class=&quot;String&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;Keyword&quot;&gt;fi&lt;/span&gt;
    compadd &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;cat ~/.zsh_cache/cap_tasks-$(echo $PWD | sha512sum)&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;Keyword&quot;&gt;fi&lt;/span&gt;
}

compdef _cap cap
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;


I have the above in &lt;code&gt;~/.zsh.d/S50_capistrano&lt;/code&gt;, which automatically gets loaded on startup.


  &lt;div class=&quot;code shell-unix-generic&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;&lt;span class=&quot;Keyword&quot;&gt;for&lt;/span&gt; zshrc_snipplet &lt;span class=&quot;Keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;~&lt;/span&gt;/.zsh.d/S[0-9][0-9]*[^~] &lt;span class=&quot;Keyword&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do&lt;/span&gt;
    source &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;zshrc_snipplet&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;done&lt;/span&gt;
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;
          </content>  </entry>
  <entry xml:base="http://technosorcery.net/">
    <author>
      <name>jhelwig</name>
    </author>
    <id>tag:technosorcery.net,2009-10-04:10</id>
    <published>2009-10-04T17:33:00Z</published>
    <updated>2009-10-04T17:53:39Z</updated>
    <category term="Development"/>
    <category term="gems"/>
    <category term="git"/>
    <category term="jeweler"/>
    <category term="oniguruma"/>
    <category term="ruby"/>
    <link href="http://technosorcery.net/2009/10/4/fixing-the-oniguruma-gem" rel="alternate" type="text/html"/>
    <title>Fixing the Oniguruma Gem for use on DreamHost</title>
<content type="html">
            &lt;p&gt;While looking at how to get syntax highlighted source back up on here
after switching to Mephisto, I kept running across references to the
Ultraviolet gem.  Some of the dependencies are a little old,(Oniguruma
&lt;a href=&quot;http://oniguruma.rubyforge.org/&quot; title=&quot;RubyForge Project&quot;&gt;Gem&lt;/a&gt;,
&lt;a href=&quot;http://www.geocities.jp/kosako3/oniguruma/&quot;&gt;Library&lt;/a&gt;), but the output
looks very nice, from the examples I&#8217;d seen.&lt;/p&gt;


	&lt;p&gt;The problem comes in, that the Oniguruma gem won&#8217;t install without you
already having the Oniguruma library installed (in a standard system
location).  This is a pretty well documented problem, with a &lt;a href=&quot;http://rubyforge.org/tracker/index.php?func=detail&amp;amp;aid=16169&amp;amp;group_id=3289&amp;amp;atid=12696&quot; title=&quot;extconf.rb
patch&quot;&gt;simple
fix&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Unfortunately, I wasn&#8217;t even able to get the gem to build at all with
the original &lt;code&gt;Rakefile&lt;/code&gt; that comes with it, and gave up very quickly on
trying to fix it.  Fortunately, there is a wonderful gem out there
called &lt;a href=&quot;http://github.com/technicalpickles/jeweler&quot; title=&quot;Jeweler GitHub
project&quot;&gt;Jeweler&lt;/a&gt;.  This allowed me
to trivially setup a working build environment, drop in the original gem
code, and get something up and running.&lt;/p&gt;


	&lt;p&gt;After adding &lt;code&gt;dir_config&lt;/code&gt; to the extconf.rb, you can happily install the
Oniguruma gem (provided your &lt;code&gt;LD_LIBRARY_PATH&lt;/code&gt; includes wherever you
installed the library).  This gets to be a problem, when using Passenger
on a shared host (such as DreamHost), like I&#8217;m trying to do.
Fortunately, there&#8217;s a way to fix this (at least on Linux).  When
linking in the libraries, you can tell &lt;code&gt;ld&lt;/code&gt; to include path information
on where to look for them.  This is very handy.&lt;/p&gt;


	&lt;p&gt;Here&#8217;s the &lt;code&gt;extconf.rb&lt;/code&gt; that I ended up going with:&lt;/p&gt;




  &lt;div class=&quot;code ruby&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;&lt;span class=&quot;Keyword&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;mkmf&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
onig_dirs &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;dir_config&lt;/span&gt;(&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;onig&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;)
onig_libs &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; onig_dirs.&lt;span class=&quot;Entity&quot;&gt;pop&lt;/span&gt;
ldshared &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;CONFIG&lt;/span&gt;[&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;LDSHARED&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;]
&lt;span class=&quot;Keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;!&lt;/span&gt;onig_libs.&lt;span class=&quot;Entity&quot;&gt;nil?&lt;/span&gt;
    onig_libs.&lt;span class=&quot;Entity&quot;&gt;split&lt;/span&gt;(&lt;span class=&quot;Support&quot;&gt;File&lt;/span&gt;::&lt;span class=&quot;Entity&quot;&gt;PATH_SEPARATOR&lt;/span&gt;).&lt;span class=&quot;Entity&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do &lt;/span&gt;|&lt;span class=&quot;Variable&quot;&gt;p&lt;/span&gt;|
        ldshared &lt;span class=&quot;Keyword&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt; -Wl,-rpath,&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;#{&lt;/span&gt;p&lt;span class=&quot;String&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;Variable&quot;&gt;CONFIG&lt;/span&gt;[&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;LDSHARED&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;] &lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt; ldshared
&lt;span class=&quot;Entity&quot;&gt;have_library&lt;/span&gt;(&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;onig&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)
&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;CFLAGS&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;-Wall&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;Entity&quot;&gt;create_makefile&lt;/span&gt;( &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;oregexp&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; )
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;


	&lt;p&gt;With this, I was able to build the gem, install it locally, and still
have it work with passenger.  I can&#8217;t guarantee it&#8217;s the best way to do
it, but it works.&lt;/p&gt;


	&lt;p&gt;I&#8217;ve put the modified Oniguruma gem on &lt;a href=&quot;http://github.com/jhelwig/oniguruma/&quot; title=&quot;modified Oniguruma
gem&quot;&gt;GitHub&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Until GitHub gets the gem building back up and running, you&#8217;ll have to
download, and make the &lt;code&gt;.gem&lt;/code&gt; file yourself, unfortunately.&lt;/p&gt;




  &lt;div class=&quot;code shell-unix-generic&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;git clone git://github.com/jhelwig/oniguruma
cd oniguruma
rake build
gem install pkg/oniguruma-&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;$(&lt;/span&gt;rake version &lt;span class=&quot;Keyword&quot;&gt;|&lt;/span&gt; sed -e &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;/oniguruma/d&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt; -e &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;s/Current version: //&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.gem -- --with-onig-dir &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;HOME&lt;/span&gt;
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;
          </content>  </entry>
  <entry xml:base="http://technosorcery.net/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:technosorcery.net,2009-09-30:6</id>
    <published>2009-09-30T21:37:00Z</published>
    <updated>2009-10-04T16:29:03Z</updated>
    <category term="Development"/>
    <category term="authorization"/>
    <category term="ruby"/>
    <category term="ruby on rails"/>
    <link href="http://technosorcery.net/2009/9/30/unhappy-with-the-standard-rails-authorization-plugins" rel="alternate" type="text/html"/>
    <title>Unhappy with the standard Rails Authorization plugins</title>
<content type="html">
            Recently, I've decided to start learning Ruby on Rails (2.3.4).  Things have been going along more-or-less smoothly (I'm still not sure whether or not I hate ActiveRecord, or can tolerate it, but that's a post for another time.).  That is, until I started looking into the various plugins/frameworks for doing Authorization in Rails.

After searching around for a bit, the two main contenders I found were &lt;a href=&quot;http://github.com/DocSavage/rails-authorization-plugin&quot;&gt;rails-authorization-plugin&lt;/a&gt;, and &lt;a href=&quot;http://github.com/be9/acl9&quot;&gt;acl9&lt;/a&gt;. acl9 seemed to be, by far, the more commonly recommended of the two.

I wasn't really impressed with the Apache style allow/deny used by acl9.  Just wasn't what I was looking for with my project, so I started looking at rails-authorization-plugin.  This is where I ran into trouble.

rails-authorization-plugin allows you to assign roles for objects, and have an optional scope.
For example:


  &lt;div class=&quot;code ruby&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4
5
6&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; Assign user the &amp;quot;global&amp;quot; role 'administrator'&lt;/span&gt;
user.&lt;span class=&quot;Entity&quot;&gt;has_role&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;administrator&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; Assign user the role &amp;quot;moderator&amp;quot; for the class Group&lt;/span&gt;
user.&lt;span class=&quot;Entity&quot;&gt;has_role&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;moderator&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;Variable&quot;&gt;Group&lt;/span&gt;
&lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; Assigns user the role &amp;quot;member&amp;quot; for the instance (of class Group)&lt;/span&gt;
user.&lt;span class=&quot;Entity&quot;&gt;has_role&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;member&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, club
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;

So far, so good.

Now, let's check what roles this user has:


  &lt;div class=&quot;code ruby&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4
5
6
7
8
9
10
11&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;administrator&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;        &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; true&lt;/span&gt;
user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;administrator&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;Variable&quot;&gt;Group&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; false&lt;/span&gt;
user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;administrator&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, club  &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; false&lt;/span&gt;

user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;moderator&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;        &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; true&lt;/span&gt;
user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;moderator&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;Variable&quot;&gt;Group&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; true&lt;/span&gt;
user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;moderator&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, club  &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; false&lt;/span&gt;

user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;member&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;        &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; true&lt;/span&gt;
user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;member&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;Variable&quot;&gt;Group&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; true&lt;/span&gt;
user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;member&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, club  &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; true&lt;/span&gt;
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;

Wait?  What?  That's right: Inheritance of roles flows from instance, to class, to global.  If you have a role for any instance, you also have it globally.  This is &lt;strong&gt;completely backwards&lt;/strong&gt; from what I would have expected, and from what I wanted.

Ok, time to go back to looking at acl9.  Guess what?  It does the &lt;strong&gt;exact same thing&lt;/strong&gt;.  Given these findings, I did what any developer, with access to Git would do.  I forked the code to make it do what I want.  Thus &lt;a href=&quot;http://github.com/jhelwig/rails-authorization-plugin&quot;&gt;my fork of rails-authorization-plugin&lt;/a&gt; (and &lt;a href=&quot;http://github.com/jhelwig/rails-authorization-plugin-test&quot;&gt;it's tests&lt;/a&gt;) was born.  I decided to base my changes off of rails-authroization plugin, simply because I didn't like the Apache style allow/deny syntax of acl9.

Now, given the initial role assignments above, we get the following:


  &lt;div class=&quot;code ruby&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4
5
6
7
8
9
10
11&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;administrator&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;        &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; true&lt;/span&gt;
user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;administrator&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;Variable&quot;&gt;Group&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; true&lt;/span&gt;
user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;administrator&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, club  &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; true&lt;/span&gt;

user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;moderator&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;        &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; false&lt;/span&gt;
user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;moderator&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;Variable&quot;&gt;Group&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; true&lt;/span&gt;
user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;moderator&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, club  &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; true&lt;/span&gt;

user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;member&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;        &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; false&lt;/span&gt;
user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;member&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;Variable&quot;&gt;Group&lt;/span&gt; &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; false&lt;/span&gt;
user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;member&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;, club  &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; true&lt;/span&gt;
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;

Inheritance is handled as follows: Global -&gt; Class -&gt; Instance.  If a role is assigned at a &quot;higher&quot; level (further left), then it applies at all levels &quot;lower&quot; than it (further right).

While I was in there monkeying around, I decided that I didn't like strings as role names.  They seemed a little more special to me than just plain old strings.

Now we can use symbols as role names:


  &lt;div class=&quot;code ruby&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;user.&lt;span class=&quot;Entity&quot;&gt;has_role&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;administrator&lt;/span&gt;
user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;administrator&lt;/span&gt;, &lt;span class=&quot;Variable&quot;&gt;Group&lt;/span&gt;
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;

Things still didn't quite seem right though.  The whole role to scope mapping seemed like it deserved to be emphasized a little more, and assigning multiple roles at once was a little clunky.

Now we can use hashes for assignment, and lookup:


  &lt;div class=&quot;code ruby&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4
5
6&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;user.&lt;span class=&quot;Entity&quot;&gt;has_role&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;administrator&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;nil&lt;/span&gt;,
  &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;moderator&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Variable&quot;&gt;Group&lt;/span&gt;,
  &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;member&lt;/span&gt;    =&amp;gt; club

user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;administrator&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Variable&quot;&gt;Group&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;moderator&lt;/span&gt; =&amp;gt; club &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; true&lt;/span&gt;
user.&lt;span class=&quot;Entity&quot;&gt;has_role?&lt;/span&gt; &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;administrator&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;nil&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;&lt;span class=&quot;Constant&quot;&gt;:&lt;/span&gt;moderator&lt;/span&gt; =&amp;gt; &lt;span class=&quot;Constant&quot;&gt;nil&lt;/span&gt;    &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; =&amp;gt; false&lt;/span&gt;
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;

This actually demonstrates two things.  First using a scope of &lt;code&gt;nil&lt;/code&gt;, is the same as saying that the scope is global.  Secondly, when doing &lt;code&gt;has_role?&lt;/code&gt; with a hash, all role requirements must be met for &lt;code&gt;has_role?&lt;/code&gt; to be true.
          </content>  </entry>
  <entry xml:base="http://technosorcery.net/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:technosorcery.net,2008-05-18:5</id>
    <published>2008-05-18T17:43:00Z</published>
    <updated>2009-10-04T19:01:13Z</updated>
    <category term="Git"/>
    <category term="Kamitsukai"/>
    <category term="Lighthouse"/>
    <link href="http://technosorcery.net/2008/5/18/git-lighthouse" rel="alternate" type="text/html"/>
    <title>Git + Lighthouse</title>
<summary type="html">I've been playing around with &lt;a href=&quot;http://git.or.cz/&quot; title=&quot;Git - Fast Version Control System&quot;&gt;Git&lt;/a&gt;, &lt;a href=&quot;http://cia.vc/&quot; alt=&quot;&quot;&gt;CIA.vc&lt;/a&gt;, and &lt;a href=&quot;http://lighthouseapp.com&quot; alt=&quot;&quot;&gt;Lighthouse&lt;/a&gt; on a project of mine that's recently been resurrected.

There is a pretty good update hook for CIA.vc integration called &lt;a href=&quot;http://git.kernel.org/?p=cogito/cogito.git;a=blob;hb=HEAD;f=contrib/ciabot.pl&quot; alt=&quot;ciabot.pl from Cogito&quot;&gt;ciabot.pl&lt;/a&gt; that I've been using, without any complaints.  Unfortunately, I haven't been able to find anything to integrate Git with Lighthouse that hasn't needed modification out of the box.  I tried the (pre|post)-receive hooks provided at &lt;a href=&quot;http://obvcode.blogspot.com/2007/10/using-git-with-lighthouse.html&quot; alt=&quot;Obviouse Code: Using Git with Lighthouse&quot;&gt;Obvious Code&lt;/a&gt;, but it had a few issues.  It would use the author/committer information of the first rev it saw, and use that for every revision it handled.  Lighthouse couldn't understand the &quot;changed-at&quot; time format it was using.  The hook also relied on writing out a file with the last rev it saw, so it knew where to pick up, which I didn't really like.

So, I decided to write my own in Perl.  The latest version is available via &lt;a href=&quot;http://git.or.cz/&quot; alt=&quot;Git - Fast Version Control System&quot;&gt;Git&lt;/a&gt; (&lt;a href=&quot;http://technosorcery.net/git/?p=lighthouseapp-git-hook;a=summary&quot;&gt;Git Web&lt;/a&gt;).
&lt;pre&gt;&lt;code&gt;git clone http://technosorcery.net/git/lighthouseapp-git-hook/&lt;/code&gt;&lt;/pre&gt;
The script can either be called straight from an existing update hook, or can be the update hook.  It will split out commits on its own given the old and new SHA1.</summary><content type="html">
            I've been playing around with &lt;a href=&quot;http://git.or.cz/&quot; title=&quot;Git - Fast Version Control System&quot;&gt;Git&lt;/a&gt;, &lt;a href=&quot;http://cia.vc/&quot; alt=&quot;&quot;&gt;CIA.vc&lt;/a&gt;, and &lt;a href=&quot;http://lighthouseapp.com&quot; alt=&quot;&quot;&gt;Lighthouse&lt;/a&gt; on a project of mine that's recently been resurrected.

There is a pretty good update hook for CIA.vc integration called &lt;a href=&quot;http://git.kernel.org/?p=cogito/cogito.git;a=blob;hb=HEAD;f=contrib/ciabot.pl&quot; alt=&quot;ciabot.pl from Cogito&quot;&gt;ciabot.pl&lt;/a&gt; that I've been using, without any complaints.  Unfortunately, I haven't been able to find anything to integrate Git with Lighthouse that hasn't needed modification out of the box.  I tried the (pre|post)-receive hooks provided at &lt;a href=&quot;http://obvcode.blogspot.com/2007/10/using-git-with-lighthouse.html&quot; alt=&quot;Obviouse Code: Using Git with Lighthouse&quot;&gt;Obvious Code&lt;/a&gt;, but it had a few issues.  It would use the author/committer information of the first rev it saw, and use that for every revision it handled.  Lighthouse couldn't understand the &quot;changed-at&quot; time format it was using.  The hook also relied on writing out a file with the last rev it saw, so it knew where to pick up, which I didn't really like.

So, I decided to write my own in Perl.  The latest version is available via &lt;a href=&quot;http://git.or.cz/&quot; alt=&quot;Git - Fast Version Control System&quot;&gt;Git&lt;/a&gt; (&lt;a href=&quot;http://technosorcery.net/git/?p=lighthouseapp-git-hook;a=summary&quot;&gt;Git Web&lt;/a&gt;).
&lt;pre&gt;&lt;code&gt;git clone http://technosorcery.net/git/lighthouseapp-git-hook/&lt;/code&gt;&lt;/pre&gt;
The script can either be called straight from an existing update hook, or can be the update hook.  It will split out commits on its own given the old and new SHA1.
I've been playing around with &lt;a href=&quot;http://git.or.cz/&quot; title=&quot;Git - Fast Version Control System&quot;&gt;Git&lt;/a&gt;, &lt;a href=&quot;http://cia.vc/&quot; alt=&quot;&quot;&gt;CIA.vc&lt;/a&gt;, and &lt;a href=&quot;http://lighthouseapp.com&quot; alt=&quot;&quot;&gt;Lighthouse&lt;/a&gt; on a project of mine that's recently been resurrected.

There is a pretty good update hook for CIA.vc integration called &lt;a href=&quot;http://git.kernel.org/?p=cogito/cogito.git;a=blob;hb=HEAD;f=contrib/ciabot.pl&quot; alt=&quot;ciabot.pl from Cogito&quot;&gt;ciabot.pl&lt;/a&gt; that I've been using, without any complaints.  Unfortunately, I haven't been able to find anything to integrate Git with Lighthouse that hasn't needed modification out of the box.  I tried the (pre|post)-receive hooks provided at &lt;a href=&quot;http://obvcode.blogspot.com/2007/10/using-git-with-lighthouse.html&quot; alt=&quot;Obviouse Code: Using Git with Lighthouse&quot;&gt;Obvious Code&lt;/a&gt;, but it had a few issues.  It would use the author/committer information of the first rev it saw, and use that for every revision it handled.  Lighthouse couldn't understand the &quot;changed-at&quot; time format it was using.  The hook also relied on writing out a file with the last rev it saw, so it knew where to pick up, which I didn't really like.

So, I decided to write my own in Perl.  The latest version is available via &lt;a href=&quot;http://git.or.cz/&quot; alt=&quot;Git - Fast Version Control System&quot;&gt;Git&lt;/a&gt; (&lt;a href=&quot;http://technosorcery.net/git/?p=lighthouseapp-git-hook;a=summary&quot;&gt;Git Web&lt;/a&gt;).


  &lt;div class=&quot;code shell-unix-generic&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;git clone http://technosorcery.net/git/lighthouseapp-git-hook/
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;

The script can either be called straight from an existing update hook, or can be the update hook.  It will split out commits on its own given the old and new SHA1.



  &lt;div class=&quot;code perl&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;!/usr/bin/perl -w&lt;/span&gt;

&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; strict;
&lt;span class=&quot;Support&quot;&gt;binmode&lt;/span&gt; &lt;span class=&quot;Support&quot;&gt;STDIN&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;:utf8&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;;

&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; LWP::UserAgent ();

&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; Date::Format          &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;qw/&lt;/span&gt; time2str &lt;span class=&quot;String&quot;&gt;/&lt;/span&gt;&lt;/span&gt;;
&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; HTTP::Request::Common &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;qw/&lt;/span&gt; POST     &lt;span class=&quot;String&quot;&gt;/&lt;/span&gt;&lt;/span&gt;;
&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; XML::Simple           &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;qw/&lt;/span&gt; XMLout   &lt;span class=&quot;String&quot;&gt;/&lt;/span&gt;&lt;/span&gt;;
&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; YAML                  &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;qw/&lt;/span&gt; Dump     &lt;span class=&quot;String&quot;&gt;/&lt;/span&gt;&lt;/span&gt;;

&lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;################################################&lt;/span&gt;
&lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; Configuration Options                         #&lt;/span&gt;
&lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;################################################&lt;/span&gt;
&lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;git&lt;/span&gt; = &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;/home/jhelwig/bin/git&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;;
&lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;%&lt;/span&gt;tokens&lt;/span&gt; = (
    &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; Fallback token to use if one isn't found for an author.&lt;/span&gt;
    &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;default&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt; =&amp;gt;&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;,
    &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; Individual tokens for author/committer.&lt;/span&gt;
    &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; If author email can't be found, committer's email will be tried.&lt;/span&gt;
    &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;jacob@technosorcery.net&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt; =&amp;gt;&lt;/span&gt; &lt;span class=&quot;Support&quot;&gt;undef&lt;/span&gt;,
    &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;Another Author&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt; =&amp;gt;&lt;/span&gt; &lt;span class=&quot;Support&quot;&gt;undef&lt;/span&gt;,
);
&lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;lighthouseapp_account_url&lt;/span&gt; = &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;http://account-name.lighthouseapp.com&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;;
&lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;lighthouseapp_project_id&lt;/span&gt; = 0;

&lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;################################################&lt;/span&gt;

&lt;span class=&quot;Support&quot;&gt;shift&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;ARGV&lt;/span&gt;;
&lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;old_sha1&lt;/span&gt; = &lt;span class=&quot;Support&quot;&gt;shift&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;ARGV&lt;/span&gt;;
&lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;new_sha1&lt;/span&gt; = &lt;span class=&quot;Support&quot;&gt;shift&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;ARGV&lt;/span&gt;;

&lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;rev_list&lt;/span&gt; = &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;git&lt;/span&gt; rev-list --pretty=format:&amp;quot;&amp;quot; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;old_sha1&lt;/span&gt;..&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;new_sha1&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;/span&gt;;
&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;rev_list&lt;/span&gt; =~ &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;Support&quot;&gt;s&lt;/span&gt;/&lt;/span&gt;^commit &lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;Keyword&quot;&gt;gm&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;;

&lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;revs&lt;/span&gt; = &lt;span class=&quot;Support&quot;&gt;reverse&lt;/span&gt;(&lt;span class=&quot;Support&quot;&gt;split&lt;/span&gt;(&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;Constant&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;rev_list&lt;/span&gt;));

&lt;span class=&quot;Keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;rev&lt;/span&gt; (&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;revs&lt;/span&gt;) {
    &lt;span class=&quot;Support&quot;&gt;chomp&lt;/span&gt;(&lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;author_name&lt;/span&gt; = &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;git&lt;/span&gt; show --pretty=format:&amp;quot;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;%&lt;/span&gt;an&lt;/span&gt;&amp;quot; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;rev&lt;/span&gt; | sed q&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;/span&gt;);
    &lt;span class=&quot;Support&quot;&gt;chomp&lt;/span&gt;(&lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;author_email&lt;/span&gt; = &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;git&lt;/span&gt; show --pretty=format:&amp;quot;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;%&lt;/span&gt;ae&lt;/span&gt;&amp;quot; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;rev&lt;/span&gt; | sed q&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;/span&gt;);
    &lt;span class=&quot;Support&quot;&gt;chomp&lt;/span&gt;(&lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;author_date&lt;/span&gt; = &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;git&lt;/span&gt; show --pretty=format:&amp;quot;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;%&lt;/span&gt;aD&lt;/span&gt;&amp;quot; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;rev&lt;/span&gt; | sed q&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;/span&gt;);
    &lt;span class=&quot;Support&quot;&gt;chomp&lt;/span&gt;(&lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;committer_name&lt;/span&gt; = &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;git&lt;/span&gt; show --pretty=format:&amp;quot;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;%&lt;/span&gt;cn&lt;/span&gt;&amp;quot; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;rev&lt;/span&gt; | sed q&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;/span&gt;);
    &lt;span class=&quot;Support&quot;&gt;chomp&lt;/span&gt;(&lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;committer_email&lt;/span&gt; = &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;git&lt;/span&gt; show --pretty=format:&amp;quot;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;%&lt;/span&gt;ce&lt;/span&gt;&amp;quot; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;rev&lt;/span&gt; | sed q&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;/span&gt;);
    &lt;span class=&quot;Support&quot;&gt;chomp&lt;/span&gt;(&lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;committer_date&lt;/span&gt; = &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;git&lt;/span&gt; show --pretty=format:&amp;quot;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;%&lt;/span&gt;cD&lt;/span&gt;&amp;quot; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;rev&lt;/span&gt; | sed q&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;/span&gt;);
    &lt;span class=&quot;Support&quot;&gt;chomp&lt;/span&gt;(&lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;changed_at&lt;/span&gt; = time2str(&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;%&lt;/span&gt;Y&lt;/span&gt;-&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;%&lt;/span&gt;m&lt;/span&gt;-&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;%&lt;/span&gt;dT&lt;/span&gt;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;%&lt;/span&gt;TZ&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;git&lt;/span&gt; show --pretty=format:&amp;quot;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;%&lt;/span&gt;ct&lt;/span&gt;&amp;quot; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;rev&lt;/span&gt; | sed q&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;GMT&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;));
    &lt;span class=&quot;Support&quot;&gt;chomp&lt;/span&gt;(&lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;commit_log&lt;/span&gt; = &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;git&lt;/span&gt; log -n1 --pretty=medium &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;rev&lt;/span&gt; | sed '1,4d'&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;/span&gt;);

    &lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;body&lt;/span&gt; = &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&amp;quot;HERE&amp;quot;&lt;/span&gt;;&lt;span class=&quot;String&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;commit_log&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;Author:     &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;author_name&lt;/span&gt; &amp;lt;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;author_email&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;AuthorDate: &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;author_date&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;Commit:     &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;committer_name&lt;/span&gt; &amp;lt;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;committer_email&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;CommitDate: &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;committer_date&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;HERE&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;    chomp(my &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;commit_subject&lt;/span&gt; = `&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;git&lt;/span&gt; show --pretty=format:&amp;quot;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;%&lt;/span&gt;s&lt;/span&gt;&amp;quot; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;rev&lt;/span&gt; | sed q`);&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;    my &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;changes_yaml&lt;/span&gt; = Dump([&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;        map { [ split(/&lt;span class=&quot;Constant&quot;&gt;\s&lt;/span&gt;+/, &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;_&lt;/span&gt;) ] } split(&amp;quot;&lt;span class=&quot;Constant&quot;&gt;\n&lt;/span&gt;&amp;quot;, `&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;git&lt;/span&gt; diff-tree -r --name-status &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;rev&lt;/span&gt; | sed '1d'`)&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;    ]);&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;    my &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;xml&lt;/span&gt; = XMLout({ 'changeset' =&amp;gt; {&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;            'title'      =&amp;gt; [ &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;commit_subject&lt;/span&gt;, ],&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;            'body'       =&amp;gt; [ &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;body&lt;/span&gt;, ],&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;            'revision'   =&amp;gt; [ &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;rev&lt;/span&gt;, ],&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;            'changes'    =&amp;gt; {&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;                'type'    =&amp;gt; 'yaml',&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;                'content' =&amp;gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;changes_yaml&lt;/span&gt;,&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;            },&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;            'changed-at' =&amp;gt; {&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;                'type'    =&amp;gt; 'datetime',&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;                'content' =&amp;gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;changed_at&lt;/span&gt;,&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;            },&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;        }},&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;        KeepRoot =&amp;gt; 1,&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;    );&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;    my &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;lh_token&lt;/span&gt; = defined(&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;tokens&lt;/span&gt;{&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;author_email&lt;/span&gt;})&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;        ? &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;tokens&lt;/span&gt;{&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;author_email&lt;/span&gt;}&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;        : defined(&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;tokens&lt;/span&gt;{&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;committer_email&lt;/span&gt;})&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;            ? &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;tokens&lt;/span&gt;{&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;committer_email&lt;/span&gt;}&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;            : &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;tokens&lt;/span&gt;{'default'};&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;    my &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;ua&lt;/span&gt; = LWP::UserAgent-&amp;gt;new();&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;    &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;ua&lt;/span&gt;-&amp;gt;timeout(3);&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;    &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;ua&lt;/span&gt;-&amp;gt;env_proxy();&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;    my &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;response&lt;/span&gt; = &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;ua&lt;/span&gt;-&amp;gt;simple_request(POST(&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;        &amp;quot;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;lighthouseapp_account_url&lt;/span&gt;/projects/&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;lighthouseapp_project_id&lt;/span&gt;/changesets.xml&amp;quot;,&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;        'content-type' =&amp;gt; 'application/xml',&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;        'X-LighthouseToken' =&amp;gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;lh_token&lt;/span&gt;,&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;        Content =&amp;gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;xml&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;    ));&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;    unless (&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;response&lt;/span&gt;-&amp;gt;is_success()) {&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;        print &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;response&lt;/span&gt;-&amp;gt;status_line() . &amp;quot;&lt;span class=&quot;Constant&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;            . &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;response&lt;/span&gt;-&amp;gt;content() . &amp;quot;&lt;span class=&quot;Constant&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;Constant&quot;&gt;\n&lt;/span&gt;&amp;quot;;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;    }&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;

          </content>  </entry>
  <entry xml:base="http://technosorcery.net/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:technosorcery.net,2007-09-06:4</id>
    <published>2007-09-06T12:51:00Z</published>
    <updated>2009-10-11T09:52:29Z</updated>
    <category term="Request Tracker"/>
    <link href="http://technosorcery.net/2007/9/6/soft-resolution-of-request-tracker-tickets" rel="alternate" type="text/html"/>
    <title>Soft resolution of Request Tracker tickets.</title>
<summary type="html">We wanted to be able to close a ticket, without actually &quot;closing&quot; it.  Thus the &quot;pending&quot; ticket status was born.  We can set a ticket's status as &quot;pending&quot;, and have it automatically marked as &quot;closed&quot; &lt;i&gt;n&lt;/i&gt; days later, if there haven't been any replies in that time.

I have received permission from my employer to release this under the &lt;a href=&quot;http://www.gnu.org/copyleft/gpl.html&quot;&gt;GNU GPLv2&lt;/a&gt;.

Now that the background info is done with, here's the solution I came up with to be able to have a soft resolution of tickets.</summary><content type="html">
            We wanted to be able to close a ticket, without actually &quot;closing&quot; it.  Thus the &quot;pending&quot; ticket status was born.  We can set a ticket's status as &quot;pending&quot;, and have it automatically marked as &quot;closed&quot; &lt;i&gt;n&lt;/i&gt; days later, if there haven't been any replies in that time.

I have received permission from my employer to release this under the &lt;a href=&quot;http://www.gnu.org/copyleft/gpl.html&quot;&gt;GNU GPLv2&lt;/a&gt;.

Now that the background info is done with, here's the solution I came up with to be able to have a soft resolution of tickets.
We wanted to be able to close a ticket, without actually &quot;closing&quot; it.  Thus the &quot;pending&quot; ticket status was born.  We can set a ticket's status as &quot;pending&quot;, and have it automatically marked as &quot;closed&quot; &lt;i&gt;n&lt;/i&gt; days later, if there haven't been any replies in that time.

I have received permission from my employer to release this under the &lt;a href=&quot;http://www.gnu.org/copyleft/gpl.html&quot;&gt;GNU GPLv2&lt;/a&gt;.

Now that the background info is done with, here's the solution I came up with to be able to have a soft resolution of tickets.

First up: Add the status itself to the list of inactive statuses, since supposedly the ticket is done with, or the requester just doesn't care enough anymore to be bothered with replying to it.

Put the following in &lt;code&gt;etc/RT_SiteConfig.pm&lt;/code&gt;:


  &lt;div class=&quot;code perl&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;InactiveStatus&lt;/span&gt; = &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;qw(&lt;/span&gt;resolved rejected pending deleted&lt;span class=&quot;String&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;InactiveStatus&lt;/span&gt;;
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;



You'll then need to create &lt;code&gt;local/lib/RT/Action/AutoResolve.pm&lt;/code&gt; ((I'd love to give credit on where I found the code that this is based on, but I can't seem to find it on the RT Wiki anymore.  If you can find the original, let me know so I can give proper credit for this.)) with the following content:


  &lt;div class=&quot;code perl&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;&lt;span class=&quot;Keyword&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;RT::Action::AutoResolve;&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;require&lt;/span&gt; RT::Action::Generic;

&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; strict;
&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; vars &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;qw/&lt;/span&gt;@ISA&lt;span class=&quot;String&quot;&gt;/&lt;/span&gt;&lt;/span&gt;;
&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;ISA&lt;/span&gt;=&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;qw(&lt;/span&gt;RT::Action::Generic&lt;span class=&quot;String&quot;&gt;)&lt;/span&gt;&lt;/span&gt;;

&lt;span class=&quot;Storage&quot;&gt;sub&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;Describe&lt;/span&gt;  {
    &lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;self&lt;/span&gt; = &lt;span class=&quot;Support&quot;&gt;shift&lt;/span&gt;;
    &lt;span class=&quot;Keyword&quot;&gt;return&lt;/span&gt; (&lt;span class=&quot;Support&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;self&lt;/span&gt; );
}

&lt;span class=&quot;Storage&quot;&gt;sub&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;Prepare&lt;/span&gt; {
    &lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;self&lt;/span&gt; = &lt;span class=&quot;Support&quot;&gt;shift&lt;/span&gt;;

    &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; if the ticket is already resolved don't re-resolve it.&lt;/span&gt;
    &lt;span class=&quot;Keyword&quot;&gt;if&lt;/span&gt; ( ( &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;self&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;TicketObj&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;Status &lt;span class=&quot;Support&quot;&gt;eq&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;resolved&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt; ) ) {
        &lt;span class=&quot;Keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;Support&quot;&gt;undef&lt;/span&gt;;
    } &lt;span class=&quot;Keyword&quot;&gt;else&lt;/span&gt; {
        &lt;span class=&quot;Keyword&quot;&gt;return&lt;/span&gt; (1);
    }
}

&lt;span class=&quot;Storage&quot;&gt;sub&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;Commit&lt;/span&gt; {
    &lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;self&lt;/span&gt; = &lt;span class=&quot;Support&quot;&gt;shift&lt;/span&gt;;
    &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;self&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;TicketObj&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;SetStatus( &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;resolved&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt; );

    &lt;span class=&quot;Keyword&quot;&gt;return&lt;/span&gt; (1);
}

1;
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;

This will be used as the &lt;code&gt;--action argument to &lt;/code&gt;&lt;code&gt;rt-crontool&lt;/code&gt;.

Create &lt;code&gt;local/lib/RT/Condition/UntouchedInDays.pm&lt;/code&gt; ((Modified from &lt;a href=&quot;http://wiki.bestpractical.com/view/UntouchedInHours&quot;&gt;UntouchedInHours&lt;/a&gt;.)) for the &lt;code&gt;--condition&lt;/code&gt; used with &lt;code&gt;rt-crontool&lt;/code&gt;:


  &lt;div class=&quot;code perl&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;&lt;span class=&quot;Keyword&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;RT::Condition::UntouchedInDays;&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;require&lt;/span&gt; RT::Condition::Generic;

&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; RT::Date;

&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;@&lt;/span&gt;ISA&lt;/span&gt; = &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;qw(&lt;/span&gt;RT::Condition::Generic&lt;span class=&quot;String&quot;&gt;)&lt;/span&gt;&lt;/span&gt;; 

&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; strict;
&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; vars &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;qw/&lt;/span&gt;@ISA&lt;span class=&quot;String&quot;&gt;/&lt;/span&gt;&lt;/span&gt;; 

&lt;span class=&quot;Storage&quot;&gt;sub&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;IsApplicable&lt;/span&gt; {
        &lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;self&lt;/span&gt; = &lt;span class=&quot;Support&quot;&gt;shift&lt;/span&gt;;
        &lt;span class=&quot;Keyword&quot;&gt;if&lt;/span&gt; ((&lt;span class=&quot;Support&quot;&gt;time&lt;/span&gt;()-&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;self&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;TicketObj&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;LastUpdatedObj&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;Unix)&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;/&lt;/span&gt;3600&lt;span class=&quot;String&quot;&gt;/&lt;/span&gt;&lt;/span&gt;24 &amp;gt;= &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;self&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;Argument) {
                &lt;span class=&quot;Keyword&quot;&gt;return&lt;/span&gt; 1
        }
        &lt;span class=&quot;Keyword&quot;&gt;else&lt;/span&gt; {
                &lt;span class=&quot;Keyword&quot;&gt;return&lt;/span&gt; 0;
        }
}

1;
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;


&lt;code&gt;local/lib/RT/Search/PendingTicketsInQueue.pm&lt;/code&gt; will be used for the &lt;code&gt;--search&lt;/code&gt;. ((I can't seem to find where I got this code from originally.  If you recognize it, or are the original author, please let me know.))


  &lt;div class=&quot;code perl&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;&lt;span class=&quot;Keyword&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;RT::Search::PendingTicketsInQueue;&lt;/span&gt;

&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; strict;
&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; base &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;qw(&lt;/span&gt;RT::Search::Generic&lt;span class=&quot;String&quot;&gt;)&lt;/span&gt;&lt;/span&gt;;


&lt;span class=&quot;Storage&quot;&gt;sub&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;Describe&lt;/span&gt;  {
  &lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;self&lt;/span&gt; = &lt;span class=&quot;Support&quot;&gt;shift&lt;/span&gt;;
  &lt;span class=&quot;Keyword&quot;&gt;return&lt;/span&gt; (&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;self&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;loc(&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;No description for [_1]&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;Support&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;self&lt;/span&gt;));
}

&lt;span class=&quot;Storage&quot;&gt;sub&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;Prepare&lt;/span&gt;  {
  &lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;self&lt;/span&gt; = &lt;span class=&quot;Support&quot;&gt;shift&lt;/span&gt;;

  &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;self&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;TicketsObj&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;LimitQueue(&lt;span class=&quot;Constant&quot;&gt;VALUE &lt;/span&gt;=&amp;gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;self&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;Argument);

  &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;self&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;TicketsObj&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;LimitStatus(&lt;span class=&quot;Constant&quot;&gt;VALUE &lt;/span&gt;=&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;pending&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;);

  &lt;span class=&quot;Keyword&quot;&gt;return&lt;/span&gt;(1);
}
1;
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;


Now that the pre-requisites are in place, we can create the &lt;code&gt;rt-pending&lt;/code&gt; script that should be called daily to resolve tickets that have been set as pending for &lt;i&gt;n&lt;/i&gt; days (in this example: &lt;code&gt;n = 7&lt;/code&gt;). ((I just dropped this script into &lt;code&gt;/etc/cron.daily/&lt;/code&gt;, but I'm using Debian.  You should adjust as appropriate for your distribution.))


  &lt;div class=&quot;code shell-unix-generic&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;! /bin/sh&lt;/span&gt;

/opt/rt3/bin/rt-crontool --search RT::Search::PendingTicketsInQueue --search-arg &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;Help Desk&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt; --condition RT::Condition::UntouchedInDays --condition-arg 7 --action RT::Action::AutoResolve
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;


That finishes up the portion to mark the tickets as resolved, after the given number of days have passed, with no updates to a ticket.  Next up is re-opening the ticket if someone replies to it.

Now we'll create the pre-requisites necessary to setup the queue, and global scrips relating to pending tickets.
&lt;code&gt;local/lib/RT/Condition/ReplyToPending.pm&lt;/code&gt; ((Heavily based on &lt;a href=&quot;http://wiki.bestpractical.com/view/ReplyToResolved&quot;&gt;ReplyToResolved.pm&lt;/a&gt;))


  &lt;div class=&quot;code perl&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;&lt;span class=&quot;Keyword&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;RT::Condition::ReplyToPending;&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; strict;
&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; base &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;qw(&lt;/span&gt;RT::Condition::Generic&lt;span class=&quot;String&quot;&gt;)&lt;/span&gt;&lt;/span&gt;;
&lt;span class=&quot;Storage&quot;&gt;sub&lt;/span&gt; &lt;span class=&quot;Entity&quot;&gt;IsApplicable&lt;/span&gt; {
   &lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;self&lt;/span&gt; = &lt;span class=&quot;Support&quot;&gt;shift&lt;/span&gt;;
   &lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;ticket&lt;/span&gt; = &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;self&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;TicketObj;
   &lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;transaction&lt;/span&gt; = &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;self&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;TransactionObj;
   &lt;span class=&quot;Keyword&quot;&gt;if&lt;/span&gt; ( &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;transaction&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;Type &lt;span class=&quot;Support&quot;&gt;eq&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;Correspond&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt; &amp;amp;&amp;amp;
       &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;ticket&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;Status &lt;span class=&quot;Support&quot;&gt;eq&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;pending&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt; &amp;amp;&amp;amp;
       &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;transaction&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;Creator != 1 )  { &lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; prevent loop&lt;/span&gt;
       &lt;span class=&quot;Keyword&quot;&gt;return&lt;/span&gt;(1);
   }
   &lt;span class=&quot;Keyword&quot;&gt;else&lt;/span&gt; {
       &lt;span class=&quot;Keyword&quot;&gt;return&lt;/span&gt;(&lt;span class=&quot;Support&quot;&gt;undef&lt;/span&gt;);
   }
}
1;
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;


You can use the following template ((Also taken from the &lt;a href=&quot;http://wiki.bestpractical.com/view/ReplyToResolved&quot;&gt;ReplyToResolved&lt;/a&gt; &lt;a href=&quot;http://wiki.bestpractical.com/&quot;&gt;RT Wiki&lt;/a&gt; site.)) to make the conditions, and actions described here available through the web scrip interface:


  &lt;div class=&quot;code perl&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;!/usr/bin/perl&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; strict;
&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; Unicode::String &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;qw(&lt;/span&gt;utf8 latin1&lt;span class=&quot;String&quot;&gt;)&lt;/span&gt;&lt;/span&gt;;
&lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; Replace this with your RT_LIB_PATH&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; lib &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;/opt/rt3/lib&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;;
&lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt; Replace this with your RT_ETC_PATH&lt;/span&gt;
&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; lib &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;/opt/rt3/etc&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;;
&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; RT;
&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; RT::Interface::CLI &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;qw(&lt;/span&gt; CleanEnv GetCurrentUser &lt;span class=&quot;String&quot;&gt;)&lt;/span&gt;&lt;/span&gt;;
&lt;span class=&quot;Keyword&quot;&gt;use&lt;/span&gt; RT::ScripCondition;
CleanEnv();
RT::LoadConfig();
RT::Init();
&lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;#Drop setgid permissions&lt;/span&gt;
RT::DropSetGIDPermissions();
&lt;span class=&quot;Comment&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#&lt;/span&gt;#Get the current user all loaded&lt;/span&gt;
&lt;span class=&quot;Storage&quot;&gt;our&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;CurrentUser&lt;/span&gt; = GetCurrentUser();
&lt;span class=&quot;Keyword&quot;&gt;unless&lt;/span&gt;( &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;CurrentUser&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;Id ) {
    &lt;span class=&quot;Support&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;No RT user found. Please consult your RT administrator.&lt;span class=&quot;Constant&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;;
    &lt;span class=&quot;Keyword&quot;&gt;exit&lt;/span&gt; 1;
}
&lt;span class=&quot;Storage&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;sc&lt;/span&gt; = new RT::ScripCondition(&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;CurrentUser&lt;/span&gt;);

&lt;span class=&quot;Variable&quot;&gt;&lt;span class=&quot;Variable&quot;&gt;$&lt;/span&gt;sc&lt;/span&gt;&lt;span class=&quot;Keyword&quot;&gt;-&amp;gt;&lt;/span&gt;Create(
           &lt;span class=&quot;Constant&quot;&gt;Name                 &lt;/span&gt;=&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;On Reply to Pending&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;,
           &lt;span class=&quot;Constant&quot;&gt;Description          &lt;/span&gt;=&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;Reply to a ticket marked as pending.&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
           &lt;span class=&quot;Constant&quot;&gt;ExecModule           &lt;/span&gt;=&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;ReplyToPendingTicket&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;,
           &lt;span class=&quot;Constant&quot;&gt;ApplicableTransTypes &lt;/span&gt;=&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;Any&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
           );
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;


Now that these steps are done, you can create a global scrip with the condition set to &lt;code&gt;On Reply to Pending&lt;/code&gt;, and the action set to &lt;code&gt;Open Ticket&lt;/code&gt;.  This will re-open any tickets as soon as someone replies to them, but not if anyone comments on them.  (Commenting will, however delay the resolution of a ticket.)

You'll then need to create either a global scrip, or a queue specific scrip for each queue where you want people to be able to reply to a pending ticket, and have it re-opened. (Personally I recommend the global scrip method.)

This step requires direct DB access.  You'll need to be able to do an insert on the &lt;code&gt;ScripConditions&lt;/code&gt; table. &lt;code&gt;&amp;lt;user_id&amp;gt;&lt;/code&gt; should be replaced with a valid user ID, taken from one of the other entries in the &lt;code&gt;ScripConditions&lt;/code&gt; table.


  &lt;div class=&quot;code sql&quot;&gt;
    &lt;table class=&quot;code&quot;&gt;
      &lt;tr&gt;
        &lt;td width=&quot;25px&quot;&gt;
&lt;pre class=&quot;blackboard lines&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class=&quot;blackboard&quot;&gt;&lt;span class=&quot;Keyword&quot;&gt;INSERT INTO&lt;/span&gt; ScripConditions(
  Name,
  Description,
  ExecModule,
  Argument,
  ApplicableTransTypes,
  Creator,
  Created,
  LastUpdatedBy,
  LastUpdated
) &lt;span class=&quot;Keyword&quot;&gt;VALUES&lt;/span&gt; (
  &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;On Pending'&lt;/span&gt;,
  &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;Whenever a ticket is marked as pending resolution'&lt;/span&gt;,
  &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;StatusChange'&lt;/span&gt;,
  &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;pending'&lt;/span&gt;,
  &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;Status'&lt;/span&gt;,
  &amp;lt;user_id&amp;gt;,
  NOW(),
  &amp;lt;user_id&amp;gt;,
  NOW()
);
&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/div&gt;

This sets up the &quot;On Pending&quot; scrip condition, so that you'll be able to create a scrip such as &quot;On Pending Reply to Requesters with template XXXXXX&quot;, and have a custom message sent out to inform the requester that the ticket will close itself in &lt;i&gt;n&lt;/i&gt; days, unless they reply to it.
          </content>  </entry>
  <entry xml:base="http://technosorcery.net/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:technosorcery.net,2007-05-26:2</id>
    <published>2007-05-26T18:00:22Z</published>
    <updated>2009-10-02T02:29:01Z</updated>
    <category term="Request Tracker"/>
    <link href="http://technosorcery.net/2007/5/26/welcome" rel="alternate" type="text/html"/>
    <title>Welcome!</title>
<content type="html">
            Welcome to Technosorcery Networks.  There's not much up here right now, but I have gotten permission from my current employer to release some of the extensions to &lt;a href=&quot;http://bestpractical.com/rt/&quot; alt=&quot;Request Tracker by Best Practical Solutions, LLC.&quot;&gt;Request Tracker&lt;/a&gt; that I have written while at work.  As I document these extensions at work, I'll also be putting them up here, for anyone else to add them to his or her RT instance.
          </content>  </entry>
  <entry xml:base="http://technosorcery.net/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:technosorcery.net,2007-05-25:1</id>
    <published>2007-05-25T17:58:02Z</published>
    <updated>2009-10-02T02:29:00Z</updated>
    <category term="Uncategorized"/>
    <link href="http://technosorcery.net/2007/5/25/gpg" rel="alternate" type="text/html"/>
    <title>GPG</title>
<content type="html">
            I tend to sign all outgoing email with my &lt;a href=&quot;http://technosorcery.net/key0x4612D29E282E4321.asc&quot; title=&quot;Jacob Helwig's GPG Key&quot;&gt;GPG key&lt;/a&gt;.  If you happen to be sending email to me, feel free to encrypt it using that key.  I am always more than happy to meet up for a keysigning, or to include a keysigning as part of any other meetup.
&lt;ul&gt;
	&lt;li&gt;Key ID: 0x4612D29E282E4321&lt;/li&gt;
	&lt;li&gt;Key Fingerprint: 8445 B661 E215 BD04 A363  A52E 4612 D29E 282E 4321&lt;/li&gt;
&lt;/ul&gt;
          </content>  </entry>
</feed>
