Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Sven Fuchs committed Mar 26, 2012
0 parents commit 8c6af63
Show file tree
Hide file tree
Showing 20 changed files with 421 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Gemfile
@@ -0,0 +1,4 @@
source :rubygems

gem 'ansi'
gem 'hashr'
6 changes: 6 additions & 0 deletions bin/space
@@ -0,0 +1,6 @@
#!/usr/bin/env ruby

$: << 'lib'
require 'space'

Space::App.new.run
13 changes: 13 additions & 0 deletions lib/core_ext/enumerable.rb
@@ -0,0 +1,13 @@
module Enumerable
def map_with_index(&block)
result = []
each_with_index { |element, ix| result << yield(element, ix) }
result
end

def map_slice(num, &block)
result = []
each_slice(num) { |element| result << yield(element) }
result
end
end
7 changes: 7 additions & 0 deletions lib/core_ext/string.rb
@@ -0,0 +1,7 @@
class String
def wrap(width)
gsub(/(.{1,#{width}})( +|$\n?)|(.{1,#{width}})/, "\\1\\3\n")
end
end


23 changes: 23 additions & 0 deletions lib/space.rb
@@ -0,0 +1,23 @@
require 'yaml'
require 'hashr'
require 'core_ext/enumerable'

module Space
autoload :App, 'space/app'
autoload :Helpers, 'space/helpers'
autoload :Bundle, 'space/models/bundle'
autoload :Commands, 'space/models/commands'
autoload :Command, 'space/models/command'
autoload :Dependency, 'space/models/dependency'
autoload :Git, 'space/models/git'
autoload :Repos, 'space/models/repos'
autoload :Repo, 'space/models/repo'
autoload :Screen, 'space/screen'
autoload :System, 'space/system'
autoload :View, 'space/view'

TEMPLATES = {
:project => 'templates/project.erb',
:repo => 'templates/repository.erb'
}
end
49 changes: 49 additions & 0 deletions lib/space/app.rb
@@ -0,0 +1,49 @@
require 'readline'

module Space
class App
class Config < Hashr
def paths
@paths ||= repositories.map { |path| "#{base_dir}/#{path}" }
end
end

include Readline

attr_reader :screen, :name, :config, :repos, :bundle

def initialize
@screen = Screen.new(self)
@config = Config.new(YAML.load(File.read('space.yml')))
@name = config.name
@repos = Repos.new(self)
@bundle = Bundle.new(self, config.paths.first)
end

def run
screen.render
loop do
line = readline('huzzar > ', true)
break if line.nil?
handle(line) unless line.empty?
end
puts
end

def handle(line)
action = parse(line)
# action.run
screen.render
end

def parse(line)
line =~ /(\S+) (.+)/
name, command = $1, $2
repo = repos.detect { |repo| repo.name == name }
case $2
when 'reload'
repo.reset
end
end
end
end
43 changes: 43 additions & 0 deletions lib/space/helpers.rb
@@ -0,0 +1,43 @@
# encoding: UTF-8
require 'ansi/core'
require 'core_ext/string'

module Space
module Helpers
def project_title
"Project: #{app.name}".ansi(:bold)
end

def git_status
"Git: #{format_boolean(git.clean?)}"
end

def bundle_status
"Bundle: #{format_boolean(bundle.clean?)}"
end

def bundle_info
"#{bundle.info}\n" unless bundle.clean?
end

def bundle_deps
bundle.deps.map { |dep| "• #{dep.ref} #{format_boolean(dep.fresh?)} #{dep.name}" }.join("\n")
end

def bundle_local
repos = bundle.local_repos
"\nLocal: #{repos.join(', ')}\n" unless repos.empty?
end

def format_boolean(value)
value ? '✔'.ansi(:green, :bold) : '⚡'.ansi(:red, :bold)
end

def i(string)
lines = string.split("\n")
lines = lines.map { |line| line.wrap(80).split("\n") }.flatten
lines = lines.map { |line| " #{line}" }
lines.join("\n")
end
end
end
50 changes: 50 additions & 0 deletions lib/space/models/bundle.rb
@@ -0,0 +1,50 @@
module Space
class Bundle
include Commands

COMMANDS = {
:check => 'bundle check',
:list => 'bundle list',
:config => 'bundle config --global'
}

attr_reader :app

def initialize(app, path)
@app = app
super(path)
end

def clean?
info =~ /dependencies are satisfied/
end

def info
result(:check).split("\n").first
end

def deps
@deps ||= result(:list).split("\n").map do |dep|
names = app.repos.map { |repo| repo.name }
dep =~ /(#{app.name}.*) \(\d\.\d\.\d (.+)\)/
Dependency.new(app, $1, $2) if names.include?($1)
end.compact
end

def local_repos
@local_repos ||= config.keys.map do |key|
key =~ /^local\.(.+)$/ && $1
end.compact
end

def config
@config ||= begin
lines = result(:config).split("\n")[2..-1]
values = lines.map_slice(3) do |name, value, _|
[name, value =~ /: "(.*)"/ && $1]
end
Hash[*values.compact.flatten]
end
end
end
end
26 changes: 26 additions & 0 deletions lib/space/models/command.rb
@@ -0,0 +1,26 @@
module Space
class Command
attr_reader :path, :command

def initialize(path, command)
@path = File.expand_path(path)
@command = command
end

def result
@result ||= chdir { strip_ansi(`#{command}`) }
end

def reset
@result = nil
end

def chdir(&block)
Dir.chdir(path, &block)
end

def strip_ansi(string)
string.gsub(/\e\[\d+m/, '')
end
end
end
23 changes: 23 additions & 0 deletions lib/space/models/commands.rb
@@ -0,0 +1,23 @@
module Space
module Commands
attr_reader :path

def initialize(path)
@path = path
end

def result(command)
commands[command].result
end

def commands
@commands ||= Hash[*self.class::COMMANDS.map do |key, cmd|
[key, Command.new(path, cmd)]
end.flatten]
end

def reset
commands.each { |key, command| command.reset }
end
end
end
19 changes: 19 additions & 0 deletions lib/space/models/dependency.rb
@@ -0,0 +1,19 @@
module Space
class Dependency
attr_reader :app, :name, :ref

def initialize(app, name, ref)
@app = app
@name = name
@ref = ref
end

def fresh?
repo.ref == ref
end

def repo
app.repos.detect { |repo| repo.name == name }
end
end
end
23 changes: 23 additions & 0 deletions lib/space/models/git.rb
@@ -0,0 +1,23 @@
module Space
class Git
include Commands

COMMANDS = {
:status => 'git status -s',
:branch => 'git branch --no-color',
:commit => 'git log -1 head'
}

def clean?
result(:status).empty?
end

def branch
result(:branch) =~ /^\* (.+)/ && $1.strip
end

def commit
result(:commit) =~ /^commit (\S{7})/ && $1
end
end
end
26 changes: 26 additions & 0 deletions lib/space/models/repo.rb
@@ -0,0 +1,26 @@
module Space
class Repo
attr_reader :app, :num, :path, :git, :bundle

def initialize(app, num, path)
@app = app
@num = num
@path = File.expand_path(path)
@git = Git.new(path)
@bundle = Bundle.new(app, path)
end

def name
@name ||= File.basename(path)
end

def ref
git.commit
end

def reset
git.reset
bundle.reset
end
end
end
19 changes: 19 additions & 0 deletions lib/space/models/repos.rb
@@ -0,0 +1,19 @@
module Space
class Repos
include Enumerable

attr_reader :app

def initialize(app)
@app = app
end

def each(&block)
all.each(&block)
end

def all
@all ||= app.config.paths.map_with_index { |path, ix| Repo.new(app, ix, path) }
end
end
end
25 changes: 25 additions & 0 deletions lib/space/screen.rb
@@ -0,0 +1,25 @@
module Space
class Screen
attr_reader :app

def initialize(app)
@app = app
end

def render
system 'clear'
puts render_project
app.repos.each { |repo| puts render_repo(repo) }
end

private

def render_project
View.new.render(:project, :app => app, :bundle => app.bundle)
end

def render_repo(repo)
View.new.render(:repo, :repo => repo, :git => repo.git, :bundle => repo.bundle)
end
end
end
21 changes: 21 additions & 0 deletions lib/space/system.rb
@@ -0,0 +1,21 @@
module Space
module System
attr_reader :path

def initialize(path = '~')
@path = File.expand_path(path)
end

def run(cmd)
chdir { `#{cmd}` }
end

def chdir(&block)
Dir.chdir(path, &block)
end

def strip_ansi(string)
string.gsub(/\e\[\d+m/, '')
end
end
end

0 comments on commit 8c6af63

Please sign in to comment.