lace 0.2.2 → 0.2.3

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.
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: []