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.
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))