lace 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ N2EwOWNjNGJiNTg5NWE0YTM0NGVmZjcyMGJlZGEwNzkyZmRlZWU3YQ==
5
+ data.tar.gz: !binary |-
6
+ NzM4NzhkMWU0NTRhZjljYjVjZTA1OWFlMjA1MmQyMWViYjg1NmQ1Ng==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ MzQ3ZjA0OWU5OTU2YWVmOTAzMDAxYjQ5MDU3NWI4MDFkMDNkMDZjMzMxZDVm
10
+ NjVmODEwMjcyYzcxZTk2MDAyMWE5NDI2MTlhMWEyMjAyYTc5NWM4NmQxMmFk
11
+ OThkODU1NzM5MWRhNDk0NmRkMjM1NDNiNTIxYjJlZjc3MTk4MmU=
12
+ data.tar.gz: !binary |-
13
+ ZjI3N2ZkMTczNDdkMWZkY2U1ZDgwMzYzYTZkMGY5NTRlMzY0ZTVhZDM5ZWJi
14
+ MjdjY2RjYjY4NDAxMjBjODkzMmM1NjkzNGM1M2Y1ZGFjNDMxNTIyOWQ4ZDAx
15
+ MmYxMTQ3ZTU1M2ZmN2ZhMzY2MDA1NjUwN2QxMTRhYmY0Y2RiMDM=
data/bin/lace CHANGED
@@ -30,6 +30,14 @@ if ARGV.debug?
30
30
  require "debugger"
31
31
  end
32
32
 
33
+ def require? path
34
+ require path.to_s.chomp
35
+ rescue LoadError => e
36
+ # HACK :( because we should raise on syntax errors but
37
+ # not if the file doesn't exist. TODO make robust!
38
+ raise unless e.to_s.include? path
39
+ end
40
+
33
41
  case ARGV.first when '-h', '--help', '--usage', '-?', 'help', nil
34
42
  require 'cmd/help'
35
43
  puts Lace.help_s
@@ -58,7 +66,8 @@ begin
58
66
  cmd = ARGV.shift
59
67
  cmd = aliases[cmd] if aliases[cmd]
60
68
 
61
- if require "cmd/" + cmd
69
+
70
+ if require? "cmd/" + cmd
62
71
  Lace.send cmd.to_s.gsub('-', '_').downcase
63
72
  else
64
73
  onoe "Unknown command: #{cmd}"
data/lib/cmd/activate.rb CHANGED
@@ -6,7 +6,7 @@ module Lace extend self
6
6
  def activate
7
7
  package_name = ARGV.shift
8
8
  raise ResourceNotSpecified if not package_name
9
- PackageUtils.activate package_name, ARGV
9
+ PackageUtils.activate package_name
10
10
  end
11
11
  end
12
12
 
@@ -5,7 +5,7 @@ module Lace extend self
5
5
  def deactivate
6
6
  package_name = ARGV.shift
7
7
  raise ResourceNotSpecified if not package_name
8
- PackageUtils.deactivate package_name, ARGV
8
+ PackageUtils.deactivate package_name
9
9
  end
10
10
  end
11
11
 
data/lib/cmd/fetch.rb CHANGED
@@ -5,6 +5,6 @@ module Lace extend self
5
5
  def fetch
6
6
  resource = ARGV.shift
7
7
  raise ResourceNotSpecified if not resource
8
- PackageUtils.fetch resource, ARGV
8
+ PackageUtils.fetch resource
9
9
  end
10
10
  end
data/lib/cmd/inspect.rb CHANGED
@@ -4,10 +4,11 @@ require 'lace/package'
4
4
  require 'lace/exceptions'
5
5
 
6
6
  INSPECT = <<-EOS
7
- Inspection of simple:
7
+ Inspection of <%= package.name %>:
8
8
  active: <%= package.is_active? %>
9
9
  flavors: <%= package.flavors %>
10
10
  version: <%= package.version %>
11
+ homepage: <%= package.homepage %>
11
12
  upgradeable: <%= package.upgradeable? %>
12
13
  manifest: <%= package.manifest %>
13
14
  EOS
@@ -18,7 +19,7 @@ module Lace extend self
18
19
  raise ResourceNotSpecified if not resource
