Browse files

documentation updates and real command-line parsing

  • Loading branch information...
1 parent 2710be5 commit 701f27ee575e44985a1fa8476c3a7383b32b9fcd @technomancy committed Jul 24, 2008
Showing with 77 additions and 43 deletions.
  1. +23 −6 README.rdoc
  2. +8 −3 Rakefile
  3. +9 −3 bin/conspire
  4. +11 −12 lib/conspire.rb
  5. +10 −6 lib/conspire/conspirator.rb
  6. +4 −3 lib/conspire/gitjour_exts.rb
  7. +2 −1 lib/conspire/support/conspire.el
  8. +10 −9 test/test_conspire.rb
View
29 README.rdoc
@@ -5,23 +5,38 @@
Conspire is a real-time collaborative editing platform using Git as a
transport layer.
-You don't actually use Conspire directly; you would invoke it through
-an editor interface. See lib/conspire/support to see which editors are
-supported.
-
== Installation
You'll need git 1.5.5 or higher.
TODO: instructions for avahi-compatible dnssd from source.
+TODO: make latest gitjour available as a gem
-* sudo gem install net-mdns
+* sudo gem install dnssd newgem
+* git clone git://github.com/chad/gitjour.git; cd gitjour; rake install_gem
* sudo gem install technomancy-conspire --source=http://gems.github.com
Once a proper release has happened:
* sudo gem install conspire
+== Usage
+
+Conspiracy sessions operate around repositories rather than single
+files like other collaborative editors. So launch +conspire+ with a
+directory as its first argument to have it initialize a repository in
+that directory. From there you should open up your editor and invoke
+conspire from there.
+
+TODO: you still have to manually <tt>git add</tt> files at first.
+
+See lib/conspire/support to see which editors are supported.
+
+When using Avahi for your ZeroConf implementation, you will not be
+able to do anything unless you have an active network connection. So
+disconnected conspirancy sessions on the same machine are not possible
+without bringing up an ad-hoc network.
+
== Editor Support
Editors must support:
@@ -30,4 +45,6 @@ Editors must support:
* Committing files to the repo
* Refreshing internal copies
-Edits should not be allowed in between these steps.
+Edits should not be allowed in between these steps.
+
+Editors should be able to support launching the +conspire+ executable.
View
11 Rakefile
@@ -7,9 +7,14 @@ require './lib/conspire.rb'
Hoe.new('conspire', Conspire::VERSION) do |p|
p.developer('Phil Hagelberg', 'technomancy@gmail.com')
- # Get these from github:
- # TODO: currently have to build manually; no gem built
- p.extra_deps << 'chad-gitjour'
+ p.extra_deps << ['gitjour', '6.3.0']
+ p.extra_deps << 'clip'
+end
+
+desc "Code statistics"
+task :stats do
+ require 'code_statistics'
+ CodeStatistics.new(['lib'], ['Unit tests', 'test']).to_s
end
# vim: syntax=Ruby
View
12 bin/conspire
@@ -1,10 +1,16 @@
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../lib/conspire'
+require 'clip'
-# TODO: real option parsing
-Conspire.start(:port => ARGV.shift || Conspire::DEFAULT_OPTIONS[:port],
- :name => ARGV.shift || Conspire::DEFAULT_OPTIONS[:name])
+options = Clip do |c|
+ c.optional 'p', 'port', :default => Conspire::DEFAULTS[:port]
+ c.optional('s', 'sync_interval', :desc => 'Time between synchronizing repos',
+ :default => Conspire::DEFAULTS[:sync_interval])
+ c.optional('n', 'name', :desc => "Session name; must include 'conspiracy'",
+ :default => Conspire::DEFAULTS[:name])
+end
+Conspire.start ARGV.first, options
Thread.new { Conspire.discover_loop }
Conspire.sync_loop
View
23 lib/conspire.rb
@@ -3,36 +3,35 @@
require 'fileutils'
require 'rubygems'
-require 'gitjour'
+require 'gitjour' # TODO: can we get rid of the avahi compatibility warning?
require 'conspire/gitjour_exts'
require 'conspire/conspirator'
module Conspire
VERSION = '0.0.1'
- DEFAULT_OPTIONS = { :port => 7456, :path => Dir.pwd, :name => 'conspiracy',
- :discover_interval => 10, :sync_interval => 1 }
+ DEFAULTS = { :port => 7456, :name => 'conspiracy', :sync_interval => 0.5 }
@conspirators = Set.new
module_function
# Begin a conspiracy session
- def start(options = {})
- @options = DEFAULT_OPTIONS.merge options
+ def start(path, options)
+ @options = options
+ @path = path
puts "Starting with #{@options.inspect}" if ENV['DEBUG']
- Gitjour::Application.init @options[:path]
+ Gitjour::Application.init @path
@thread = Thread.new do
- Gitjour::Application.serve(@options[:path], @options[:name],
- @options[:port])
+ Gitjour::Application.serve(@path, @options.name, @options.port)
end
end
# This should be called periodically
- def discover(wait = @options[:discover_interval])
+ def discover(wait = 5)
Gitjour::Application.discover(wait) do |service|
next if service.name !~ /conspiracy/ # TODO: better way of choosing names
- next if service.port.to_i == @options[:port].to_i # TODO: and local
+ next if service.port.to_i == @options.port.to_i # TODO: and local
# No-op if we've got it already, since @conspirators is a Set
@conspirators << Conspirator.new(service.host, service.port, service.name)
@@ -42,7 +41,7 @@ def discover(wait = @options[:discover_interval])
def sync_all
@conspirators.map do |c|
begin
- c.sync(@options[:path])
+ c.sync(@path)
rescue => e
puts "Dropping #{c} because #{e.message}"
@conspirators.delete c
@@ -51,7 +50,7 @@ def sync_all
end
def sync_loop
- loop { sync_all and sleep @options[:sync_interval] }
+ loop { sync_all and sleep @options.sync_interval }
end
def discover_loop
View
16 lib/conspire/conspirator.rb
@@ -2,15 +2,19 @@ module Conspire
class Conspirator
attr_accessor :last_synced, :host, :port, :name
- def initialize(host, port, name = SERVICE_NAME)
- @host, @port, @name = host[0 .. -2], port || DEFAULT_OPTIONS[:port], name
+ def initialize(host, port, name = DEFAULTS[:name])
+ @host, @port, @name = host[0 .. -2], port || DEFAULTS[:port], name
end
def sync(path)
- # TODO: suppress output
- puts "cd #{path} && git pull --rebase #{url}" if ENV['DEBUG']
- system "cd #{path} && git pull --rebase #{url}" or
- raise "Could not rebase from #{url}"
+ if ENV['DEBUG']
+ puts "cd #{path} && git pull --rebase #{url}"
+ system "cd #{path} && git pull --rebase #{url}" or
+ raise "Could not rebase from #{url}"
+ else
+ system "cd #{path} && git pull --rebase #{url} > /dev/null" or
+ raise "Could not rebase from #{url}"
+ end
@last_synced = Time.now
end
View
7 lib/conspire/gitjour_exts.rb
@@ -1,13 +1,14 @@
module Gitjour
class Application
class << self
+ public :discover, :serve
+
def init(path)
- FileUtils.mkdir_p(path) unless File.exist? path
- `cd #{path}; git init` if ! File.exist? path + '/.git'
+ abort "Repository already exists: #{path}" if File.exist? path + '/.git'
+ `mkdir -p #{path} && cd #{path} && git init`
`touch #{path}/.git/git-daemon-export-ok`
end
- public :discover, :serve
def puts(*args); end unless ENV['DEBUG']
end
end
View
3 lib/conspire/support/conspire.el
@@ -37,6 +37,8 @@
;; session and then switch buffers, since the timer is not yet buffer
;; local. Watch out!
+;; Launch conspire executable.
+
;;; Code:
(defvar conspire-interval 0.33
@@ -60,5 +62,4 @@
buffer-file-name)))
(revert-buffer nil t))
-
;;; conspire.el ends here
View
19 test/test_conspire.rb
@@ -4,6 +4,7 @@
rescue LoadError; end
require 'test/unit'
+require 'ostruct'
require File.dirname(__FILE__) + '/../lib/conspire'
REMOTE_SPACE = File.dirname(__FILE__) + '/remote-space'
@@ -18,15 +19,15 @@ def self.reset!
class TestConspire < Test::Unit::TestCase
def setup
- FileUtils.mkdir_p(REMOTE_SPACE)
+ Gitjour::Application.init(REMOTE_SPACE)
File.open(REMOTE_SPACE + '/file', 'w') { |f| f.puts "hello world." }
- `cd #{REMOTE_SPACE}; git init; git add file; git commit -m "init"`
+ `cd #{REMOTE_SPACE}; git add file; git commit -m "init"`
@remote_thread = Thread.new do
- Gitjour::Application.serve(REMOTE_SPACE, Conspire::SERVICE_NAME, 7458)
+ Gitjour::Application.serve(REMOTE_SPACE, 'conspiracy-remote-test', 7458)
end
- Conspire.start(:port => 7457, :path => LOCAL_SPACE)
+ Conspire.start(LOCAL_SPACE, OpenStruct.new(:port => 7457))
end
def teardown
@@ -43,16 +44,16 @@ def test_discover
end
def test_sync
- Conspire.conspirators << Conspire::Conspirator.new('dynabook', '7458')
+ Conspire.conspirators << Conspire::Conspirator.new('localhost.', '7458')
Conspire.sync_all
assert_equal ["#{LOCAL_SPACE}/file"], Dir.glob("#{LOCAL_SPACE}/*")
end
def test_conspirator_set
- Conspire.conspirators << Conspire::Conspirator.new('dynabook', '7458')
- Conspire.conspirators << Conspire::Conspirator.new('dynabook', '7458')
- Conspire.conspirators << Conspire::Conspirator.new('dynabook', '7458')
- Conspire.conspirators << Conspire::Conspirator.new('dynabook', '7458')
+ Conspire.conspirators << Conspire::Conspirator.new('dynabook.', '7458')
+ Conspire.conspirators << Conspire::Conspirator.new('dynabook.', '7458')
+ Conspire.conspirators << Conspire::Conspirator.new('dynabook.', '7458')
+ Conspire.conspirators << Conspire::Conspirator.new('dynabook.', '7458')
assert_equal 1, Conspire.conspirators.size
end
end

0 comments on commit 701f27e

Please sign in to comment.