bananajour 2.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +66 -0
 - data/Readme.md +86 -0
 - data/bin/bananajour +58 -0
 - data/lib/bananajour.rb +99 -0
 - data/lib/bananajour/bonjour.rb +9 -0
 - data/lib/bananajour/bonjour/advertiser.rb +57 -0
 - data/lib/bananajour/bonjour/bananajour_browser.rb +24 -0
 - data/lib/bananajour/bonjour/browser.rb +52 -0
 - data/lib/bananajour/bonjour/person.rb +21 -0
 - data/lib/bananajour/bonjour/repository.rb +39 -0
 - data/lib/bananajour/bonjour/repository_browser.rb +36 -0
 - data/lib/bananajour/commands.rb +80 -0
 - data/lib/bananajour/gem_dependencies.rb +34 -0
 - data/lib/bananajour/grit_extensions.rb +11 -0
 - data/lib/bananajour/helpers.rb +100 -0
 - data/lib/bananajour/repository.rb +85 -0
 - data/lib/bananajour/version.rb +3 -0
 - data/sinatra/app.rb +87 -0
 - data/sinatra/lib/browsers.rb +2 -0
 - data/sinatra/lib/diff_helpers.rb +92 -0
 - data/sinatra/lib/mock_browsers.rb +55 -0
 - data/sinatra/public/jquery-1.3.2.min.js +19 -0
 - data/sinatra/public/loader.gif +0 -0
 - data/sinatra/public/logo.png +0 -0
 - data/sinatra/public/pbjt.swf +0 -0
 - data/sinatra/public/peanut.png +0 -0
 - data/sinatra/views/commit.haml +112 -0
 - data/sinatra/views/home.haml +305 -0
 - data/sinatra/views/layout.haml +119 -0
 - data/sinatra/views/readme.haml +52 -0
 - metadata +183 -0
 
    
        data/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1,66 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "rubygems"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            $:.unshift "#{File.dirname(__FILE__)}/lib"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require "bananajour/version"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "bananajour/gem_dependencies"
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            gem = Gem::Specification.new do |gem|
         
     | 
| 
      
 9 
     | 
    
         
            +
              gem.name             = "bananajour"
         
     | 
| 
      
 10 
     | 
    
         
            +
              gem.version          = Bananajour::VERSION
         
     | 
| 
      
 11 
     | 
    
         
            +
              gem.platform         = Gem::Platform::RUBY
         
     | 
| 
      
 12 
     | 
    
         
            +
              gem.extra_rdoc_files = ["Readme.md"]
         
     | 
| 
      
 13 
     | 
    
         
            +
              gem.summary          = "Local git repository hosting with a sexy web interface and bonjour discovery. It's like your own little adhoc, network-aware github!"
         
     | 
| 
      
 14 
     | 
    
         
            +
              gem.description      = gem.summary
         
     | 
| 
      
 15 
     | 
    
         
            +
              gem.authors          = ["Tim Lucas"]
         
     | 
| 
      
 16 
     | 
    
         
            +
              gem.email            = "t.lucas@toolmantim.com"
         
     | 
| 
      
 17 
     | 
    
         
            +
              gem.homepage         = "http://github.com/toolmantim/bananajour"
         
     | 
| 
      
 18 
     | 
    
         
            +
              gem.require_path     = "lib"
         
     | 
| 
      
 19 
     | 
    
         
            +
              gem.files            = %w(Readme.md Rakefile) + Dir.glob("{bin,lib,sinatra}/**/*")
         
     | 
| 
      
 20 
     | 
    
         
            +
              gem.has_rdoc         = false
         
     | 
| 
      
 21 
     | 
    
         
            +
              gem.bindir           = 'bin'
         
     | 
| 
      
 22 
     | 
    
         
            +
              gem.executables      = [ 'bananajour' ]
         
     | 
| 
      
 23 
     | 
    
         
            +
              Bananajour::GemDependencies.all.each {|dep| gem.add_runtime_dependency( dep.name, dep.version ) }
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            task :clean do
         
     | 
| 
      
 27 
     | 
    
         
            +
              FileUtils.rm_rf Dir['*.gem', '*.gemspec']
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
         
     | 
| 
      
 30 
     | 
    
         
            +
            namespace :gem do
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              desc "Rebuild and install bananajour as a gem"
         
     | 
| 
      
 33 
     | 
    
         
            +
              task :install => :package do
         
     | 