19
20
  package = PackagePresenter.new Package.new(resource, false)
20
21
  puts ERB.new(INSPECT).result(binding)
21
- end
22
+ end
22
23
  end
23
24
 
24
25
  class PackagePresenter
@@ -28,6 +29,10 @@ class PackagePresenter
28
29
  @pkg = obj
29
30
  end
30
31
 
32
+ def name
33
+ @pkg.name
34
+ end
35
+
31
36
  def is_active?
32
37
  pkg.is_active?
33
38
  end
@@ -46,6 +51,10 @@ class PackagePresenter
46
51
  @pkg.facts.version or 'n/a'
47
52
  end
48
53
 
54
+ def homepage
55
+ @pkg.facts.homepage or 'n/a'
56
+ end
57
+
49
58
  def upgradeable?
50
59
  @pkg.is_git_repo?
51
60
  end
data/lib/cmd/install.rb CHANGED
@@ -5,6 +5,6 @@ module Lace extend self
5
5
  def install
6
6
  resource = ARGV.shift
7
7
  raise ResourceNotSpecified if not resource
8
- PackageUtils.install resource, ARGV
8
+ PackageUtils.install resource
9
9
  end
10
10
  end
data/lib/cmd/list.rb CHANGED
@@ -10,21 +10,21 @@ module Lace extend self
10
10
  end.compact.uniq
11
11
  end
12
12
 
13
- def active_dotties
13
+ def active_packages
14
14
  linked_files.map do |path|
15
15
  Pathname.new File.dirname(path)
16
16
  end.uniq
17
17
  end
18
18
 
19
- def installed_dotties
19
+ def installed_packages
20
20
  Dir.glob(File.join(LACE_PKGS_FOLDER, "**")).sort.map do |p|
21
21
  Pathname.new(p).basename.to_s
22
22
  end
23
23
  end
24
24
 
25
25
  def list
26
- if installed_dotties.length > 0
27
- installed_dotties.map do |d|
26
+ if installed_packages.length > 0
27
+ installed_packages.map do |d|
28
28
  package = Package.new d, false
29
29
  puts "- [#{Tty.green}#{package.is_active? ? "*" : " "}#{Tty.reset}] #{d}"
30
30
  end
data/lib/cmd/remove.rb CHANGED
@@ -5,7 +5,7 @@ module Lace extend self
5
5
  def remove
6
6
  package_name = ARGV.shift
7
7
  raise ResourceNotSpecified if not package_name
8
- PackageUtils.remove package_name, ARGV
8
+ PackageUtils.remove package_name
9
9
  end
10
10
  end
11
11
 
data/lib/cmd/update.rb CHANGED
@@ -5,6 +5,6 @@ module Lace extend self
5
5
  def update
6
6
  resource = ARGV.shift
7
7
  raise ResourceNotSpecified if not resource
8
- PackageUtils.update resource, ARGV
8
+ PackageUtils.update resource
9
9
  end
10
10
  end
@@ -1,5 +1,5 @@
1
1
  require 'pathname'
2
-
2
+ # borrowed from brew.sh
3
3
  # we enhance pathname to make our code more readable
4
4
  class Pathname
5
5
 
@@ -136,55 +136,6 @@ class Pathname
136
136
  (dirname+link).exist?
137
137
  end
138
138
 
