space 0.0.5 → 0.0.6
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/bin/space +6 -0
- data/lib/core_ext/string/deansi.rb +7 -0
- data/lib/core_ext/string/demodulize.rb +5 -0
- data/lib/space.rb +4 -4
- data/lib/space/action.rb +43 -0
- data/lib/space/action/builtin.rb +43 -0
- data/lib/space/action/development.rb +56 -0
- data/lib/space/{app → action}/handler.rb +17 -9
- data/lib/space/{app → action}/parser.rb +4 -7
- data/lib/space/app.rb +14 -30
- data/lib/space/events.rb +27 -20
- data/lib/space/events/sources.rb +34 -0
- data/lib/space/events/subscription.rb +23 -0
- data/lib/space/logger.rb +34 -0
- data/lib/space/model.rb +7 -0
- data/lib/space/{models → model}/project.rb +4 -10
- data/lib/space/{models → model}/project/bundler.rb +7 -8
- data/lib/space/model/project/bundler/config.rb +30 -0
- data/lib/space/model/repo.rb +38 -0
- data/lib/space/{models → model}/repo/bundle.rb +6 -7
- data/lib/space/{models → model}/repo/dependency.rb +1 -1
- data/lib/space/{models → model}/repo/git.rb +14 -16
- data/lib/space/{models → model}/repos.rb +18 -9
- data/lib/space/{models → model}/repos/collection.rb +1 -1
- data/lib/space/{models → model}/repos/scope.rb +1 -1
- data/lib/space/screen.rb +28 -11
- data/lib/space/screen/dashboard.rb +21 -5
- data/lib/space/screen/progress.rb +16 -5
- data/lib/space/screen/view.rb +2 -6
- data/lib/space/source.rb +51 -0
- data/lib/space/source/command.rb +70 -0
- data/lib/space/source/watch.rb +64 -0
- data/lib/space/source/watcher.rb +32 -0
- data/lib/space/version.rb +1 -1
- metadata +27 -24
- data/lib/space/app/command.rb +0 -45
- data/lib/space/app/command/builtin.rb +0 -43
- data/lib/space/app/command/development.rb +0 -60
- data/lib/space/app/logger.rb +0 -21
- data/lib/space/events/buffer.rb +0 -18
- data/lib/space/events/event.rb +0 -14
- data/lib/space/models.rb +0 -7
- data/lib/space/models/repo.rb +0 -57
- data/lib/space/shell.rb +0 -56
- data/lib/space/shell/command.rb +0 -63
- data/lib/space/shell/watch.rb +0 -50
- data/lib/space/shell/watcher.rb +0 -40
@@ -0,0 +1,23 @@
|
|
1
|
+
module Space
|
2
|
+
module Events
|
3
|
+
class Subscription
|
4
|
+
attr_reader :observer, :types
|
5
|
+
|
6
|
+
def initialize(observer, types)
|
7
|
+
@observer = observer
|
8
|
+
@types = types
|
9
|
+
end
|
10
|
+
|
11
|
+
def notify(event)
|
12
|
+
observer.notify(event) if matches?(event)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def matches?(event)
|
18
|
+
# log [observer.class, types, event].inspect
|
19
|
+
types.empty? || types.include?(event)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/space/logger.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Kernel
|
5
|
+
def log(*msgs)
|
6
|
+
$logger.log(*msgs)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module Space
|
11
|
+
class Logger < ::Logger
|
12
|
+
def initialize(path)
|
13
|
+
truncate
|
14
|
+
super
|
15
|
+
self.formatter = ->(severity, datetime, progname, msg) { "#{msg}\n" }
|
16
|
+
end
|
17
|
+
|
18
|
+
def log(*msgs)
|
19
|
+
msgs.each do |msg|
|
20
|
+
info msg.is_a?(Array) ? msg.join("\n") : msg
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def truncate
|
25
|
+
File.open(filename, 'w+') { |f| f.write('-' * 80 + "\n") }
|
26
|
+
end
|
27
|
+
|
28
|
+
def filename
|
29
|
+
'/tmp/space.log'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
$logger = Space::Logger.new('/tmp/space.log')
|
data/lib/space/model.rb
ADDED
@@ -1,9 +1,9 @@
|
|
1
1
|
module Space
|
2
|
-
module
|
2
|
+
module Model
|
3
3
|
class Project
|
4
|
-
|
4
|
+
autoload :Bundler, 'space/model/project/bundler'
|
5
5
|
|
6
|
-
|
6
|
+
include Events
|
7
7
|
|
8
8
|
attr_reader :name, :repos, :bundler, :config
|
9
9
|
|
@@ -35,13 +35,7 @@ module Space
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def refresh
|
38
|
-
bundler.refresh
|
39
|
-
repos.all.each(&:refresh)
|
40
|
-
end
|
41
|
-
|
42
|
-
def subscribe(*args)
|
43
|
-
super
|
44
|
-
[bundler, repos].each { |object| object.subscribe(self) }
|
38
|
+
[bundler, repos].each(&:refresh)
|
45
39
|
end
|
46
40
|
end
|
47
41
|
end
|
@@ -1,10 +1,12 @@
|
|
1
1
|
require 'core_ext/enumerable/map_slice'
|
2
2
|
|
3
3
|
module Space
|
4
|
-
module
|
4
|
+
module Model
|
5
5
|
class Project
|
6
6
|
class Bundler
|
7
|
-
|
7
|
+
autoload :Config, 'space/model/project/bundler/config'
|
8
|
+
|
9
|
+
include Source
|
8
10
|
|
9
11
|
commands config: 'bundle config'
|
10
12
|
|
@@ -14,17 +16,14 @@ module Space
|
|
14
16
|
|
15
17
|
def initialize(project)
|
16
18
|
@project = project
|
17
|
-
super()
|
19
|
+
super('.')
|
18
20
|
end
|
19
21
|
|
20
22
|
def config
|
21
|
-
|
22
|
-
values = lines.map_slice(3) do |name, value, _|
|
23
|
-
[name, value =~ /: "(.*)"/ && $1]
|
24
|
-
end
|
25
|
-
Hash[*values.compact.flatten]
|
23
|
+
Config.new(result(:config)).to_hash
|
26
24
|
end
|
27
25
|
end
|
28
26
|
end
|
29
27
|
end
|
30
28
|
end
|
29
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Space
|
2
|
+
module Model
|
3
|
+
class Project
|
4
|
+
class Bundler
|
5
|
+
class Config
|
6
|
+
attr_reader :config
|
7
|
+
|
8
|
+
def initialize(config)
|
9
|
+
@config = config
|
10
|
+
end
|
11
|
+
|
12
|
+
def lines
|
13
|
+
config.split("\n")[2..-1] || []
|
14
|
+
end
|
15
|
+
|
16
|
+
def data
|
17
|
+
lines.map_slice(3) do |name, value, _|
|
18
|
+
[name, value =~ /: "(.*)"/ && $1]
|
19
|
+
end.compact.flatten
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_hash
|
23
|
+
Hash[*data]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Space
|
2
|
+
module Model
|
3
|
+
class Repo
|
4
|
+
autoload :Bundle, 'space/model/repo/bundle'
|
5
|
+
autoload :Dependency, 'space/model/repo/dependency'
|
6
|
+
autoload :Git, 'space/model/repo/git'
|
7
|
+
|
8
|
+
attr_reader :project, :path, :git, :bundle
|
9
|
+
|
10
|
+
def initialize(project, path)
|
11
|
+
@project = project
|
12
|
+
@path = File.expand_path(path)
|
13
|
+
@git = Git.new(self)
|
14
|
+
@bundle = Bundle.new(self, project.repos)
|
15
|
+
end
|
16
|
+
|
17
|
+
def name
|
18
|
+
@name ||= File.basename(path)
|
19
|
+
end
|
20
|
+
|
21
|
+
def number
|
22
|
+
@number ||= project.number(name)
|
23
|
+
end
|
24
|
+
|
25
|
+
def ref
|
26
|
+
git.commit
|
27
|
+
end
|
28
|
+
|
29
|
+
def deps
|
30
|
+
bundle.deps
|
31
|
+
end
|
32
|
+
|
33
|
+
def refresh
|
34
|
+
[git, bundle].each(&:refresh)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,18 +1,16 @@
|
|
1
|
-
require 'observer'
|
2
|
-
|
3
1
|
module Space
|
4
|
-
module
|
2
|
+
module Model
|
5
3
|
class Repo
|
6
4
|
class Bundle
|
7
|
-
include
|
5
|
+
include Source
|
8
6
|
|
9
|
-
commands check: 'bundle check',
|
7
|
+
commands check: 'bundle check --no-lock',
|
10
8
|
list: 'bundle list'
|
11
9
|
|
12
10
|
watch 'Gemfile',
|
13
11
|
'Gemfile.lock'
|
14
12
|
|
15
|
-
attr_reader :
|
13
|
+
attr_reader :repos
|
16
14
|
|
17
15
|
def initialize(repo, repos)
|
18
16
|
@repo = repo
|
@@ -25,7 +23,7 @@ module Space
|
|
25
23
|
end
|
26
24
|
|
27
25
|
def info
|
28
|
-
result(:check).split("\n").first
|
26
|
+
result(:check).split("\n").first || ''
|
29
27
|
end
|
30
28
|
|
31
29
|
def deps
|
@@ -37,3 +35,4 @@ module Space
|
|
37
35
|
end
|
38
36
|
end
|
39
37
|
end
|
38
|
+
|
@@ -1,10 +1,8 @@
|
|
1
|
-
require 'observer'
|
2
|
-
|
3
1
|
module Space
|
4
|
-
module
|
2
|
+
module Model
|
5
3
|
class Repo
|
6
4
|
class Git
|
7
|
-
include
|
5
|
+
include Source
|
8
6
|
|
9
7
|
commands status: 'git status',
|
10
8
|
branch: 'git branch --no-color',
|
@@ -19,32 +17,32 @@ module Space
|
|
19
17
|
super(repo.path)
|
20
18
|
end
|
21
19
|
|
22
|
-
def branch
|
23
|
-
result(:branch) =~ /^\* (.+)/ && $1.strip
|
24
|
-
end
|
25
|
-
|
26
|
-
def commit
|
27
|
-
result(:commit) =~ /^commit (\S{7})/ && $1
|
28
|
-
end
|
29
|
-
|
30
20
|
def status
|
31
21
|
dirty? ? :dirty : (ahead? ? :ahead : :clean)
|
32
22
|
end
|
33
23
|
|
24
|
+
def dirty?
|
25
|
+
!clean?
|
26
|
+
end
|
27
|
+
|
34
28
|
def ahead?
|
35
29
|
ahead > 0
|
36
30
|
end
|
37
31
|
|
32
|
+
def clean?
|
33
|
+
result(:status) =~ /nothing to commit (working directory clean)/
|
34
|
+
end
|
35
|
+
|
38
36
|
def ahead
|
39
37
|
result(:status) =~ /Your branch is ahead of .* by (\d+) commits?\./ ? $1.to_i : 0
|
40
38
|
end
|
41
39
|
|
42
|
-
def
|
43
|
-
|
40
|
+
def branch
|
41
|
+
result(:branch) =~ /^\* (.+)/ && $1.strip
|
44
42
|
end
|
45
43
|
|
46
|
-
def
|
47
|
-
result(:
|
44
|
+
def commit
|
45
|
+
result(:commit) =~ /^commit (\S{7})/ && $1
|
48
46
|
end
|
49
47
|
end
|
50
48
|
end
|
@@ -1,9 +1,7 @@
|
|
1
1
|
module Space
|
2
|
-
module
|
2
|
+
module Model
|
3
3
|
class Repos
|
4
|
-
|
5
|
-
|
6
|
-
autoload :Collection, 'space/models/repos/collection'
|
4
|
+
autoload :Collection, 'space/model/repos/collection'
|
7
5
|
|
8
6
|
attr_accessor :project, :paths, :scope
|
9
7
|
|
@@ -21,8 +19,8 @@ module Space
|
|
21
19
|
end
|
22
20
|
|
23
21
|
def scope=(scope)
|
22
|
+
log "SCOPE: #{scope ? scope.map(&:name) : '-'}"
|
24
23
|
@scope = scope
|
25
|
-
notify(:update, nil)
|
26
24
|
end
|
27
25
|
|
28
26
|
def scope
|
@@ -33,17 +31,28 @@ module Space
|
|
33
31
|
!!@scope
|
34
32
|
end
|
35
33
|
|
34
|
+
def find_by_name_or_number(repo)
|
35
|
+
repo =~ /^\d+$/ ? find_by_number(repo.to_i) : find_by_name(repo)
|
36
|
+
end
|
37
|
+
|
36
38
|
def find_by_name(name)
|
37
|
-
all.detect { |repo| repo.name == name } || raise("cannot find repo #{name.inspect}")
|
39
|
+
all.detect { |repo| repo.name == name } || raise("cannot find repo by name #{name.inspect}")
|
40
|
+
end
|
41
|
+
|
42
|
+
def find_by_number(number)
|
43
|
+
all.detect { |repo| repo.number == number } || raise("cannot find repo by number #{number.inspect}")
|
44
|
+
end
|
45
|
+
|
46
|
+
def select_by_names_or_numbers(repos)
|
47
|
+
Collection.new(self, repos.map { |repo| find_by_name_or_number(repo) })
|
38
48
|
end
|
39
49
|
|
40
50
|
def select_by_names(names)
|
41
51
|
Collection.new(self, all.select { |repo| names.include?(repo.name) })
|
42
52
|
end
|
43
53
|
|
44
|
-
def
|
45
|
-
|
46
|
-
all.each { |repo| repo.subscribe(*args) }
|
54
|
+
def refresh
|
55
|
+
all.each(&:refresh)
|
47
56
|
end
|
48
57
|
end
|
49
58
|
end
|
data/lib/space/screen.rb
CHANGED
@@ -8,25 +8,42 @@ module Space
|
|
8
8
|
|
9
9
|
def initialize(project)
|
10
10
|
@project = project
|
11
|
+
render_header
|
11
12
|
end
|
12
13
|
|
13
|
-
def display
|
14
|
-
@
|
15
|
-
render
|
14
|
+
def display
|
15
|
+
@views = [Progress.new(project), Dashboard.new(project)]
|
16
16
|
end
|
17
17
|
|
18
|
-
def render
|
19
|
-
|
20
|
-
|
18
|
+
# def render
|
19
|
+
# view.render
|
20
|
+
# move prompt.size + 1, 3
|
21
|
+
# end
|
21
22
|
|
22
|
-
def notify(event)
|
23
|
-
|
24
|
-
end
|
23
|
+
# def notify(event)
|
24
|
+
# view.notify(event)
|
25
|
+
# end
|
25
26
|
|
26
27
|
private
|
27
28
|
|
28
|
-
def
|
29
|
-
|
29
|
+
def render_header
|
30
|
+
print "\e[2J" # clear entire screen
|
31
|
+
move 0, 0
|
32
|
+
puts "Project #{project.name}\n\n"
|
33
|
+
puts prompt
|
34
|
+
end
|
35
|
+
|
36
|
+
def move(x, y)
|
37
|
+
print "\e[#{y};#{x}H"
|
30
38
|
end
|
39
|
+
|
40
|
+
def prompt
|
41
|
+
"#{project.repos.scoped? ? project.repos.scope.map { |r| r.name }.join(', ') : project.name} > "
|
42
|
+
end
|
43
|
+
|
44
|
+
# def create(screen)
|
45
|
+
# self.class.const_get(screen.to_s.capitalize).new(project)
|
46
|
+
# end
|
31
47
|
end
|
32
48
|
end
|
49
|
+
|
@@ -1,11 +1,9 @@
|
|
1
1
|
module Space
|
2
2
|
class Screen
|
3
3
|
class Dashboard < View
|
4
|
-
def
|
5
|
-
|
6
|
-
|
7
|
-
render_header
|
8
|
-
render_repos
|
4
|
+
def initialize(*)
|
5
|
+
Events.subscribe(self, :finish)
|
6
|
+
super
|
9
7
|
end
|
10
8
|
|
11
9
|
def notify(event)
|
@@ -14,6 +12,24 @@ module Space
|
|
14
12
|
|
15
13
|
private
|
16
14
|
|
15
|
+
def render
|
16
|
+
App.log 'RENDER dashboard'
|
17
|
+
clear
|
18
|
+
render_repos
|
19
|
+
move prompt.size + 1, 3
|
20
|
+
print "\e[0K"
|
21
|
+
end
|
22
|
+
|
23
|
+
def clear
|
24
|
+
move 0, 4
|
25
|
+
print "\e[J" # clear from cursor down
|
26
|
+
move 0, 5
|
27
|
+
end
|
28
|
+
|
29
|
+
def prompt
|
30
|
+
"#{project.repos.scoped? ? project.repos.scope.map { |r| r.name }.join(', ') : project.name} > "
|
31
|
+
end
|
32
|
+
|
17
33
|
def render_repos
|
18
34
|
project.repos.scope.self_and_deps.each do |repo|
|
19
35
|
render_template(:repo, assigns(repo))
|