| 
      
 34 
     | 
    
         
            +
                require 'rubygems/installer'
         
     | 
| 
      
 35 
     | 
    
         
            +
                Dir['*.gem'].each do |gem|
         
     | 
| 
      
 36 
     | 
    
         
            +
                  Gem::Installer.new(gem).install
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              desc "Create the gem"
         
     | 
| 
      
 41 
     | 
    
         
            +
              task :package => [:clean, "spec:generate"] do
         
     | 
| 
      
 42 
     | 
    
         
            +
                require 'rubygems/builder'
         
     | 
| 
      
 43 
     | 
    
         
            +
                Gem::Builder.new( gem ).build
         
     | 
| 
      
 44 
     | 
    
         
            +
              end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
              namespace :spec do
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                desc "Update #{gem.name}.gemspec"
         
     | 
| 
      
 49 
     | 
    
         
            +
                task :generate do
         
     | 
| 
      
 50 
     | 
    
         
            +
                  File.open("#{gem.name}.gemspec", "w") do |f|
         
     | 
| 
      
 51 
     | 
    
         
            +
                    f.puts(gem.to_ruby)
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                desc "Test spec in github cleanroom"
         
     | 
| 
      
 56 
     | 
    
         
            +
                task :test => :generate do
         
     | 
| 
      
 57 
     | 
    
         
            +
                  require 'rubygems/specification'
         
     | 
| 
      
 58 
     | 
    
         
            +
                  data = File.read("#{gem.name}.gemspec")
         
     | 
| 
      
 59 
     | 
    
         
            +
                  spec = nil
         
     | 
| 
      
 60 
     | 
    
         
            +
                  Thread.new { spec = eval("$SAFE = 3\n#{data}") }.join
         
     | 
| 
      
 61 
     | 
    
         
            +
                  puts "#{spec} - Good to go!"
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
              
         
     | 
| 
      
 66 
     | 
    
         
            +
            end
         
     | 
    
        data/Readme.md
    ADDED
    
    | 
         @@ -0,0 +1,86 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Bananajour - Local git publication and collaboration
         
     | 