139
- # perhaps confusingly, this Pathname object becomes the symlink pointing to
140
- # the src paramter.
141
- def make_relative_symlink src
142
- src = Pathname.new(src) unless src.kind_of? Pathname
143
-
144
- self.dirname.mkpath
145
- Dir.chdir self.dirname do
146
- # NOTE only system ln -s will create RELATIVE symlinks
147
- quiet_system 'ln', '-s', src.relative_path_from(self.dirname), self.basename
148
- if not $?.success?
149
- if self.exist?
150
- raise <<-EOS.undent
151
- Could not symlink file: #{src.expand_path}
152
- Target #{self} already exists. You may need to delete it.
153
- To force the link and overwrite all other conflicting files, do:
154
- brew link --overwrite formula_name
155
-
156
- To list all files that would be deleted:
157
- brew link --overwrite --dry-run formula_name
158
- EOS
159
- # #exist? will return false for symlinks whose target doesn't exist
160
- elsif self.symlink?
161
- raise <<-EOS.undent
162
- Could not symlink file: #{src.expand_path}
163
- Target #{self} already exists as a symlink to #{readlink}.
164
- If this file is from another formula, you may need to
165
- `brew unlink` it. Otherwise, you may want to delete it.
166
- To force the link and overwrite all other conflicting files, do:
167
- brew link --overwrite formula_name
168
-
169
- To list all files that would be deleted:
170
- brew link --overwrite --dry-run formula_name
171
- EOS
172
- elsif !dirname.writable_real?
173
- raise <<-EOS.undent
174
- Could not symlink file: #{src.expand_path}
175
- #{dirname} is not writable. You should change its permissions.
176
- EOS
177
- else
178
- raise <<-EOS.undent
179
- Could not symlink file: #{src.expand_path}
180
- #{self} may already exist.
181
- #{dirname} may not be writable.
182
- EOS
183
- end
184
- end
185
- end
186
- end
187
-
188
139
  def / that
189
140
  join that.to_s
190
141
  end
@@ -20,7 +20,7 @@ end
20
20
  class LocalFileStrategy < AbstractDownloadStrategy
21
21
  def fetch
22
22
  ohai "Fetching #@uri into #@target_folder"
23
- FileUtils.cp_r @uri, @target_folder
23
+ FileUtils.cp_r @uri, @target_folder, :preserve => true
24
24
  @target_folder
25
25
  end
26
26
 
@@ -20,6 +20,45 @@ class NonActiveFlavorError < RuntimeError
20
20
  end
21
21
  end
22
22
 
23
+ class PackageAlreadyInstalled < RuntimeError
24
+ def initialize
25
+ super "Package already installed"
26
+ end
27
+ end
28
+
29
+ class CannotRemoveActivePackage < RuntimeError
30
+ def initialize
31
+ super "Cannot remove active pkg, deactivate first"
32
+ end
33
+ end
34
+
35
+ class PackageNotInstalled < RuntimeError
36
+ def initialize name
37
+ super "Package #{name} is not installed"
38
+ end
39
+ end
40
+
41
+ class FlavorError < RuntimeError; end
42
+
43
+ class FlavorArgumentRequired < FlavorError
44
+ def initialize available_flavors
45
+ super FlavorArgumentMsg % available_flavors.join("\n- ")
46
+ end
47
+ end
48
+
49
+ class PackageFactsNotFound < RuntimeError
50
+ def initialize path
51
+ super "No PackageFacts found in #{path}"
52
+ end
53
+ end
54
+
55
+ class PackageFlavorDoesNotExist < FlavorError
56
+ def initialize which_flavor, flavors
57
+ super "Flavor '#{which_flavor}' does not exist"
58
+ end
59
+ end
60
+
61
+
23
62
  FlavorArgumentMsg = <<-EOS
24
63
  Sorry, this command needs a flavor argument you can choose from the following:
25
64
  - %s
data/lib/lace/package.rb CHANGED
@@ -1,67 +1,73 @@
1
+ require 'set'
1
2
  require 'yaml'
2
3
  require 'ostruct'
3
- require 'set'
4
4
 
5
5
  require 'lace/download_strategy'
6
6
  require 'lace/exceptions'
7
7
 
8
8
  class PackageUtils
9
- def self.is_package_any_flavor_active name
9
+ def self.has_active_flavors name
10
10
  @path = LACE_PKGS_FOLDER/name
11
11
  facts = Facts.new @path
12
- facts.flavors.any?{|f| Package.new(@name, f).is_active?}
12
+ facts.flavors.any?{|f| Package.new(@name, f).is_active? }
13
13
  end
14
14
 
15
- def self.fetch uri, argv
15
+ def self.fetch uri
16
16
  downloader = DownloadStrategyDetector.detect(uri).new(uri)
17
- if downloader.target_folder.exist?
18
- raise "Package already installed"
19
- end
17
+ raise PackageAlreadyInstalled.new if downloader.target_folder.exist?
20
18
  downloader.fetch
