lace 0.3.3 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|