lace 0.3.3 → 0.3.4
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 +13 -5
- data/bin/lace +27 -17
- data/lib/cmd/activate.rb +1 -1
- data/lib/cmd/deactivate.rb +1 -1
- data/lib/cmd/fetch.rb +5 -4
- data/lib/cmd/inspect.rb +2 -2
- data/lib/cmd/list.rb +3 -3
- data/lib/cmd/remove.rb +1 -1
- data/lib/cmd/update.rb +1 -1
- data/lib/cmd/upgrade.rb +21 -0
- data/lib/cmd/validate.rb +4 -3
- data/lib/extend/ARGV.rb +23 -0
- data/lib/extend/pathname.rb +23 -1
- data/lib/lace/download_strategy.rb +48 -6
- data/lib/lace/package/facts.rb +99 -0
- data/lib/lace/package/package.rb +75 -0
- data/lib/lace/package/utils.rb +59 -0
- data/lib/lace/package.rb +3 -227
- data/lib/lace/utils.rb +23 -0
- data/lib/lace/version.rb +1 -1
- data/lib/lace.rb +23 -0
- metadata +12 -8
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YjBmODJmNDczOGIyNmYxYzUxZWU3NmRmM2QzOWNlNjg2NWU3ODc2Mg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YmYxMTAzMTUyNzk2Y2IzNzQ4YjUzNjA1Njc4ZDBjMDQ5MTJmODA5YQ==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NzY3YzVkNTQ1ZTQ0ZmYxZjJkNGE3YzU0YWUyN2M0ZGQ4N2MxYmIzYWMyMDRj
|
10
|
+
MDZmM2QzNzFkYmM5YTVlMjA0NDI2ZGZhZDQ2ZmFkNjYzZmU5OWM5ZWE5MTZl
|
11
|
+
NjBiZjU3YTJiNGJlZWU0ZjcwM2U3YjYzNzVkZmEwZDM3ODIyNjM=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YjU0MWUxMzVkN2Q3NjRjOWYzNzMxMzE1MmQ5YjRkNjEzYjA1MjI5YzY4YWY4
|
14
|
+
YzZiNTk1Y2IyZWY3MGJjNDkzOTM5NzZiYmQ3OWZlYTk5NGVmYzM1YTVlNzdm
|
15
|
+
YWIyMWMxNWY0MWRmYTkyMzViMTk1MGY4MzAwNTdhZGNkNjE0NWI=
|
data/bin/lace
CHANGED
@@ -1,33 +1,43 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#Copyright 2009-2014 Max Howell and other contributors.
|
4
|
+
#
|
5
|
+
#Redistribution and use in source and binary forms, with or without
|
6
|
+
#modification, are permitted provided that the following conditions
|
7
|
+
#are met:
|
8
|
+
#
|
9
|
+
# 1. Redistributions of source code must retain the above copyright
|
10
|
+
# notice, this list of conditions and the following disclaimer.
|
11
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer in the
|
13
|
+
# documentation and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
#THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
16
|
+
#IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
17
|
+
#OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
18
|
+
#IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
19
|
+
#INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
20
|
+
#NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
21
|
+
#DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
22
|
+
#THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
23
|
+
#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
24
|
+
#THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
25
|
+
|
2
26
|
std_trap = trap("INT") { exit! 130 } # no backtrace thanks
|
3
27
|
require 'pathname'
|
4
28
|
|
5
29
|
LIB_PATH = Pathname.new(__FILE__).realpath.dirname.parent.join("lib").to_s
|
6
30
|
$:.unshift(LIB_PATH)
|
7
31
|
|
8
|
-
require
|
9
|
-
require "lace/exceptions"
|
10
|
-
require "lace/version"
|
32
|
+
require 'lace'
|
11
33
|
|
12
34
|
require "extend/ARGV"
|
13
35
|
require "extend/pathname"
|
14
36
|
|
15
|
-
packages_folder = Pathname.new(ENV["HOME"]).join(".cassias")
|
16
|
-
|
17
|
-
if ENV["LACE_FOLDER"]
|
18
|
-
packages_folder = Pathname.new(ENV["LACE_FOLDER"])
|
19
|
-
end
|
20
|
-
LACE_PKGS_FOLDER = packages_folder
|
21
|
-
|
22
|
-
module Lace extend self
|
23
|
-
attr_accessor :failed
|
24
|
-
alias_method :failed?, :failed
|
25
|
-
end
|
26
|
-
|
27
37
|
ARGV.extend(LaceArgvExtension)
|
28
38
|
|
29
39
|
if ARGV.debug?
|
30
|
-
require
|
40
|
+
require 'pry'
|
31
41
|
end
|
32
42
|
|
33
43
|
def require? path
|
@@ -62,12 +72,12 @@ begin
|
|
62
72
|
|
63
73
|
aliases = {'ls' => 'list',
|
64
74
|
'info' => 'inspect',
|
75
|
+
'--upgrade' => 'upgrade',
|
65
76
|
'rm' => 'remove'}
|
66
77
|
|
67
78
|
cmd = ARGV.shift
|
68
79
|
cmd = aliases[cmd] if aliases[cmd]
|
69
80
|
|
70
|
-
|
71
81
|
if require? "cmd/" + cmd
|
72
82
|
Lace.send cmd.to_s.gsub('-', '_').downcase
|
73
83
|
else
|
data/lib/cmd/activate.rb
CHANGED
data/lib/cmd/deactivate.rb
CHANGED
data/lib/cmd/fetch.rb
CHANGED
@@ -4,14 +4,15 @@ require 'lace/exceptions'
|
|
4
4
|
module Lace extend self
|
5
5
|
def fetch
|
6
6
|
resource = ARGV.shift
|
7
|
-
|
8
|
-
|
7
|
+
desired_package_name = ARGV.value "name"
|
8
|
+
raise ResourceNotSpecified unless resource
|
9
|
+
package_name, target_folder = PackageUtils.fetch(resource, desired_package_name)
|
9
10
|
begin
|
10
|
-
Package.new
|
11
|
+
Package.new(package_name, false)
|
11
12
|
rescue PackageFactsNotFound => e
|
12
13
|
onoe e.message
|
13
14
|
onoe "Removing fetched files"
|
14
|
-
FileUtils.rm_rf
|
15
|
+
FileUtils.rm_rf(target_folder)
|
15
16
|
Lace.failed = true
|
16
17
|
end
|
17
18
|
end
|
data/lib/cmd/inspect.rb
CHANGED
@@ -16,7 +16,7 @@ EOS
|
|
16
16
|
module Lace extend self
|
17
17
|
def inspect
|
18
18
|
resource = ARGV.shift
|
19
|
-
raise ResourceNotSpecified
|
19
|
+
raise ResourceNotSpecified unless resource
|
20
20
|
package = PackagePresenter.new Package.new(resource, false)
|
21
21
|
puts ERB.new(INSPECT).result(binding)
|
22
22
|
end
|
@@ -60,6 +60,6 @@ class PackagePresenter
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def manifest
|
63
|
-
|
63
|
+
@pkg.facts.facts_file
|
64
64
|
end
|
65
65
|
end
|
data/lib/cmd/list.rb
CHANGED
@@ -12,12 +12,12 @@ module Lace extend self
|
|
12
12
|
|
13
13
|
def active_packages
|
14
14
|
linked_files.map do |path|
|
15
|
-
Pathname.new
|
15
|
+
Pathname.new(File.dirname(path)).basename.to_s
|
16
16
|
end.uniq
|
17
17
|
end
|
18
18
|
|
19
19
|
def installed_packages
|
20
|
-
Dir.glob(File.join(
|
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
|
@@ -25,7 +25,7 @@ module Lace extend self
|
|
25
25
|
def list
|
26
26
|
if installed_packages.length > 0
|
27
27
|
installed_packages.map do |d|
|
28
|
-
package = Package.new
|
28
|
+
package = Package.new(d, false)
|
29
29
|
puts "[#{Tty.green}#{package.is_active? ? "*" : " "}#{Tty.reset}] #{d}"
|
30
30
|
end
|
31
31
|
else
|
data/lib/cmd/remove.rb
CHANGED
data/lib/cmd/update.rb
CHANGED
data/lib/cmd/upgrade.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'lace/package'
|
2
|
+
require 'lace/exceptions'
|
3
|
+
|
4
|
+
module Lace extend self
|
5
|
+
def upgrade
|
6
|
+
require 'cmd/list'
|
7
|
+
if Lace.active_packages.empty?
|
8
|
+
upgrade_lace_folder
|
9
|
+
else
|
10
|
+
onoe "Please deactivate all packages before continuing"
|
11
|
+
Lace.failed = true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
def upgrade_lace_folder
|
15
|
+
old_dir = Pathname.new(ENV["HOME"])/".cassias"
|
16
|
+
if old_dir.exist?
|
17
|
+
File.rename old_dir, Lace.pkgs_folder
|
18
|
+
old_dir.rmdir_if_possible
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/cmd/validate.rb
CHANGED
@@ -19,8 +19,9 @@ EOS
|
|
19
19
|
module Lace extend self
|
20
20
|
def validate
|
21
21
|
resource = ARGV.shift
|
22
|
-
|
23
|
-
|
22
|
+
flavor = ARGV.shift
|
23
|
+
raise ResourceNotSpecified unless resource
|
24
|
+
validation = PackageValidator.new(PackageFacts.new(resource), flavor)
|
24
25
|
puts ERB.new(VALIDATE, nil, '-').result(binding)
|
25
26
|
Lace.failed = true if validation.has_errors?
|
26
27
|
end
|
@@ -47,7 +48,7 @@ class PackageValidator
|
|
47
48
|
@facts = facts
|
48
49
|
@errors = []
|
49
50
|
if @facts.has_flavors? && flavor.nil?
|
50
|
-
raise RuntimeError.new
|
51
|
+
raise RuntimeError.new(FlavorArgumentMsg % @facts.flavors.join("\n- "))
|
51
52
|
elsif @facts.has_flavors? && flavor != false
|
52
53
|
@facts.flavor! flavor
|
53
54
|
end
|
data/lib/extend/ARGV.rb
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
#Copyright 2009-2014 Max Howell and other contributors.
|
2
|
+
#
|
3
|
+
#Redistribution and use in source and binary forms, with or without
|
4
|
+
#modification, are permitted provided that the following conditions
|
5
|
+
#are met:
|
6
|
+
#
|
7
|
+
# 1. Redistributions of source code must retain the above copyright
|
8
|
+
# notice, this list of conditions and the following disclaimer.
|
9
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
10
|
+
# notice, this list of conditions and the following disclaimer in the
|
11
|
+
# documentation and/or other materials provided with the distribution.
|
12
|
+
#
|
13
|
+
#THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
14
|
+
#IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
15
|
+
#OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
16
|
+
#IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
17
|
+
#INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
18
|
+
#NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
19
|
+
#DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
20
|
+
#THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
21
|
+
#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
22
|
+
#THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
23
|
+
|
1
24
|
module LaceArgvExtension
|
2
25
|
def named
|
3
26
|
@named ||= reject{|arg| arg[0..0] == '-'}
|
data/lib/extend/pathname.rb
CHANGED
@@ -1,5 +1,27 @@
|
|
1
|
+
#Copyright 2009-2014 Max Howell and other contributors.
|
2
|
+
#
|
3
|
+
#Redistribution and use in source and binary forms, with or without
|
4
|
+
#modification, are permitted provided that the following conditions
|
5
|
+
#are met:
|
6
|
+
#
|
7
|
+
# 1. Redistributions of source code must retain the above copyright
|
8
|
+
# notice, this list of conditions and the following disclaimer.
|
9
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
10
|
+
# notice, this list of conditions and the following disclaimer in the
|
11
|
+
# documentation and/or other materials provided with the distribution.
|
12
|
+
#
|
13
|
+
#THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
14
|
+
#IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
15
|
+
#OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
16
|
+
#IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
17
|
+
#INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
18
|
+
#NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
19
|
+
#DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
20
|
+
#THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
21
|
+
#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
22
|
+
#THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
23
|
+
|
1
24
|
require 'pathname'
|
2
|
-
# borrowed from brew.sh
|
3
25
|
# we enhance pathname to make our code more readable
|
4
26
|
class Pathname
|
5
27
|
|
@@ -1,18 +1,46 @@
|
|
1
|
+
#Copyright 2009-2014 Max Howell and other contributors.
|
2
|
+
#
|
3
|
+
#Redistribution and use in source and binary forms, with or without
|
4
|
+
#modification, are permitted provided that the following conditions
|
5
|
+
#are met:
|
6
|
+
#
|
7
|
+
# 1. Redistributions of source code must retain the above copyright
|
8
|
+
# notice, this list of conditions and the following disclaimer.
|
9
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
10
|
+
# notice, this list of conditions and the following disclaimer in the
|
11
|
+
# documentation and/or other materials provided with the distribution.
|
12
|
+
#
|
13
|
+
#THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
14
|
+
#IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
15
|
+
#OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
16
|
+
#IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
17
|
+
#INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
18
|
+
#NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
19
|
+
#DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
20
|
+
#THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
21
|
+
#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
22
|
+
#THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
23
|
+
|
1
24
|
require "fileutils"
|
2
25
|
|
3
26
|
class AbstractDownloadStrategy
|
4
27
|
attr_reader :name, :resource, :target_folder
|
5
28
|
|
6
|
-
def initialize uri
|
29
|
+
def initialize uri, desired_package_name=nil
|
30
|
+
@desired_package_name = desired_package_name
|
7
31
|
@uri = uri
|
8
|
-
@target_folder =
|
32
|
+
@target_folder = Lace.pkgs_folder/name
|
33
|
+
end
|
34
|
+
|
35
|
+
def uri
|
36
|
+
@uri
|
9
37
|
end
|
10
38
|
|
11
39
|
# All download strategies are expected to implement these methods
|
12
40
|
def fetch; end
|
13
41
|
def stage; end
|
14
42
|
def name
|
15
|
-
|
43
|
+
@desired_package_name
|
16
44
|
end
|
17
45
|
end
|
18
46
|
|
@@ -71,7 +99,7 @@ class GitUpdateStrategy
|
|
71
99
|
include GitCommands
|
72
100
|
|
73
101
|
def initialize name
|
74
|
-
@target_folder =
|
102
|
+
@target_folder = Lace.pkgs_folder/name
|
75
103
|
end
|
76
104
|
|
77
105
|
def update
|
@@ -128,6 +156,16 @@ class GitDownloadStrategy < AbstractDownloadStrategy
|
|
128
156
|
|
129
157
|
end
|
130
158
|
|
159
|
+
class AbbrevGitDownloadStrategy < GitDownloadStrategy
|
160
|
+
def initialize uri
|
161
|
+
unless uri.end_with?(".git")
|
162
|
+
uri = "#{uri}.git"
|
163
|
+
end
|
164
|
+
uri = "https://github.com/#{uri}"
|
165
|
+
super uri
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
131
169
|
|
132
170
|
class DownloadStrategyDetector
|
133
171
|
def self.detect(uri, strategy=nil)
|
@@ -142,10 +180,14 @@ class DownloadStrategyDetector
|
|
142
180
|
end
|
143
181
|
|
144
182
|
def self.detect_from_uri(uri)
|
145
|
-
|
183
|
+
is_git_dir = File.directory?(uri+"/.git")
|
184
|
+
has_single_slash = uri.scan("/").count == 1
|
185
|
+
if File.directory?(uri) && !is_git_dir
|
146
186
|
return LocalFileStrategy
|
147
|
-
elsif
|
187
|
+
elsif is_git_dir
|
148
188
|
return GitDownloadStrategy
|
189
|
+
elsif has_single_slash
|
190
|
+
return AbbrevGitDownloadStrategy
|
149
191
|
end
|
150
192
|
|
151
193
|
case uri
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'erb'
|
3
|
+
|
4
|
+
class PackageFacts
|
5
|
+
attr_reader :facts_file
|
6
|
+
|
7
|
+
def inspect
|
8
|
+
"#<Facts:#{@package_path}>"
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize package_path
|
12
|
+
@package_path = Pathname.new(package_path)
|
13
|
+
@facts_file = @package_path/".lace.yml"
|
14
|
+
raise PackageFactsNotFound.new(@package_path) unless @facts_file.exist?
|
15
|
+
@facts = facts_file_to_hash
|
16
|
+
@unflavorable_facts = facts_file_to_hash
|
17
|
+
end
|
18
|
+
|
19
|
+
def flavor_with the_flavor
|
20
|
+
if has_flavors? && the_flavor.nil?
|
21
|
+
raise FlavorArgumentRequired.new flavors
|
22
|
+
elsif has_flavors? && the_flavor != false
|
23
|
+
flavor! the_flavor
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def config_files
|
28
|
+
if @unflavorable_facts.nil? or @facts["config_files"].nil?
|
29
|
+
[]
|
30
|
+
else
|
31
|
+
@facts["config_files"].flatten.map do |file|
|
32
|
+
@package_path + file
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def has_flavors?
|
38
|
+
@unflavorable_facts && !@unflavorable_facts["flavors"].nil?
|
39
|
+
end
|
40
|
+
|
41
|
+
def has_key? key
|
42
|
+
@unflavorable_facts && @unflavorable_facts.has_key?(key)
|
43
|
+
end
|
44
|
+
|
45
|
+
def version
|
46
|
+
@unflavorable_facts["version"] if @unflavorable_facts.key? "version"
|
47
|
+
end
|
48
|
+
|
49
|
+
def setup_files
|
50
|
+
@facts["setup"].flatten rescue []
|
51
|
+
end
|
52
|
+
|
53
|
+
def homepage
|
54
|
+
@unflavorable_facts["homepage"] if @unflavorable_facts.key? "homepage"
|
55
|
+
end
|
56
|
+
|
57
|
+
def flavors
|
58
|
+
if @unflavorable_facts && @unflavorable_facts.key?("flavors")
|
59
|
+
@unflavorable_facts["flavors"].keys.sort
|
60
|
+
else
|
61
|
+
[]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def flavor! the_flavor
|
66
|
+
raise PackageFlavorDoesNotExist.new(the_flavor, flavors) unless flavors.include? the_flavor
|
67
|
+
@facts = @unflavorable_facts["flavors"][the_flavor]
|
68
|
+
end
|
69
|
+
|
70
|
+
def unflavor!
|
71
|
+
@facts = @unflavorable_facts
|
72
|
+
end
|
73
|
+
|
74
|
+
def post hook_point
|
75
|
+
if @unflavorable_facts.nil? or !@facts.key? "post"
|
76
|
+
[]
|
77
|
+
else
|
78
|
+
post_hook = @facts["post"]
|
79
|
+
(post_hook[hook_point.to_s] || []).flatten
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
protected
|
84
|
+
def facts_file_to_hash
|
85
|
+
begin
|
86
|
+
rendered_manifest = ERB.new(@facts_file.read, nil, '-').result(binding)
|
87
|
+
rescue Exception => e
|
88
|
+
raise ManifestErbError.new(self, e)
|
89
|
+
end
|
90
|
+
value = YAML.load rendered_manifest
|
91
|
+
if value.is_a?(String) && value == "---"
|
92
|
+
return Hash.new
|
93
|
+
else
|
94
|
+
value
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
require 'lace/download_strategy'
|
4
|
+
|
5
|
+
class Package
|
6
|
+
include GitCommands
|
7
|
+
attr_reader :name, :facts, :path
|
8
|
+
|
9
|
+
def initialize name, flavor=nil
|
10
|
+
require 'cmd/list'
|
11
|
+
raise PackageNotInstalled.new(name) unless Lace.installed_packages.include?(name)
|
12
|
+
@name = name
|
13
|
+
@path = Lace.pkgs_folder/name
|
14
|
+
@flavor = flavor
|
15
|
+
read_facts!
|
16
|
+
end
|
17
|
+
|
18
|
+
def setup
|
19
|
+
return if ARGV.nohooks?
|
20
|
+
ENV['LACEPKG_PATH'] = @path
|
21
|
+
@path.cd do
|
22
|
+
facts.setup_files.each do |cmd|
|
23
|
+
safe_system cmd
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def after_update
|
29
|
+
return if ARGV.nohooks?
|
30
|
+
@path.cd do
|
31
|
+
facts.post(:update).each do |cmd|
|
32
|
+
system cmd
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def is_git_repo?
|
38
|
+
@target_folder = @path
|
39
|
+
repo_valid?
|
40
|
+
end
|
41
|
+
|
42
|
+
def is_active?
|
43
|
+
if @facts.has_flavors? && @flavor == false
|
44
|
+
@facts.flavors.any?{|f| Package.new(@name, f).is_active?}
|
45
|
+
else
|
46
|
+
linked_files = Set.new Lace.linked_files.map(&:to_s)
|
47
|
+
config_files = Set.new @facts.config_files.map(&:to_s)
|
48
|
+
config_files.subset? linked_files
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def read_facts!
|
53
|
+
@facts = PackageFacts.new @path
|
54
|
+
@facts.flavor_with @flavor
|
55
|
+
end
|
56
|
+
|
57
|
+
def deactivate!
|
58
|
+
files = @facts.config_files
|
59
|
+
home_dir = ENV["HOME"]
|
60
|
+
files.each do |file|
|
61
|
+
file = Pathname.new(file)
|
62
|
+
dotfile = file.as_dotfile(home_dir)
|
63
|
+
FileUtils.rm_f dotfile if dotfile.exist? && dotfile.readlink == file
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def activate!
|
68
|
+
files = @facts.config_files
|
69
|
+
home_dir = ENV["HOME"]
|
70
|
+
files.each do |file|
|
71
|
+
# if ends in erb -> generate it
|
72
|
+
FileUtils.ln_s file, Pathname.new(file).as_dotfile(home_dir), :force => ARGV.force?
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'lace/exceptions'
|
2
|
+
|
3
|
+
class PackageUtils
|
4
|
+
|
5
|
+
def self.fetch uri, desired_package_name=nil
|
6
|
+
downloader_cls = DownloadStrategyDetector.detect(uri)
|
7
|
+
downloader = downloader_cls.new(uri, desired_package_name)
|
8
|
+
raise PackageAlreadyInstalled.new if downloader.target_folder.exist?
|
9
|
+
downloader.fetch
|
10
|
+
return downloader.name, downloader.target_folder
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.remove package_name
|
14
|
+
package = Package.new(package_name, false)
|
15
|
+
raise CannotRemoveActivePackage.new if package.is_active?
|
16
|
+
ohai "Removing"
|
17
|
+
FileUtils.rm_rf package.path
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.setup package_name
|
21
|
+
begin
|
22
|
+
package = Package.new(package_name, ARGV.first)
|
23
|
+
package.activate!
|
24
|
+
package.setup
|
25
|
+
rescue FlavorError => e
|
26
|
+
onoe e.message
|
27
|
+
onoe "Package remains installed but was not activated"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.deactivate package_name
|
32
|
+
package = Package.new(package_name, ARGV.first)
|
33
|
+
raise NonActiveFlavorError.new unless package.is_active? || ARGV.force?
|
34
|
+
ohai "Deactivating"
|
35
|
+
package.deactivate!
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.activate package_name
|
39
|
+
package = Package.new(package_name, ARGV.first)
|
40
|
+
raise AlreadyActiveError.new if Package.new(package_name, false).is_active?
|
41
|
+
ohai "Activating"
|
42
|
+
package.activate!
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.update package_name
|
46
|
+
package = Package.new(package_name, false)
|
47
|
+
raise OnlyGitReposCanBeUpdatedError.new unless package.is_git_repo?
|
48
|
+
updater = GitUpdateStrategy.new(package_name)
|
49
|
+
was_active_before_update = package.is_active?
|
50
|
+
self.deactivate(package_name) if was_active_before_update
|
51
|
+
ohai "Updating"
|
52
|
+
updater.update
|
53
|
+
self.activate(package_name) if was_active_before_update
|
54
|
+
package = Package.new package_name, false
|
55
|
+
package.after_update
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
|
data/lib/lace/package.rb
CHANGED
@@ -1,229 +1,5 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
require '
|
4
|
-
require 'erb'
|
1
|
+
require 'lace/package/utils'
|
2
|
+
require 'lace/package/facts'
|
3
|
+
require 'lace/package/package'
|
5
4
|
|
6
|
-
require 'lace/download_strategy'
|
7
|
-
require 'lace/exceptions'
|
8
5
|
|
9
|
-
class PackageUtils
|
10
|
-
def self.has_active_flavors name
|
11
|
-
@path = LACE_PKGS_FOLDER/name
|
12
|
-
facts = Facts.new @path
|
13
|
-
facts.flavors.any?{|f| Package.new(@name, f).is_active? }
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.fetch uri
|
17
|
-
downloader = DownloadStrategyDetector.detect(uri).new(uri)
|
18
|
-
raise PackageAlreadyInstalled.new if downloader.target_folder.exist?
|
19
|
-
downloader.fetch
|
20
|
-
return downloader.name, downloader.target_folder
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.remove package_name
|
24
|
-
package = Package.new package_name, false
|
25
|
-
raise CannotRemoveActivePackage.new if package.is_active?
|
26
|
-
ohai "Removing"
|
27
|
-
FileUtils.rm_rf package.path
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.setup package_name
|
31
|
-
begin
|
32
|
-
package = Package.new package_name, ARGV.first
|
33
|
-
package.activate!
|
34
|
-
package.setup
|
35
|
-
rescue FlavorError => e
|
36
|
-
onoe e.message
|
37
|
-
onoe "Package remains installed but was not activated"
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.deactivate package_name
|
42
|
-
package = Package.new package_name, ARGV.first
|
43
|
-
raise NonActiveFlavorError.new unless package.is_active? || ARGV.force?
|
44
|
-
ohai "Deactivating"
|
45
|
-
package.deactivate!
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.activate package_name
|
49
|
-
package = Package.new package_name, ARGV.first
|
50
|
-
raise AlreadyActiveError.new if Package.new(package_name, false).is_active?
|
51
|
-
ohai "Activating"
|
52
|
-
package.activate!
|
53
|
-
end
|
54
|
-
|
55
|
-
def self.update package_name
|
56
|
-
package = Package.new package_name, false
|
57
|
-
raise OnlyGitReposCanBeUpdatedError.new unless package.is_git_repo?
|
58
|
-
updater = GitUpdateStrategy.new package_name
|
59
|
-
self.deactivate package_name
|
60
|
-
ohai "Updating"
|
61
|
-
updater.update
|
62
|
-
self.activate package_name
|
63
|
-
package = Package.new package_name, false
|
64
|
-
package.after_update
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
class Facts
|
69
|
-
attr_reader :facts_file
|
70
|
-
|
71
|
-
def inspect
|
72
|
-
"#<Facts:#{@package_path}>"
|
73
|
-
end
|
74
|
-
|
75
|
-
def initialize package_path
|
76
|
-
@package_path = Pathname.new(package_path)
|
77
|
-
@facts_file = @package_path/".lace.yml"
|
78
|
-
raise PackageFactsNotFound.new(@package_path) unless @facts_file.exist?
|
79
|
-
@facts = facts_file_to_hash
|
80
|
-
@_facts = facts_file_to_hash
|
81
|
-
end
|
82
|
-
|
83
|
-
def config_files
|
84
|
-
if @_facts.nil? or @facts["config_files"].nil?
|
85
|
-
[]
|
86
|
-
else
|
87
|
-
@facts["config_files"].flatten.map do |file|
|
88
|
-
@package_path + file
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
def has_flavors?
|
94
|
-
@_facts && !@_facts["flavors"].nil?
|
95
|
-
end
|
96
|
-
|
97
|
-
def has_key? key
|
98
|
-
@_facts && @_facts.has_key?(key)
|
99
|
-
end
|
100
|
-
|
101
|
-
def version
|
102
|
-
@_facts["version"] if @_facts.key? "version"
|
103
|
-
end
|
104
|
-
|
105
|
-
def setup_files
|
106
|
-
@facts["setup"].flatten rescue []
|
107
|
-
end
|
108
|
-
|
109
|
-
def homepage
|
110
|
-
@_facts["homepage"] if @_facts.key? "homepage"
|
111
|
-
end
|
112
|
-
|
113
|
-
def flavors
|
114
|
-
if @_facts && @_facts.key?("flavors")
|
115
|
-
@_facts["flavors"].keys.sort
|
116
|
-
else
|
117
|
-
[]
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
def flavor! which_flavor
|
122
|
-
raise PackageFlavorDoesNotExist.new(which_flavor, flavors) unless flavors.include? which_flavor
|
123
|
-
@facts = @_facts["flavors"][which_flavor]
|
124
|
-
end
|
125
|
-
|
126
|
-
def unflavor!
|
127
|
-
@facts = @_facts
|
128
|
-
end
|
129
|
-
|
130
|
-
def post hook_point
|
131
|
-
if @_facts.nil? or !@facts.key? "post"
|
132
|
-
[]
|
133
|
-
else
|
134
|
-
post_hook = @facts["post"]
|
135
|
-
(post_hook[hook_point.to_s] || []).flatten
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
protected
|
140
|
-
def facts_file_to_hash
|
141
|
-
begin
|
142
|
-
rendered_lace = ERB.new(@facts_file.read, nil, '-').result(binding)
|
143
|
-
rescue Exception => e
|
144
|
-
raise ManifestErbError.new(self, e)
|
145
|
-
end
|
146
|
-
value = YAML.load rendered_lace
|
147
|
-
if value.is_a?(String) && value == "---"
|
148
|
-
return Hash.new
|
149
|
-
else
|
150
|
-
value
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
class Package
|
156
|
-
include GitCommands
|
157
|
-
attr_reader :name, :facts, :path
|
158
|
-
|
159
|
-
def setup
|
160
|
-
return if ARGV.nohooks?
|
161
|
-
@path.cd do
|
162
|
-
facts.setup_files.each do |cmd|
|
163
|
-
safe_system cmd
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
def after_update
|
169
|
-
return if ARGV.nohooks?
|
170
|
-
@path.cd do
|
171
|
-
facts.post(:update).each do |cmd|
|
172
|
-
system cmd
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
def initialize name, flavor=nil
|
178
|
-
require 'cmd/list'
|
179
|
-
raise PackageNotInstalled.new(name) unless Lace.installed_packages.include? name
|
180
|
-
@name = name
|
181
|
-
@path = LACE_PKGS_FOLDER/name
|
182
|
-
@flavor = flavor
|
183
|
-
read_facts!
|
184
|
-
end
|
185
|
-
|
186
|
-
def is_git_repo?
|
187
|
-
@target_folder = @path
|
188
|
-
repo_valid?
|
189
|
-
end
|
190
|
-
|
191
|
-
def is_active?
|
192
|
-
if @facts.has_flavors? && @flavor == false
|
193
|
-
@facts.flavors.any?{|f| Package.new(@name, f).is_active?}
|
194
|
-
else
|
195
|
-
linked_files = Set.new Lace.linked_files.map(&:to_s)
|
196
|
-
config_files = Set.new @facts.config_files.map(&:to_s)
|
197
|
-
config_files.subset? linked_files
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
def read_facts!
|
202
|
-
# todo simplify
|
203
|
-
@facts = Facts.new @path
|
204
|
-
if @facts.has_flavors? && @flavor.nil?
|
205
|
-
raise FlavorArgumentRequired.new @facts.flavors
|
206
|
-
elsif @facts.has_flavors? && @flavor != false
|
207
|
-
@facts.flavor! @flavor
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
def deactivate!
|
212
|
-
files = @facts.config_files
|
213
|
-
home_dir = ENV["HOME"]
|
214
|
-
files.each do |file|
|
215
|
-
file = Pathname.new(file)
|
216
|
-
dotfile = file.as_dotfile(home_dir)
|
217
|
-
FileUtils.rm_f dotfile if dotfile.exist? && dotfile.readlink == file
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
def activate!
|
222
|
-
files = @facts.config_files
|
223
|
-
home_dir = ENV["HOME"]
|
224
|
-
files.each do |file|
|
225
|
-
# if ends in erb -> generate it
|
226
|
-
FileUtils.ln_s file, Pathname.new(file).as_dotfile(home_dir), :force => ARGV.force?
|
227
|
-
end
|
228
|
-
end
|
229
|
-
end
|
data/lib/lace/utils.rb
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
#Copyright 2009-2014 Max Howell and other contributors.
|
2
|
+
#
|
3
|
+
#Redistribution and use in source and binary forms, with or without
|
4
|
+
#modification, are permitted provided that the following conditions
|
5
|
+
#are met:
|
6
|
+
#
|
7
|
+
# 1. Redistributions of source code must retain the above copyright
|
8
|
+
# notice, this list of conditions and the following disclaimer.
|
9
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
10
|
+
# notice, this list of conditions and the following disclaimer in the
|
11
|
+
# documentation and/or other materials provided with the distribution.
|
12
|
+
#
|
13
|
+
#THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
14
|
+
#IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
15
|
+
#OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
16
|
+
#IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
17
|
+
#INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
18
|
+
#NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
19
|
+
#DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
20
|
+
#THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
21
|
+
#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
22
|
+
#THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
23
|
+
|
1
24
|
class Tty
|
2
25
|
class << self
|
3
26
|
def blue; bold 34; end
|
data/lib/lace/version.rb
CHANGED
data/lib/lace.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "lace/utils"
|
2
|
+
require "lace/exceptions"
|
3
|
+
require "lace/version"
|
4
|
+
|
5
|
+
module Lace extend self
|
6
|
+
attr_accessor :failed
|
7
|
+
alias_method :failed?, :failed
|
8
|
+
|
9
|
+
def self.pkgs_folder
|
10
|
+
packages_folder = Pathname.new(ENV["HOME"]).join(".lace.pkgs")
|
11
|
+
|
12
|
+
if ENV["LACE_FOLDER"]
|
13
|
+
packages_folder = Pathname.new(ENV["LACE_FOLDER"])
|
14
|
+
end
|
15
|
+
packages_folder
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.pstore
|
19
|
+
@pstore ||= PStore.new(pkgs_folder/".lace.pstore")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
metadata
CHANGED
@@ -1,23 +1,23 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lace
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kai Richard Koenig
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-06-03 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description:
|
14
|
-
all the different machines
|
13
|
+
description: Lace lets you manage your dotfiles when using them on multiple machines
|
15
14
|
email: kai@kairichardkoenig.de
|
16
15
|
executables:
|
17
16
|
- lace
|
18
17
|
extensions: []
|
19
18
|
extra_rdoc_files: []
|
20
19
|
files:
|
20
|
+
- bin/lace
|
21
21
|
- lib/cmd/activate.rb
|
22
22
|
- lib/cmd/deactivate.rb
|
23
23
|
- lib/cmd/fetch.rb
|
@@ -27,15 +27,19 @@ files:
|
|
27
27
|
- lib/cmd/remove.rb
|
28
28
|
- lib/cmd/setup.rb
|
29
29
|
- lib/cmd/update.rb
|
30
|
+
- lib/cmd/upgrade.rb
|
30
31
|
- lib/cmd/validate.rb
|
31
32
|
- lib/extend/ARGV.rb
|
32
33
|
- lib/extend/pathname.rb
|
34
|
+
- lib/lace.rb
|
33
35
|
- lib/lace/download_strategy.rb
|
34
36
|
- lib/lace/exceptions.rb
|
35
37
|
- lib/lace/package.rb
|
38
|
+
- lib/lace/package/facts.rb
|
39
|
+
- lib/lace/package/package.rb
|
40
|
+
- lib/lace/package/utils.rb
|
36
41
|
- lib/lace/utils.rb
|
37
42
|
- lib/lace/version.rb
|
38
|
-
- bin/lace
|
39
43
|
homepage: https://github.com/kairichard/lace
|
40
44
|
licenses:
|
41
45
|
- MIT
|
@@ -46,17 +50,17 @@ require_paths:
|
|
46
50
|
- lib
|
47
51
|
required_ruby_version: !ruby/object:Gem::Requirement
|
48
52
|
requirements:
|
49
|
-
- - '>='
|
53
|
+
- - ! '>='
|
50
54
|
- !ruby/object:Gem::Version
|
51
55
|
version: 1.8.6
|
52
56
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
57
|
requirements:
|
54
|
-
- - '>='
|
58
|
+
- - ! '>='
|
55
59
|
- !ruby/object:Gem::Version
|
56
60
|
version: '0'
|
57
61
|
requirements: []
|
58
62
|
rubyforge_project:
|
59
|
-
rubygems_version: 2.0
|
63
|
+
rubygems_version: 2.2.0
|
60
64
|
signing_key:
|
61
65
|
specification_version: 4
|
62
66
|
summary: Manage your .dotfiles
|