I'm pleased to announce the very first release (v0.1) of RTF-Extensions, a Ruby library that adds a few useful extensions to the excellent Ruby RTF package originally developed by Peter Wood.

RTF-Extensions has two main interests for Ruby developers who write code for generating RTF documents.

  1. It can handle character strings encoded in UTF-8 and generate RTF documents that preserve those Unicode characters.
  2. It offers a facility to add hyperlinks to a RTF document.

RTF-Extensions is NOT a replacement for Ruby RTF. It comes as an addition and shall be used on top of the original Ruby RTF.

For more details, please visit the project homepage on GitHub.

I work with a few clients who do not own a source code repository. I try to educate them about the benefits of putting their project under a Version Control System but it takes time to convince them.

As the developer of their application, I feel the need for such a service. I want to track the changes made to the source code, tag a version when I deliver a release or be able to figure out what precisely changed between 2 releases.

That’s why I had to find my own solution. Since I know Subversion, I came up with a Subversion repository installed on my Macbook. Actually it’s pretty simple and here are the steps to do that.

Firstly, install the whole Subversion package on your Mac. There used to be many variants available, depending on the version of OS X you use. Now it looks like CollabNet glue them all into one Universal binary object, which is a great initiative.

Once installed, use a terminal (iTerm is cool) to create your own SVN repository. I put it under my home directory since it’s for a personal use.

$ mkdir -p ~/repositories/svn
$ svnadmin create ~/repositories/svn/local

Since I want a simple setup, I use the svnserve server available with the Subversion package. Edit svnserve.conf to configure how authentication and authorization works. I just change the general section to disallow anonymous access, grant all permissions to any authenticated users and ask svnserve to look into the passwd file for valid credentials.

$ vi ~/repositories/svn/local/conf/svnserve.conf

[general]
### These options control access to the repository for unauthenticated
### and authenticated users.  Valid values are "write", "read",
### and "none".  The sample settings below are the defaults.
anon-access = none
auth-access = write
### The password-db option controls the location of the password
### database file.  Unless you specify a path starting with a /,
### the file's location is relative to the directory containing
### this configuration file.
### If SASL is enabled (see below), this file will NOT be used.
### Uncomment the line below to use the default password file.
password-db = passwd

Now edit the passwd file to create a valid login/password credential you will use to access the local repository.

$ vi ~/repositories/svn/local/conf/passwd
[users]
mylogin = mypassword

At this stage, you’ve got the simplest Subversion configuration and it’s time to test it. Launch the Subversion server in test mode and try to connect to it through your favorite SVN client.

$ svnserve -d -r ~/repositories/svn/local

Use the svn://localhost URL and try to create a folder or import an existing project to be sure you are granted the commit permission. If everything works fine, congratulations: you’ve got your own local Subversion repository where you can put under control the code of your project. One more thing you can do is to ensure it’s started when you boot your Mac. I use xinetd to do that. The Subversion service is already mentioned in /etc/services (under the svn alias) so you just have to add a configuration file for xinetd.

$ # kill the existing svnserve daemon
$ killall svnserve
$ sudo vi /etc/xinetd.d/svnserve

# default: on
# Subversion server

service svn
{
    socket_type = stream
    protocol    = tcp
    user        = <mylogin>
    wait        = no
    disable     = no
    server      = /usr/local/bin/svnserve
    server_args = -i -r /Users/<mylogin>/repositories/svn/local
    only_from   = 127.0.0.1
    port        = 3690
}

Replace <mylogin> by your own login. Note that I restrict the access to local clients. Then ask xinetd to reload its configuration.

$ sudo kill -HUP `cat /var/run/xinetd.pid`

and verify that xinetd listens to incoming SVN clients.

$ netstat -an | grep LISTEN | grep 3690
tcp4       0      0  *.3690                 *.*                    LISTEN

You’re done ! Being located on my laptop, I can have it with me anytime, regardless of any connectivity constraints. However, it makes it more difficult to share with other developers. May be Git would be more adequate to fulfill such a requirement.

UPDATE for Snow Leopard (and probably Leopard too)

After migrating to Snow Leopard, I lost the xinetd configuration file because Apple deprecates xinetd in favor of their own startup technology, launchd. Though I had a nice /etc/xinetd.d-migrated2launchd/ directory on my filesystem, it was empty and nothing was actually migrated.

After googling a bit, I figured out I had to configure svnserve for launchd. Here is the org.tigris.subversion.svnserve.plist file I put in place under /Library/LaunchDaemons.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Debug</key>
  <false/>
  <key>GroupName</key>
  <string>mygroup</string>
  <key>Label</key>
  <string>org.tigris.subversion.svnserve</string>
  <key>OnDemand</key>
  <true/>
  <key>Program</key>
  <string>/usr/local/bin/svnserve</string>
  <key>ProgramArguments</key>
  <array>
    <string>/usr/local/bin/svnserve</string>
    <string>--listen-port=3690</string>
    <string>--listen-host=127.0.0.1</string>
    <string>--inetd</string>
    <string>--root=/Users/<mylogin>/repositories/svn/local</string>
  </array>
  <key>ServiceDescription</key>
  <string>SVN Version Control System</string>
  <key>Sockets</key>
  <dict>
    <key>Listeners</key>
    <array>
    <dict>
      <key>SockFamily</key>
      <string>IPv4</string>
      <key>SockServiceName</key>
      <string>svn</string>
      <key>SockType</key>
      <string>stream</string>
    </dict>
    <dict>
      <key>SockFamily</key>
      <string>IPv6</string>
      <key>SockServiceName</key>
      <string>svn</string>
      <key>SockType</key>
      <string>stream</string>
    </dict>
    </array>
  </dict>
  <key>Umask</key>
  <integer>2</integer>
  <key>UserName</key>
  <string>mylogin</string>
  <key>inetdCompatibility</key>
  <dict>
    <key>Wait</key>
    <false/>
  </dict>
</dict>
</plist>

From here, you can start the service.

$ sudo launchctl load /Library/LaunchDaemons/org.tigris.subversion.svnserve.plist
$ sudo launchctl start org.tigris.subversion.svnserve

References

Subversion Book

  1. Creating and Configuring Your Repository
  2. svnserve, a Custom Server

Kasia in a nutshell Setting up Subversion as an xinetd process (on Linux)

svnserve launchd item for OS X 10.4

Recent Entries

Recent Comments

Ruby and Rails> Recommended