space 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/bin/space +6 -0
  2. data/lib/core_ext/string/deansi.rb +7 -0
  3. data/lib/core_ext/string/demodulize.rb +5 -0
  4. data/lib/space.rb +4 -4
  5. data/lib/space/action.rb +43 -0
  6. data/lib/space/action/builtin.rb +43 -0
  7. data/lib/space/action/development.rb +56 -0
  8. data/lib/space/{app → action}/handler.rb +17 -9
  9. data/lib/space/{app → action}/parser.rb +4 -7
  10. data/lib/space/app.rb +14 -30
  11. data/lib/space/events.rb +27 -20
  12. data/lib/space/events/sources.rb +34 -0
  13. data/lib/space/events/subscription.rb +23 -0
  14. data/lib/space/logger.rb +34 -0
  15. data/lib/space/model.rb +7 -0
  16. data/lib/space/{models → model}/project.rb +4 -10
  17. data/lib/space/{models → model}/project/bundler.rb +7 -8
  18. data/lib/space/model/project/bundler/config.rb +30 -0
  19. data/lib/space/model/repo.rb +38 -0
  20. data/lib/space/{models → model}/repo/bundle.rb +6 -7
  21. data/lib/space/{models → model}/repo/dependency.rb +1 -1
  22. data/lib/space/{models → model}/repo/git.rb +14 -16
  23. data/lib/space/{models → model}/repos.rb +18 -9
  24. data/lib/space/{models → model}/repos/collection.rb +1 -1
  25. data/lib/space/{models → model}/repos/scope.rb +1 -1
  26. data/lib/space/screen.rb +28 -11
  27. data/lib/space/screen/dashboard.rb +21 -5
  28. data/lib/space/screen/progress.rb +16 -5
  29. data/lib/space/screen/view.rb +2 -6
  30. data/lib/space/source.rb +51 -0
  31. data/lib/space/source/command.rb +70 -0
  32. data/lib/space/source/watch.rb +64 -0
  33. data/lib/space/source/watcher.rb +32 -0
  34. data/lib/space/version.rb +1 -1
  35. metadata +27 -24
  36. data/lib/space/app/command.rb +0 -45
  37. data/lib/space/app/command/builtin.rb +0 -43
  38. data/lib/space/app/command/development.rb +0 -60
  39. data/lib/space/app/logger.rb +0 -21
  40. data/lib/space/events/buffer.rb +0 -18
  41. data/lib/space/events/event.rb +0 -14
  42. data/lib/space/models.rb +0 -7
  43. data/lib/space/models/repo.rb +0 -57
  44. data/lib/space/shell.rb +0 -56
  45. data/lib/space/shell/command.rb +0 -63
  46. data/lib/space/shell/watch.rb +0 -50
  47. 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
@@ -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')
@@ -0,0 +1,7 @@
1
+ module Space
2
+ module Model
3
+ autoload :Project, 'space/model/project'
4
+ autoload :Repos, 'space/model/repos'
5
+ autoload :Repo, 'space/model/repo'
6
+ end
7
+ end
@@ -1,9 +1,9 @@
1
1
  module Space
2
- module Models
2
+ module Model
3
3
  class Project
4
- include Events
4
+ autoload :Bundler, 'space/model/project/bundler'
5
5
 
6
- autoload :Bundler, 'space/models/project/bundler'
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 Models
4
+ module Model
5
5
  class Project
6
6
  class Bundler
7
- include Events, Shell
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
- lines = result(:config).split("\n")[2..-1] || []
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 Models
2
+ module Model
5
3
  class Repo
6
4
  class Bundle
7
- include Events, Shell
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 :repo, :repos
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,5 +1,5 @@
1
1
  module Space
2
- module Models
2
+ module Model
3
3
  class Repo
4
4
  class Dependency
5
5
  attr_reader :repo, :ref
@@ -1,10 +1,8 @@
1
- require 'observer'
2
-
3
1
  module Space
4
- module Models
2
+ module Model
5
3
  class Repo
6
4
  class Git
7
- include Events, Shell
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 dirty?
43
- !clean?
40
+ def branch
41
+ result(:branch) =~ /^\* (.+)/ && $1.strip
44
42
  end
45
43
 
46
- def clean?
47
- result(:status).include?('nothing to commit (working directory clean)')
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 Models
2
+ module Model
3
3
  class Repos
4
- include Events
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 subscribe(*args)
45
- super
46
- all.each { |repo| repo.subscribe(*args) }
54
+ def refresh
55
+ all.each(&:refresh)
47
56
  end
48
57
  end
49
58
  end
@@ -1,5 +1,5 @@
1
1
  module Space
2
- module Models
2
+ module Model
3
3
  class Repos
4
4
  class Collection < Array
5
5
  attr_reader :repos
@@ -1,5 +1,5 @@
1
1
  module Space
2
- module Models
2
+ module Model
3
3
  class Repos
4
4
  class Collection < Array
5
5
  attr_reader :repos
@@ -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(name)
14
- @view = create(name)
15
- render
14
+ def display
15
+ @views = [Progress.new(project), Dashboard.new(project)]
16
16
  end
17
17
 
18
- def render
19
- view.render
20
- end
18
+ # def render
19
+ # view.render
20
+ # move prompt.size + 1, 3
21
+ # end
21
22
 
22
- def notify(event)
23
- view.notify(event)
24
- end
23
+ # def notify(event)
24
+ # view.notify(event)
25
+ # end
25
26
 
26
27
  private
27
28
 
28
- def create(screen)
29
- self.class.const_get(screen.to_s.capitalize).new(project)
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 render
5
- App.logger.debug('RENDER dashboard')
6
- clear
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))