19
+ begin
20
+ package = Package.new downloader.name, false
21
+ rescue PackageFactsNotFound => e
22
+ onoe e.message
23
+ onoe "Removing fetched files"
24
+ FileUtils.rm_rf downloader.target_folder
25
+ end
21
26
  end
22
27
 
23
- def self.remove package_name, argv
24
- ohai "Removing"
28
+ def self.remove package_name
25
29
  package = Package.new package_name, false
26
- unless package.is_active?
27
- FileUtils.rm_rf package.path
28
- ohai "Successfully removed"
29
- else
30
- ofail "Cannot remove active pkg, deactivate first"
31
- end
30
+ raise CannotRemoveActivePackage.new if package.is_active?
31
+ ohai "Removing"
32
+ FileUtils.rm_rf package.path
32
33
  end
33
34
 
34
- def self.install uri, argv
35
+ def self.install uri
35
36
  downloader = DownloadStrategyDetector.detect(uri).new(uri)
36
- if downloader.target_folder.exist?
37
- raise "Package already installed"
37
+ self.fetch uri
38
+ begin
39
+ package = Package.new downloader.name, ARGV.first
40
+ package.activate!
41
+ package.after_install
42
+ rescue FlavorError => e
43
+ onoe e.message
44
+ onoe "Package remains installed but was not activated"
38
45
  end
39
- downloader.fetch
40
- package = Package.new downloader.name, ARGV.first
41
- package.activate!
42
- package.after_install
43
46
  end
44
47
 
45
- def self.deactivate package_name, argv
46
- package = Package.new package_name, ARGV.shift
48
+ def self.deactivate package_name
49
+ package = Package.new package_name, ARGV.first
47
50
  raise NonActiveFlavorError.new unless package.is_active?
51
+ ohai "Deactivating"
48
52
  package.deactivate!
49
53
  end
50
54
 
51
- def self.activate package_name, argv
52
- package = Package.new package_name, ARGV.shift
55
+ def self.activate package_name
56
+ package = Package.new package_name, ARGV.first
53
57
  raise AlreadyActiveError.new if Package.new(package_name, false).is_active?
58
+ ohai "Activating"
54
59
  package.activate!
55
60
  end
56
61
 
57
- def self.update package_name, argv
62
+ def self.update package_name
58
63
  package = Package.new package_name, false
59
64
  raise OnlyGitReposCanBeUpdatedError.new unless package.is_git_repo?
60
65
  updater = GitUpdateStrategy.new package_name
61
- package.deactivate!
66
+ self.deactivate package_name
67
+ ohai "Updating"
62
68
  updater.update
63
- package.read_facts!
64
- package.activate!
69
+ self.activate package_name
70
+ package = Package.new package_name, false
65
71
  package.after_update
66
72
  end
67
73
  end
@@ -71,9 +77,9 @@ class Facts
71
77
  def initialize location
72
78
  @location = Pathname.new(location)
73
79
  @facts_file = @location/".lace.yml"
74
- raise RuntimeError.new "No package file found in #@location" unless @facts_file.exist?
75
- @facts = YAML.load @facts_file.read
76
- @_facts = YAML.load @facts_file.read
80
+ raise PackageFactsNotFound.new(@location) unless @facts_file.exist?
81
+ @facts = facts_file_to_hash
82
+ @_facts = facts_file_to_hash
77
83
  end
78
84
 
79
85
  def config_files
@@ -98,6 +104,10 @@ class Facts
98
104
  @_facts["version"] if @_facts.key? "version"
99
105
  end
100
106
 
107
+ def homepage
108
+ @_facts["homepage"] if @_facts.key? "homepage"
109
+ end
110
+
101
111
  def flavors
102
112
  if @_facts && @_facts.key?("flavors")
103
113
  @_facts["flavors"].keys
@@ -107,7 +117,7 @@ class Facts
107
117
  end
108
118
 
109
119
  def flavor! which_flavor
110
- raise RuntimeError.new "Flavor '#{which_flavor}' does not exist -> #{flavors.join(', ')} - use: lace <command> <pkg-uri> <flavor>" unless flavors.include? which_flavor
120
+ raise PackageFlavorDoesNotExist.new(which_flavor, flavors) unless flavors.include? which_flavor
111
121
  @facts = @_facts["flavors"][which_flavor]