| 
      
 2 
     | 
    
         
            +
            ====================================================
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            Local git repository hosting with a sexy web interface and Bonjour discovery. It's like a bunch of adhoc, local, network-aware githubs!
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            Unlike Gitjour, the repositories you're serving are not your working git repositories, they're served from `~/.bananajour/repositories`. You can push to your bananajour repositories from your working copies just like you do with github.
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            Bananajour is the baby of [Tim Lucas](http://toolmantim.com/) with much railscamp hackage by [Nathan de Vries](http://github.com/atnan), [Lachlan Hardy](http://github.com/lachlanhardy), [Josh Bassett](http://github.com/nullobject), [Myles Byrne](http://github.com/quackingduck), [Ben Hoskings](http://github.com/benhoskings), [Brett Goulder](http://github.com/brettgo1), [Tony Issakov](https://github.com/tissak), and [Mark Bennett](http://github.com/MarkBennett). The rad logo was by [Carla Hackett](http://carlahackettdesign.com/). Other various fixes and contributions by [Travis Swicegood](http://github.com/tswicegood) and [Nate Haas](http://github.com/natehaas).
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            Installation and usage
         
     | 
| 
      
 13 
     | 
    
         
            +
            ----------------------
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            You'll need at least [git version 1.6](http://git-scm.com/). Run `git --version` if you're unsure.
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            Install it from github via gems:
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                gem install toolmantim-bananajour
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            (you might need to do a `gem sources -a http://gems.github.com` beforehand!)
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            Start it up:
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                bananajour
         
     | 
| 
      
 26 
     | 
    
         
            +
                
         
     | 
| 
      
 27 
     | 
    
         
            +
            Go into an existing project and add it to bananajour:
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                cd ~/code/myproj
         
     | 
| 
      
 30 
     | 
    
         
            +
                bananajour add
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            Publish your codez:
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                git push banana master
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            Fire up [http://localhost:9331/](http://localhost:9331/) to check it out.
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            If somebody starts sharing a Bananajour repository with the same name on the
         
     | 
| 
      
 39 
     | 
    
         
            +
            network it'll automatically show up in the network thanks to the wonder that is Bonjour.
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            For a list of all the commands:
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                bananajour help
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            Linux support
         
     | 
| 
      
 46 
     | 
    
         
            +
            -------------
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            To install the dnssd gem on linux you'll need [avahi](http://avahi.org/). For Ubunutu peeps this means:
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                sudo apt-get install libavahi-compat-libdnssd-dev
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            Using with Ginatra
         
     | 
| 
      
 53 
     | 
    
         
            +
            ------------------
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            Rumour has it [ginatra](http://github.com/lenary/ginatra) can be used to provide richer gitweb-like browsing of your bananajour repositories. Symlink ginatra's `repos` directory to `~/.bananajour/repositories` to serve up your bananajour repositories.
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            Official repository and support
         
     | 
| 
      
 58 
     | 
    
         
            +
            -------------------------------
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            The official repo and support issues/tickets live at [github.com/toolmantim/bananajour](http://github.com/toolmantim/bananajour).
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
            Feature and support discussions live at [groups.google.com/group/bananajour](http://groups.google.com/group/bananajour).
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            Developing
         
     | 
| 
      
 65 
     | 
    
         
            +
            ----------
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
            If you want to hack on the sinatra app then do so from a local clone but run your actual bananjour from the gem version. Running the sinatra app directly won't broadcast it onto the network and it'll run on a different port:
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                ruby sinatra/app.rb -s thin
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
            If you want code reloading use [shotgun](http://github.com/rtomayko/shotgun) instead:
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                shotgun sinatra/app.rb -s thin
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            If you then want to run your working copy as your public bananajour rebuild and install it as a gem:
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                sudo rake gem:install
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            License
         
     | 
| 
      
 80 
     | 
    
         
            +
            -------
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
            All directories and files are MIT Licensed.
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
            Warning to all those who still believe secrecy will save their revenue stream
         
     | 
| 
      
 85 
     | 
    
         
            +
            -----------------------------------------------------------------------------
         
     | 
| 
      
 86 
     | 
    
         
            +
            Bananas were meant to be shared. There are no secret bananas.
         
     | 
    
        data/bin/bananajour
    ADDED
    
    | 
         @@ -0,0 +1,58 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "rubygems"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require (File.symlink?(__FILE__) ? "bananajour" : File.join(File.dirname(__FILE__), "/../lib/bananajour"))
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            Thread.abort_on_exception = true
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            Bananajour.setup! if !Bananajour.setup?
         
     | 
| 
      
 9 
     | 
    
         
            +
            Bananajour.check_git!
         
     | 
| 
      
 10 
     | 
    
         
            +
            Bananajour.check_git_config!
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            case ARGV.first
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            when nil
         
     | 
| 
      
 15 
     | 
    
         
            +
              Bananajour.serve_web!
         
     | 
| 
      
 16 
     | 
    
         
            +
              Bananajour.serve_git!
         
     | 
| 
      
 17 
     | 
    
         
            +
              Bananajour.advertise!
         
     | 
| 
      
 18 
     | 
    
         
            +
              Process.wait
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            when "add", "init"
         
     | 
| 
      
 21 
     | 
    
         
            +
              repo = Bananajour.add!(ARGV[1] || File.expand_path("."))
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            when "remove", "rm"
         
     | 
| 
      
 24 
     | 
    
         
            +
              name = ARGV[1]
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              if !name || name.empty?
         
     | 
| 
      
 27 
     | 
    
         
            +
                abort "You need to specify the name of the repository you'd like to remove:\n#{File.basename($0)} remove <path>"
         
     | 
| 
      
 28 
     | 
    
         
            +
              elsif !(repo = Bananajour::Repository.for_name(name))
         
     | 
| 
      
 29 
     | 
    
         
            +
                abort "#{name.inspect} is not a valid repository name"
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              repo.remove!
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            when "clone"
         
     | 
| 
      
 35 
     | 
    
         
            +
              if ARGV[1].nil? || ARGV[1].empty?
         
     | 
| 
      
 36 
     | 
    
         
            +
                abort "You need to specify the path to the repository you'd like to clone:\n$ bananajour clone <path>"
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
              repo = Bananajour.clone!(ARGV[1], ARGV[2])
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            when "help", "--help", "-h"
         
     | 
| 
      
 41 
     | 
    
         
            +
              puts <<-HELP
         
     | 
| 
      
 42 
     | 
    
         
            +
            Usage: #{File.basename($0)} [<command>]
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            Commands:
         
     | 
| 
      
 45 
     | 
    
         
            +
              none               - Start the web, git and bonjour serving
         
     | 
| 
      
 46 
     | 
    
         
            +
              add [path]         - Add an existing git repo to bananajour
         
     | 
| 
      
 47 
     | 
    
         
            +
              remove <name>      - Remove a repo 
         
     | 
| 
      
 48 
     | 
    
         
            +
              clone <url> [path] - Clone a remote repo and add it to bananajour
         
     | 
| 
      
 49 
     | 
    
         
            +
              help
         
     | 
| 
      
 50 
     | 
    
         
            +
              version
         
     | 
| 
      
 51 
     | 
    
         
            +
            HELP
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            when "version", "--version", "-v"
         
     | 
| 
      
 54 
     | 
    
         
            +
              puts "bananajour version #{Bananajour::VERSION}"
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            else
         
     | 
| 
      
 57 
     | 
    
         
            +
              abort "Say what? Try: #{File.basename($0)} help"
         
     | 
| 
      
 58 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/bananajour.rb
    ADDED
    
    | 
         @@ -0,0 +1,99 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            libdir = File.dirname(__FILE__)
         
     | 
| 
      
 2 
     | 
    
         
            +
            $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require 'yaml'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'ostruct'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'socket'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'md5'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            require 'bananajour/gem_dependencies'
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            Bananajour.require_gem 'rainbow'
         
     | 
| 
      
 12 
     | 
    
         
            +
            Bananajour.require_gem 'dnssd'
         
     | 
| 
      
 13 
     | 
    
         
            +
            Bananajour.require_gem 'chrislloyd-fancypath', 'fancypath'
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            require 'bananajour/repository'
         
     | 
| 
      
 16 
     | 
    
         
            +
            require 'bananajour/grit_extensions'
         
     | 
| 
      
 17 
     | 
    
         
            +
            require 'bananajour/version'
         
     | 
| 
      
 18 
     | 
    
         
            +
            require 'bananajour/bonjour'
         
     | 
| 
      
 19 
     | 
    
         
            +
            require 'bananajour/helpers'
         
     | 
| 
      
 20 
     | 
    
         
            +
            require 'bananajour/commands'
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            module Bananajour
         
     | 
| 
      
 23 
     | 
    
         
            +
              
         
     | 
| 
      
 24 
     | 
    
         
            +
              class << self
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                include DateHelpers
         
     | 
| 
      
 27 
     | 
    
         
            +
                include GravatarHelpers
         
     | 
| 
      
 28 
     | 
    
         
            +
                include Commands
         
     | 
| 
      
 29 
     | 
    
         
            +
                
         
     | 
| 
      
 30 
     | 
    
         
            +
                def setup?
         
     | 
| 
      
 31 
     | 
    
         
            +
                  repositories_path.exists?
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
                
         
     | 
| 
      
 34 
     | 
    
         
            +
                def setup!
         
     | 
| 
      
 35 
     | 
    
         
            +
                  repositories_path.create_dir
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
                
         
     | 
| 
      
 38 
     | 
    
         
            +
                def path
         
     | 
| 
      
 39 
     | 
    
         
            +
                  Fancypath("~/.bananajour").expand_path
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
                
         
     | 
| 
      
 42 
     | 
    
         
            +
                def repositories_path
         
     | 
| 
      
 43 
     | 
    
         
            +
                  path/"repositories"
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                def get_git_global_config(key)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  `git config --global #{key}`.strip
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
                
         
     | 
| 
      
 50 
     | 
    
         
            +
                def config
         
     | 
| 
      
 51 
     | 
    
         
            +
                  @config ||= begin
         
     | 
| 
      
 52 
     | 
    
         
            +
                    OpenStruct.new({
         
     | 
| 
      
 53 
     | 
    
         
            +
                      :name => get_git_global_config("user.name"),
         
     | 
| 
      
 54 
     | 
    
         
            +
                      :email => get_git_global_config("user.email")
         
     | 
| 
      
 55 
     | 
    
         
            +
                    })
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
                
         
     | 
| 
      
 59 
     | 
    
         
            +
                def web_port
         
     | 
| 
      
 60 
     | 
    
         
            +
                  9331
         
     | 
| 
      
 61 
     | 
    
         
            +
                end
         
     | 
| 
      
 62 
     | 
    
         
            +
                
         
     | 
| 
      
 63 
     | 
    
         
            +
                def web_uri
         
     | 
| 
      
 64 
     | 
    
         
            +
                  "http://#{host_name}:#{web_port}/"
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
                
         
     | 
| 
      
 67 
     | 
    
         
            +
                def host_name
         
     | 
| 
      
 68 
     | 
    
         
            +
                  Socket.gethostname
         
     | 
| 
      
 69 
     | 
    
         
            +
                end
         
     | 
| 
      
 70 
     | 
    
         
            +
                
         
     | 
| 
      
 71 
     | 
    
         
            +
                def git_uri
         
     | 
| 
      
 72 
     | 
    
         
            +
                  "git://#{host_name}/"
         
     | 
| 
      
 73 
     | 
    
         
            +
                end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                def repositories
         
     | 
| 
      
 76 
     | 
    
         
            +
                  repositories_path.children.map {|r| Repository.new(r)}.sort_by {|r| r.name}
         
     | 
| 
      
 77 
     | 
    
         
            +
                end
         
     | 
| 
      
 78 
     | 
    
         
            +
                
         
     | 
| 
      
 79 
     | 
    
         
            +
                def repository(name)
         
     | 
| 
      
 80 
     | 
    
         
            +
                  repositories.find {|r| r.name == name}
         
     | 
| 
      
 81 
     | 
    
         
            +
                end
         
     | 
| 
      
 82 
     | 
    
         
            +
                
         
     | 
| 
      
 83 
     | 
    
         
            +
                def to_hash
         
     | 
| 
      
 84 
     | 
    
         
            +
                  {
         
     | 
| 
      
 85 
     | 
    
         
            +
                    "name" => config.name,
         
     | 
| 
      
 86 
     | 
    
         
            +
                    "email" => config.email,
         
     | 
| 
      
 87 
     | 
    
         
            +
                    "uri"  => web_uri,
         
     | 
| 
      
 88 
     | 
    
         
            +
                    "git-uri" => git_uri,
         
     | 
| 
      
 89 
     | 
    
         
            +
                    "gravatar" => Bananajour.gravatar,
         
     | 
| 
      
 90 
     | 
    
         
            +
                    "version" => Bananajour::VERSION,
         
     | 
| 
      
 91 
     | 
    
         
            +
                    "repositories" => repositories.collect do |r|
         
     | 
| 
      
 92 
     | 
    
         
            +
                      {"name" => r.name, "uri" => r.uri}
         
     | 
| 
      
 93 
     | 
    
         
            +
                    end
         
     | 
| 
      
 94 
     | 
    
         
            +
                  }
         
     | 
| 
      
 95 
     | 
    
         
            +
                end
         
     | 
| 
      
 96 
     | 
    
         
            +
                
         
     | 
| 
      
 97 
     | 
    
         
            +
              end
         
     | 
| 
      
 98 
     | 
    
         
            +
              
         
     | 
| 
      
 99 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,9 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Bananajour::Bonjour
         
     | 
| 
      
 2 
     | 
    
         
            +
            end
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require 'bananajour/bonjour/person'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'bananajour/bonjour/repository'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'bananajour/bonjour/browser'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'bananajour/bonjour/repository_browser'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require 'bananajour/bonjour/bananajour_browser'
         
     | 
| 
      
 9 
     | 
    
         
            +
            require 'bananajour/bonjour/advertiser'
         
     | 
| 
         @@ -0,0 +1,57 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Bananajour::Bonjour::Advertiser
         
     | 
| 
      
 2 
     | 
    
         
            +
              def initialize
         
     | 
| 
      
 3 
     | 
    
         
            +
                @services = []
         
     | 
| 
      
 4 
     | 
    
         
            +
              end
         
     | 
| 
      
 5 
     | 
    
         
            +
              def go!
         
     | 
| 
      
 6 
     | 
    
         
            +
                register_app
         
     | 
| 
      
 7 
     | 
    
         
            +
                register_repos
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
              private
         
     | 
| 
      
 10 
     | 
    
         
            +
                def register_app
         
     | 
| 
      
 11 
     | 
    
         
            +
                  STDOUT.puts "Registering #{Bananajour.web_uri}"
         
     | 
| 
      
 12 
     | 
    
         
            +
                  tr = DNSSD::TextRecord.new
         
     | 
| 
      
 13 
     | 
    
         
            +
                  tr["name"] = Bananajour.config.name
         
     | 
| 
      
 14 
     | 
    
         
            +
                  tr["email"] = Bananajour.config.email
         
     | 
| 
      
 15 
     | 
    
         
            +
                  tr["uri"] = Bananajour.web_uri
         
     | 
| 
      
 16 
     | 
    
         
            +
                  tr["gravatar"] = Bananajour.gravatar
         
     | 
| 
      
 17 
     | 
    
         
            +
                  tr["version"] = Bananajour::VERSION
         
     | 
| 
      
 18 
     | 
    
         
            +
                  DNSSD.register("#{Bananajour.config.name}'s bananajour", "_http._tcp,_bananajour", nil, Bananajour.web_port, tr) {}
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
                def register_repos
         
     | 
| 
      
 21 
     | 
    
         
            +
                  loop do
         
     | 
| 
      
 22 
     | 
    
         
            +
                    stop_old_services
         
     | 
| 
      
 23 
     | 
    
         
            +
                    register_new_repositories
         
     | 
| 
      
 24 
     | 
    
         
            +
                    sleep(1)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
                def stop_old_services
         
     | 
| 
      
 28 
     | 
    
         
            +
                  old_services.each do |old_service|
         
     | 
| 
      
 29 
     | 
    
         
            +
                    STDOUT.puts "Unregistering #{old_service.repository.uri}"
         
     | 
| 
      
 30 
     | 
    
         
            +
                    old_service.stop
         
     | 
| 
      
 31 
     | 
    
         
            +
                    @services.delete(old_service)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
                def old_services
         
     | 
| 
      
 35 
     | 
    
         
            +
                  @services.reject {|s| Bananajour.repositories.include?(s.repository)}
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
                def register_new_repositories
         
     | 
| 
      
 38 
     | 
    
         
            +
                  new_repositories.each do |new_repo|
         
     | 
| 
      
 39 
     | 
    
         
            +
                    STDOUT.puts "Registering #{new_repo.uri}"
         
     | 
| 
      
 40 
     | 
    
         
            +
                    tr = DNSSD::TextRecord.new
         
     | 
| 
      
 41 
     | 
    
         
            +
                    tr["name"] = new_repo.name
         
     | 
| 
      
 42 
     | 
    
         
            +
                    tr["uri"] = new_repo.uri
         
     | 
| 
      
 43 
     | 
    
         
            +
                    tr["bjour-name"] = Bananajour.config.name
         
     | 
| 
      
 44 
     | 
    
         
            +
                    tr["bjour-email"] = Bananajour.config.email
         
     | 
| 
      
 45 
     | 
    
         
            +
                    tr["bjour-uri"] = Bananajour.web_uri
         
     | 
| 
      
 46 
     | 
    
         
            +
                    tr["bjour-gravatar"] = Bananajour.gravatar
         
     | 
| 
      
 47 
     | 
    
         
            +
                    tr["bjour-version"] = Bananajour::VERSION
         
     | 
| 
      
 48 
     | 
    
         
            +
                    service = DNSSD.register(new_repo.name, "_git._tcp,_bananajour", nil, 9418, tr) {}
         
     | 
| 
      
 49 
     | 
    
         
            +
                    service.class.instance_eval { attr_accessor(:repository) }
         
     | 
| 
      
 50 
     | 
    
         
            +
                    service.repository = new_repo
         
     | 
| 
      
 51 
     | 
    
         
            +
                    @services << service
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
                def new_repositories
         
     | 
| 
      
 55 
     | 
    
         
            +
                  Bananajour.repositories.select {|repo| !@services.any? {|s| s.repository == repo } }
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Bananajour::Bonjour
         
     | 
| 
      
 2 
     | 
    
         
            +
            class BananajourBrowser
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              def initialize
         
     | 
| 
      
 5 
     | 
    
         
            +
                @browser = Browser.new('_bananajour._http._tcp')
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
              
         
     | 
| 
      
 8 
     | 
    
         
            +
              def bananajours
         
     | 
| 
      
 9 
     | 
    
         
            +
                @browser.replies.map do |reply|
         
     | 
| 
      
 10 
     | 
    
         
            +
                  Person.new(
         
     | 
| 
      
 11 
     | 
    
         
            +
                    reply.text_record["name"],
         
     | 
| 
      
 12 
     | 
    
         
            +
                    reply.text_record["email"],
         
     | 
| 
      
 13 
     | 
    
         
            +
                    reply.text_record["uri"],
         
     | 
| 
      
 14 
     | 
    
         
            +
                    reply.text_record["gravatar"]
         
     | 
| 
      
 15 
     | 
    
         
            +
                  )
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
              
         
     | 
| 
      
 19 
     | 
    
         
            +
              def other_bananajours
         
     | 
| 
      
 20 
     | 
    
         
            +
                bananajours.reject {|b| b.uri == Bananajour.web_uri}
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
              
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,52 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Bananajour.require_gem 'dnssd'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'thread'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'timeout'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            Thread.abort_on_exception = true
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            # Generic bonjour browser
         
     | 
| 
      
 9 
     | 
    
         
            +
            #
         
     | 
| 
      
 10 
     | 
    
         
            +
            # Example use:
         
     | 
| 
      
 11 
     | 
    
         
            +
            # 
         
     | 
| 
      
 12 
     | 
    
         
            +
            #   browser = BonjourBrowser.new("_bananajour._git._tcp")
         
     | 
| 
      
 13 
     | 
    
         
            +
            #   loop do
         
     | 
| 
      
 14 
     | 
    
         
            +
            #     sleep(1)
         
     | 
| 
      
 15 
     | 
    
         
            +
            #     pp browser.replies.map {|r| r.name}
         
     | 
| 
      
 16 
     | 
    
         
            +
            #   end
         
     | 
| 
      
 17 
     | 
    
         
            +
            #
         
     | 
| 
      
 18 
     | 
    
         
            +
            # Probably gem-worthy
         
     | 
| 
      
 19 
     | 
    
         
            +
            class Bananajour::Bonjour::Browser
         
     | 
| 
      
 20 
     | 
    
         
            +
              attr_reader :replies
         
     | 
| 
      
 21 
     | 
    
         
            +
              def initialize(service)
         
     | 
| 
      
 22 
     | 
    
         
            +
                @service = service
         
     | 
| 
      
 23 
     | 
    
         
            +
                @mutex = Mutex.new
         
     | 
| 
      
 24 
     | 
    
         
            +
                @replies = []
         
     | 
| 
      
 25 
     | 
    
         
            +
                watch!
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
              private
         
     | 
| 
      
 28 
     | 
    
         
            +
                def watch!
         
     | 
| 
      
 29 
     | 
    
         
            +
                  DNSSD.browse(@service) do |br|
         
     | 
| 
      
 30 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 31 
     | 
    
         
            +
                      Timeout.timeout(5) do
         
     | 
| 
      
 32 
     | 
    
         
            +
                        DNSSD.resolve(br.name, br.type, br.domain) do |rr|
         
     | 
| 
      
 33 
     | 
    
         
            +
                          begin
         
     | 
| 
      
 34 
     | 
    
         
            +
                            @mutex.synchronize do
         
     | 
| 
      
 35 
     | 
    
         
            +
                              rr_exists = Proc.new {|existing_rr| existing_rr.target == rr.target && existing_rr.fullname == rr.fullname}
         
     | 
| 
      
 36 
     | 
    
         
            +
                              if (DNSSD::Flags::Add & br.flags.to_i) != 0
         
     | 
| 
      
 37 
     | 
    
         
            +
                                @replies << rr unless @replies.any?(&rr_exists)
         
     | 
| 
      
 38 
     | 
    
         
            +
                              else
         
     | 
| 
      
 39 
     | 
    
         
            +
                                @replies.delete_if(&rr_exists)
         
     | 
| 
      
 40 
     | 
    
         
            +
                              end
         
     | 
| 
      
 41 
     | 
    
         
            +
                            end
         
     | 
| 
      
 42 
     | 
    
         
            +
                          ensure
         
     | 
| 
      
 43 
     | 
    
         
            +
                            rr.service.stop
         
     | 
| 
      
 44 
     | 
    
         
            +
                          end
         
     | 
| 
      
 45 
     | 
    
         
            +
                        end
         
     | 
| 
      
 46 
     | 
    
         
            +
                      end
         
     | 
| 
      
 47 
     | 
    
         
            +
                    rescue Timeout::Error
         
     | 
| 
      
 48 
     | 
    
         
            +
                      # Do nothing
         
     | 
| 
      
 49 
     | 
    
         
            +
                    end
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
            end
         
     |