112
122
  end
113
123
 
@@ -123,6 +133,16 @@ class Facts
123
133
  (post_hook[hook_point.to_s] || []).flatten
124
134
  end
125
135
  end
136
+
137
+ protected
138
+ def facts_file_to_hash
139
+ value = YAML.load @facts_file.read
140
+ if value.is_a?(String) && value == "---"
141
+ return Hash.new
142
+ else
143
+ value
144
+ end
145
+ end
126
146
  end
127
147
 
128
148
  class Package
@@ -151,7 +171,7 @@ class Package
151
171
 
152
172
  def initialize name, flavor=nil
153
173
  require 'cmd/list'
154
- raise "Package #{name} is not installed" unless Lace.installed_dotties.include? name
174
+ raise PackageNotInstalled.new(name) unless Lace.installed_packages.include? name
155
175
  @name = name
156
176
  @path = LACE_PKGS_FOLDER/name
157
177
  @flavor = flavor
@@ -174,16 +194,16 @@ class Package
174
194
  end
175
195
 
176
196
  def read_facts!
197
+ # todo simplify
177
198
  @facts = Facts.new @path
178
199
  if @facts.has_flavors? && @flavor.nil?
179
- raise RuntimeError.new FlavorArgumentMsg % @facts.flavors.join("\n- ")
200
+ raise FlavorArgumentRequired.new @facts.flavors
180
201
  elsif @facts.has_flavors? && @flavor != false
181
202
  @facts.flavor! @flavor
182
203
  end
183
204
  end
184
205
 
185
206
  def deactivate!
186
- ohai "Deactivating"
187
207
  files = @facts.config_files
188
208
  home_dir = ENV["HOME"]
189
209
  files.each do |file|
@@ -193,7 +213,6 @@ class Package
193
213
  end
194
214
 
195
215
  def activate!
196
- ohai "Activating"
197
216
  files = @facts.config_files
198
217
  home_dir = ENV["HOME"]
199
218
  files.each do |file|
data/lib/lace/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Lace
2
- VERSION = "0.2.2"
2
+ VERSION = "0.2.3"
3
3
  end
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lace
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
5
- prerelease:
4
+ version: 0.2.3
6
5
  platform: ruby
7
6
  authors:
8
7
  - Kai Richard Koenig
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2014-01-04 00:00:00.000000000 Z
11
+ date: 2014-01-09 00:00:00.000000000 Z
13
12
  dependencies: []
14
13
  description: This is a simple/unfinished tool which i use to manage my dotfiles on
15
14
  all the different machines
@@ -19,6 +18,7 @@ executables:
19
18
  extensions: []
20
19
  extra_rdoc_files: []
21
20
  files:
21
+ - bin/lace
22
22
  - lib/cmd/activate.rb
23
23
  - lib/cmd/deactivate.rb
24
24
  - lib/cmd/fetch.rb
@@ -36,30 +36,28 @@ files:
36
36
  - lib/lace/package.rb
37
37
  - lib/lace/utils.rb
38
38
  - lib/lace/version.rb
39
- - bin/lace
40
39
  homepage: https://github.com/kairichard/lace
41
40
  licenses:
42
41
  - MIT
42
+ metadata: {}
43
43
  post_install_message:
44
44
  rdoc_options: []
45
45
  require_paths:
46
46
  - lib
47
47
  required_ruby_version: !ruby/object:Gem::Requirement
48
- none: false
49
48
  requirements:
50
49
  - - ! '>='
51
50
  - !ruby/object:Gem::Version
52
51
  version: 1.8.6
53
52
  required_rubygems_version: !ruby/object:Gem::Requirement
54
- none: false
55
53
  requirements:
56
54
  - - ! '>='
57
55
  - !ruby/object:Gem::Version
58
56
  version: '0'
59
57
  requirements: []
60
58
  rubyforge_project:
61
- rubygems_version: 1.8.23
59
+ rubygems_version: 2.2.0
62
60
  signing_key:
63
- specification_version: 3
61
+ specification_version: 4
64
62
  summary: Manage your .dotfiles
65
63
  test_files: []