homedir 3.0.alpha1 → 3.0.alpha2
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.
- data/.gitignore +1 -0
- data/.travis.yml +1 -0
- data/.yardopts +6 -0
- data/Guardfile +1 -1
- data/LICENSE +19 -0
- data/bin/homedir +5 -0
- data/homedir.gemspec +17 -12
- data/lib/homedir/catalog.rb +47 -0
- data/lib/homedir/cli.rb +55 -0
- data/lib/homedir/errors.rb +17 -0
- data/lib/homedir/package.rb +110 -14
- data/lib/homedir/version.rb +1 -1
- data/lib/homedir.rb +3 -0
- data/spec/lib/homedir/catalog_spec.rb +75 -0
- data/spec/lib/homedir/package_spec.rb +37 -12
- data/spec/spec_helper.rb +11 -4
- metadata +39 -34
- data/lib/homedir/repository.rb +0 -27
- data/spec/lib/homedir/repository_spec.rb +0 -62
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/.yardopts
ADDED
data/Guardfile
CHANGED
|
@@ -7,7 +7,7 @@ guard 'bundler' do
|
|
|
7
7
|
# watch(/^.+\.gemspec/)
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
guard 'rspec', :version => 2, :cli => "--color --format doc" do
|
|
10
|
+
guard 'rspec', :version => 2, :cli => "--color --format doc --fail-fast" do
|
|
11
11
|
watch(%r{^spec/.+_spec\.rb$})
|
|
12
12
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
|
13
13
|
watch('spec/spec_helper.rb') { "spec" }
|
data/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2012 Christian Höltje
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
|
4
|
+
copy of this software and associated documentation files (the "Software"),
|
|
5
|
+
to deal in the Software without restriction, including without limitation
|
|
6
|
+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
7
|
+
and/or sell copies of the Software, and to permit persons to whom the
|
|
8
|
+
Software is furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included
|
|
11
|
+
in all copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
14
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
18
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
19
|
+
DEALINGS IN THE SOFTWARE.
|
data/bin/homedir
ADDED
data/homedir.gemspec
CHANGED
|
@@ -2,24 +2,29 @@
|
|
|
2
2
|
require File.expand_path('../lib/homedir/version', __FILE__)
|
|
3
3
|
|
|
4
4
|
Gem::Specification.new do |gem|
|
|
5
|
-
gem.authors
|
|
6
|
-
gem.email
|
|
7
|
-
gem.description
|
|
8
|
-
gem.summary
|
|
9
|
-
gem.homepage
|
|
5
|
+
gem.authors = ["Christian Holtje"]
|
|
6
|
+
gem.email = ["docwhat@gerf.org"]
|
|
7
|
+
gem.description = %q{Your home directory package management system}
|
|
8
|
+
gem.summary = %q{Manage your home manager}
|
|
9
|
+
gem.homepage = "http://home-dir.org/"
|
|
10
|
+
gem.license = "MIT"
|
|
11
|
+
gem.required_ruby_version = ">= 1.8.7"
|
|
10
12
|
|
|
11
|
-
gem.
|
|
12
|
-
|
|
13
|
-
gem.
|
|
14
|
-
gem.
|
|
15
|
-
gem.
|
|
16
|
-
gem.
|
|
13
|
+
#gem.post_install_message = "Type 'homedir' to get started!"
|
|
14
|
+
|
|
15
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
16
|
+
gem.files = `git ls-files`.split("\n")
|
|
17
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
18
|
+
gem.name = "homedir"
|
|
19
|
+
gem.require_paths = ["lib"]
|
|
20
|
+
gem.version = Homedir::VERSION
|
|
17
21
|
|
|
18
22
|
gem.add_development_dependency('rake')
|
|
19
23
|
gem.add_development_dependency('rspec', ["~> 2.8"])
|
|
20
|
-
gem.add_development_dependency('fakefs', ["~> 0.4.0"])
|
|
21
24
|
gem.add_development_dependency('factory_girl', ["~> 2.5.2"])
|
|
22
25
|
|
|
26
|
+
gem.add_development_dependency('yard')
|
|
27
|
+
|
|
23
28
|
gem.add_development_dependency('guard')
|
|
24
29
|
gem.add_development_dependency('guard-rspec')
|
|
25
30
|
gem.add_development_dependency('guard-bundler')
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'homedir/errors'
|
|
2
|
+
|
|
3
|
+
module Homedir
|
|
4
|
+
class Catalog < Set
|
|
5
|
+
|
|
6
|
+
# @param {String} name The name of the {Homedir::Package package} to find.
|
|
7
|
+
# @return {Homedir::Package} The package that matches the `name`
|
|
8
|
+
def find_by_name name
|
|
9
|
+
found = select { |pkg| pkg.name == name }
|
|
10
|
+
raise "Invalid package object(s): #{found.inspect}" unless found.length <= 1
|
|
11
|
+
found.first
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Returns all dependencies for `package` including `package` itself.
|
|
15
|
+
#
|
|
16
|
+
# @raise [Homedir::MissingDependendency] if a dependency cannot be found.
|
|
17
|
+
# @param {Homedir::Package} package The package to get dependencies for.
|
|
18
|
+
# @return {Set} The {Homedir::Package Package} objects that `package` depends on.
|
|
19
|
+
def find_all_dependencies package
|
|
20
|
+
found = Set.new([package])
|
|
21
|
+
find_all_dependencies_not_found found, package
|
|
22
|
+
return found
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
# This is the method that does the work for {#find_all_dependencies}.
|
|
28
|
+
#
|
|
29
|
+
# @param {Set} found The set of all found packages.
|
|
30
|
+
# @param {Homedir::Package} package The package to get dependencies for. It is assumed it is already in `found`
|
|
31
|
+
def find_all_dependencies_not_found found, package
|
|
32
|
+
package.dependencies.each do |dependency_name|
|
|
33
|
+
dependency = find_by_name dependency_name
|
|
34
|
+
|
|
35
|
+
raise MissingDependencyError.new(
|
|
36
|
+
"The package '#{package}' requires '#{dependency_name}' which cannot be found."
|
|
37
|
+
) if dependency.nil?
|
|
38
|
+
|
|
39
|
+
if not found.include? dependency
|
|
40
|
+
found << dependency
|
|
41
|
+
find_all_dependencies_not_found(found, dependency)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
return nil
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
data/lib/homedir/cli.rb
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require 'thor'
|
|
2
|
+
|
|
3
|
+
module Homedir
|
|
4
|
+
# The command line interface for {Homedir}.
|
|
5
|
+
#
|
|
6
|
+
# See the source or the command line tool `bin/homedir` for more
|
|
7
|
+
# information
|
|
8
|
+
class CLI < Thor
|
|
9
|
+
|
|
10
|
+
desc "list", "List all known packages."
|
|
11
|
+
method_option(
|
|
12
|
+
:remote,
|
|
13
|
+
:type => :boolean,
|
|
14
|
+
:default => false,
|
|
15
|
+
:aliases => '-r',
|
|
16
|
+
:description => "Queries the remote server")
|
|
17
|
+
def list
|
|
18
|
+
# FIXME: list needs to do something
|
|
19
|
+
puts "Not implemented yet"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
desc "info PACKAGE", "Describe a specific PACKAGE in detail."
|
|
23
|
+
def info(package_name)
|
|
24
|
+
# FIXME: info needs to do something
|
|
25
|
+
puts "Not implemented yet #{package_name.inspect}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
desc "enable PACKAGE...", "Enable PACKAGE, making it available in your home directory."
|
|
29
|
+
def enable(*packages)
|
|
30
|
+
# FIXME: info needs to do something
|
|
31
|
+
puts "Not implemented yet #{packages.inspect}"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
desc "disable PACKAGE...", "Disable PACKAGE, removing it from your home directory."
|
|
35
|
+
def disable(*packages)
|
|
36
|
+
# FIXME: info needs to do something
|
|
37
|
+
puts "Not implemented yet #{packages.inspect}"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
desc "create PACKAGE...", "Create PACKAGE, prompting you for information."
|
|
41
|
+
method_option(
|
|
42
|
+
:directory,
|
|
43
|
+
:type => :string,
|
|
44
|
+
:default => "#{ENV['HOME']}/.homedir/package",
|
|
45
|
+
:aliases => "-d",
|
|
46
|
+
:description => "Where to save the DIRECTORY."
|
|
47
|
+
)
|
|
48
|
+
def create(package_name)
|
|
49
|
+
# FIXME: info needs to do something
|
|
50
|
+
puts "Not implemented yet #{package_name.inspect}"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
|
|
2
|
+
module Homedir
|
|
3
|
+
# When possible, all exceptions raised by Homedir classes
|
|
4
|
+
# will be subclassed from {Homedir::Error}.
|
|
5
|
+
class Error < StandardError
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# If a dependency is missing from a {Homedir::Package package} (it isn't
|
|
9
|
+
# available in a {Homedir::Catalog Catalog}) then this exception is raised.
|
|
10
|
+
class MissingDependencyError < Error
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# The name assigned to a {Homedir::Package package} is not legal. Check the
|
|
14
|
+
# message for the list of acceptable characters in a name.
|
|
15
|
+
class InvalidNameError < Error
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/homedir/package.rb
CHANGED
|
@@ -1,28 +1,78 @@
|
|
|
1
|
-
require 'homedir'
|
|
1
|
+
require 'homedir/errors'
|
|
2
2
|
require 'pathname'
|
|
3
3
|
require 'fileutils'
|
|
4
4
|
require 'yaml'
|
|
5
5
|
|
|
6
|
+
# A package contains all the meta information about the package:
|
|
7
|
+
#
|
|
8
|
+
# * name, description, etc.
|
|
9
|
+
# * pre and post install instructions.
|
|
10
|
+
# * location of the package directory.
|
|
11
|
+
#
|
|
6
12
|
module Homedir
|
|
7
13
|
class Package
|
|
8
|
-
|
|
14
|
+
# A list of required values. If a value in this
|
|
15
|
+
# list isn't set, then the object isn't {#valid? valid}.
|
|
16
|
+
# @see #valid?
|
|
17
|
+
REQUIRED_VALUES = [
|
|
9
18
|
:name,
|
|
10
19
|
:description,
|
|
11
20
|
:directory,
|
|
12
21
|
].freeze
|
|
13
|
-
|
|
14
|
-
:name
|
|
15
|
-
:description
|
|
16
|
-
:dependencies
|
|
17
|
-
:post_install
|
|
18
|
-
:
|
|
19
|
-
:directory
|
|
22
|
+
DEFAULT_VALUES = {
|
|
23
|
+
:name => nil,
|
|
24
|
+
:description => nil,
|
|
25
|
+
:dependencies => [],
|
|
26
|
+
:post_install => nil,
|
|
27
|
+
:pre_uninstall => nil,
|
|
28
|
+
:directory => nil,
|
|
20
29
|
}.freeze
|
|
21
|
-
attr_accessor *DEFAULT_OPTIONS.keys
|
|
22
30
|
|
|
31
|
+
# The name of the package.
|
|
32
|
+
#
|
|
33
|
+
# * It must match the regex: `[a-zA-Z0-9_-]`.
|
|
34
|
+
# * It must match the directory it'll be written-to/read-from
|
|
35
|
+
#
|
|
36
|
+
# @return {String} The name of the package
|
|
37
|
+
attr_reader :name
|
|
23
38
|
|
|
39
|
+
# A description of the package for humans.
|
|
40
|
+
#
|
|
41
|
+
# @return {String} The description of the package
|
|
42
|
+
attr_accessor :description
|
|
43
|
+
|
|
44
|
+
# A list of package names this package depends on.
|
|
45
|
+
#
|
|
46
|
+
# When assigning a list, they can either be {Homedir::Package Package} objects or strings.
|
|
47
|
+
# @return [Enumerable] A list of package {#name names}.
|
|
48
|
+
attr_reader :dependencies
|
|
49
|
+
|
|
50
|
+
# A script that should run after install.
|
|
51
|
+
#
|
|
52
|
+
# @return {String}
|
|
53
|
+
attr_accessor :post_install
|
|
54
|
+
|
|
55
|
+
# A script to run before install.
|
|
56
|
+
attr_accessor :pre_uninstall
|
|
57
|
+
|
|
58
|
+
# The directory where the package is stored.
|
|
59
|
+
#
|
|
60
|
+
# * The directory's basename must match {#name}.
|
|
61
|
+
#
|
|
62
|
+
# @return {Pathname}
|
|
63
|
+
attr_reader :directory
|
|
64
|
+
|
|
65
|
+
# Create a new {Homedir::Package Package} instance.
|
|
66
|
+
#
|
|
67
|
+
# @param {Hash} options
|
|
68
|
+
# @option options [String] :name The name of the package.
|
|
69
|
+
# @option options [String] :description The description of the package.
|
|
70
|
+
# @option options [Enumerable] :dependencies A list of {Homedir::Package packages} or {String strings}.
|
|
71
|
+
# @option options [Pathname] :directory The directory the packages is located at.
|
|
72
|
+
# @option options [String] :post_install Commands to run after installing the package.
|
|
73
|
+
# @option options [String] :pre_uninstall Commands to run before uninstalling the package.
|
|
24
74
|
def initialize(options = {})
|
|
25
|
-
options =
|
|
75
|
+
options = DEFAULT_VALUES.merge(options)
|
|
26
76
|
|
|
27
77
|
# Set the options
|
|
28
78
|
options.each do |k,v|
|
|
@@ -30,19 +80,47 @@ module Homedir
|
|
|
30
80
|
end
|
|
31
81
|
end
|
|
32
82
|
|
|
83
|
+
# The hashes are based on the name
|
|
84
|
+
# @return {Fixnum} The hash
|
|
85
|
+
def hash
|
|
86
|
+
@name.hash
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Returns true if the packages have the same name.
|
|
90
|
+
#
|
|
91
|
+
# @param {Homedir::Package} other The package to check for equality to.
|
|
92
|
+
# @return {Boolean} `true` if the `name` matches.
|
|
93
|
+
def eql?(other)
|
|
94
|
+
if other.respond_to? :name
|
|
95
|
+
other.name == @name
|
|
96
|
+
else
|
|
97
|
+
false
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# {include:#dependencies}
|
|
33
102
|
def dependencies= value
|
|
34
103
|
@dependencies = value.map { |p| p.to_s }
|
|
35
104
|
end
|
|
36
105
|
|
|
106
|
+
# {include:#directory}
|
|
37
107
|
def directory= value
|
|
38
108
|
@directory = value.nil? ? nil : Pathname.new(value)
|
|
39
109
|
end
|
|
40
110
|
|
|
111
|
+
# {include:#name}
|
|
112
|
+
# @param {String} value The new name for the package.
|
|
113
|
+
# @raise [Homedir::InvalidNameError] If the name doesn't match the regexp `/^[0-9a-zA-Z_-]+$/`
|
|
41
114
|
def name= value
|
|
42
|
-
raise
|
|
115
|
+
raise InvalidNameError.new(
|
|
116
|
+
"The name #{value.inspect} must only contain numbers, letters, `_` and `-`"
|
|
117
|
+
) unless value.nil? || value =~ /^[0-9a-zA-Z_-]+$/
|
|
43
118
|
@name = value
|
|
44
119
|
end
|
|
45
120
|
|
|
121
|
+
# Saves the package info to {#directory}`/.homedir/` if it {#valid? valid}.
|
|
122
|
+
#
|
|
123
|
+
# @see #valid?
|
|
46
124
|
def save!
|
|
47
125
|
raise "The package is not valid: #{self}" unless valid?
|
|
48
126
|
|
|
@@ -54,12 +132,30 @@ module Homedir
|
|
|
54
132
|
end
|
|
55
133
|
end
|
|
56
134
|
|
|
135
|
+
# Verifies the package is valid to save.
|
|
136
|
+
#
|
|
137
|
+
# @return {Boolean} `true` if the package is valid.
|
|
57
138
|
def valid?
|
|
58
|
-
|
|
59
|
-
|
|
139
|
+
errors = []
|
|
140
|
+
REQUIRED_VALUES.each do |value|
|
|
141
|
+
errors << "#{value} must not be empty." if instance_variable_get("@#{value}").nil?
|
|
60
142
|
end
|
|
143
|
+
# FIXME: This should check that .directory.basename == .name
|
|
144
|
+
@errors = errors
|
|
145
|
+
@errors.length == 0
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# A list of errors
|
|
149
|
+
#
|
|
150
|
+
# This list is only filled after {#.valid?} is run.
|
|
151
|
+
# @return [Array] An array of strings describing the problems.
|
|
152
|
+
def errors
|
|
153
|
+
@errors || []
|
|
61
154
|
end
|
|
62
155
|
|
|
156
|
+
# Returns the {#name} attribute
|
|
157
|
+
#
|
|
158
|
+
# @return {String} The {#name} of the package.
|
|
63
159
|
def to_s
|
|
64
160
|
@name
|
|
65
161
|
end
|
data/lib/homedir/version.rb
CHANGED
data/lib/homedir.rb
CHANGED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'homedir/catalog'
|
|
3
|
+
require 'homedir/errors'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
describe Homedir::Catalog do
|
|
7
|
+
def mkpkg(name, dependencies=[])
|
|
8
|
+
double(name).tap do |pkg|
|
|
9
|
+
pkg.stub(:name) { name }
|
|
10
|
+
pkg.stub(:dependencies) { dependencies }
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe ".add" do
|
|
15
|
+
it "adds the package to the catalog" do
|
|
16
|
+
pkg = mkpkg('somename')
|
|
17
|
+
subject.add pkg
|
|
18
|
+
subject.should include(pkg)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe ".find_all_dependencies" do
|
|
23
|
+
let(:pkg) { mkpkg('pkg', ['pkg2']) }
|
|
24
|
+
|
|
25
|
+
context "in an acyclic graph" do
|
|
26
|
+
before(:each) do
|
|
27
|
+
subject.add mkpkg('pkg2', ['pkg3'])
|
|
28
|
+
subject.add mkpkg('pkg3')
|
|
29
|
+
subject.add mkpkg('lonelypkg')
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "should all dependencies" do
|
|
33
|
+
dependents = subject.find_all_dependencies(pkg)
|
|
34
|
+
dependents.size.should == 3
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "should be packages" do
|
|
38
|
+
dependents = subject.find_all_dependencies(pkg)
|
|
39
|
+
dependents.each do |p|
|
|
40
|
+
p.should respond_to(:name)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context "in a cyclic graph" do
|
|
46
|
+
before(:each) do
|
|
47
|
+
subject.add pkg
|
|
48
|
+
subject.add mkpkg('pkg2', [pkg.name])
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should return only two" do
|
|
52
|
+
dependents = subject.find_all_dependencies(pkg)
|
|
53
|
+
dependents.size.should == 2
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
context "with a missing dependency" do
|
|
58
|
+
it "should raise an error" do
|
|
59
|
+
expect { subject.find_all_dependencies(pkg) }.to raise_error(Homedir::MissingDependencyError)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
describe ".find_by_name" do
|
|
65
|
+
let(:pkg) { mkpkg('a-name') }
|
|
66
|
+
before(:each) do
|
|
67
|
+
subject.add(pkg)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "return pkg" do
|
|
71
|
+
subject.find_by_name(pkg.name).should == pkg
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
require 'homedir/package'
|
|
3
|
+
require 'homedir/errors'
|
|
3
4
|
require 'pathname'
|
|
4
5
|
|
|
5
6
|
describe Homedir::Package do
|
|
6
7
|
|
|
7
|
-
context "loading a v3 package from disk" do
|
|
8
|
-
describe "#read_from_directory"
|
|
9
|
-
end
|
|
10
|
-
|
|
11
8
|
describe "#new" do
|
|
12
9
|
context "creating a package from scratch" do
|
|
13
10
|
describe "dependencies" do
|
|
@@ -36,24 +33,52 @@ describe Homedir::Package do
|
|
|
36
33
|
end
|
|
37
34
|
end
|
|
38
35
|
|
|
39
|
-
describe "
|
|
40
|
-
it "should
|
|
36
|
+
describe ".hash" do
|
|
37
|
+
it "should be the same for two identically named packages" do
|
|
38
|
+
pkg1 = build(:package, :name => 'samename')
|
|
39
|
+
pkg2 = build(:package, :name => pkg1.name)
|
|
40
|
+
pkg1.hash.should == pkg2.hash
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe ".eql?" do
|
|
45
|
+
it "should be true for identically named packages" do
|
|
46
|
+
pkg1 = build(:package, :name => 'samename')
|
|
47
|
+
pkg2 = build(:package, :name => pkg1.name)
|
|
48
|
+
pkg1.should eql(pkg2)
|
|
49
|
+
end
|
|
41
50
|
end
|
|
42
51
|
|
|
43
52
|
describe ".name" do
|
|
44
|
-
it "
|
|
53
|
+
it "cannot have spaces" do
|
|
45
54
|
pkg = build(:package)
|
|
46
|
-
expect { pkg.name = "a name" }.to raise_error
|
|
55
|
+
expect { pkg.name = "a name" }.to raise_error(Homedir::InvalidNameError)
|
|
47
56
|
end
|
|
48
57
|
end
|
|
49
58
|
|
|
50
59
|
describe ".valid?" do
|
|
51
|
-
|
|
52
|
-
|
|
60
|
+
context "name" do
|
|
61
|
+
it "is required" do
|
|
62
|
+
build(:package, :name => nil).should_not be_valid
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "should be shown in .errors" do
|
|
66
|
+
pkg = build(:package, :name => nil)
|
|
67
|
+
pkg.valid?
|
|
68
|
+
pkg.errors.join.should include("name must not be empty")
|
|
69
|
+
end
|
|
53
70
|
end
|
|
54
71
|
|
|
55
|
-
|
|
56
|
-
|
|
72
|
+
context "description" do
|
|
73
|
+
it "should require a description" do
|
|
74
|
+
build(:package, :description => nil).should_not be_valid
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "should be shown in .errors" do
|
|
78
|
+
pkg = build(:package, :description=> nil)
|
|
79
|
+
pkg.valid?
|
|
80
|
+
pkg.errors.join.should include("description must not be empty")
|
|
81
|
+
end
|
|
57
82
|
end
|
|
58
83
|
end
|
|
59
84
|
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
require '
|
|
2
|
-
require 'fakefs/spec_helpers'
|
|
1
|
+
require 'tmpdir'
|
|
3
2
|
require 'factory_girl'
|
|
4
3
|
require 'factories'
|
|
5
4
|
|
|
5
|
+
def within_a_tmpdir
|
|
6
|
+
Dir.mktmpdir('homedir-spec-') do |dir|
|
|
7
|
+
Dir.chdir(dir)
|
|
8
|
+
yield
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
6
12
|
RSpec.configure do |config|
|
|
7
13
|
# Allows using build(), create(), etc. without the "FactoryGirl." part.
|
|
8
14
|
config.include FactoryGirl::Syntax::Methods
|
|
9
15
|
|
|
10
|
-
|
|
11
|
-
|
|
16
|
+
config.around(:each) do |example|
|
|
17
|
+
within_a_tmpdir(&example)
|
|
18
|
+
end
|
|
12
19
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: homedir
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.0.
|
|
4
|
+
version: 3.0.alpha2
|
|
5
5
|
prerelease: 4
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,11 +9,11 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2012-02-
|
|
12
|
+
date: 2012-02-18 00:00:00.000000000Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rake
|
|
16
|
-
requirement: &
|
|
16
|
+
requirement: &70240106090360 !ruby/object:Gem::Requirement
|
|
17
17
|
none: false
|
|
18
18
|
requirements:
|
|
19
19
|
- - ! '>='
|
|
@@ -21,10 +21,10 @@ dependencies:
|
|
|
21
21
|
version: '0'
|
|
22
22
|
type: :development
|
|
23
23
|
prerelease: false
|
|
24
|
-
version_requirements: *
|
|
24
|
+
version_requirements: *70240106090360
|
|
25
25
|
- !ruby/object:Gem::Dependency
|
|
26
26
|
name: rspec
|
|
27
|
-
requirement: &
|
|
27
|
+
requirement: &70240106089100 !ruby/object:Gem::Requirement
|
|
28
28
|
none: false
|
|
29
29
|
requirements:
|
|
30
30
|
- - ~>
|
|
@@ -32,32 +32,32 @@ dependencies:
|
|
|
32
32
|
version: '2.8'
|
|
33
33
|
type: :development
|
|
34
34
|
prerelease: false
|
|
35
|
-
version_requirements: *
|
|
35
|
+
version_requirements: *70240106089100
|
|
36
36
|
- !ruby/object:Gem::Dependency
|
|
37
|
-
name:
|
|
38
|
-
requirement: &
|
|
37
|
+
name: factory_girl
|
|
38
|
+
requirement: &70240106087000 !ruby/object:Gem::Requirement
|
|
39
39
|
none: false
|
|
40
40
|
requirements:
|
|
41
41
|
- - ~>
|
|
42
42
|
- !ruby/object:Gem::Version
|
|
43
|
-
version:
|
|
43
|
+
version: 2.5.2
|
|
44
44
|
type: :development
|
|
45
45
|
prerelease: false
|
|
46
|
-
version_requirements: *
|
|
46
|
+
version_requirements: *70240106087000
|
|
47
47
|
- !ruby/object:Gem::Dependency
|
|
48
|
-
name:
|
|
49
|
-
requirement: &
|
|
48
|
+
name: yard
|
|
49
|
+
requirement: &70240106085920 !ruby/object:Gem::Requirement
|
|
50
50
|
none: false
|
|
51
51
|
requirements:
|
|
52
|
-
- -
|
|
52
|
+
- - ! '>='
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version:
|
|
54
|
+
version: '0'
|
|
55
55
|
type: :development
|
|
56
56
|
prerelease: false
|
|
57
|
-
version_requirements: *
|
|
57
|
+
version_requirements: *70240106085920
|
|
58
58
|
- !ruby/object:Gem::Dependency
|
|
59
59
|
name: guard
|
|
60
|
-
requirement: &
|
|
60
|
+
requirement: &70240106084680 !ruby/object:Gem::Requirement
|
|
61
61
|
none: false
|
|
62
62
|
requirements:
|
|
63
63
|
- - ! '>='
|
|
@@ -65,10 +65,10 @@ dependencies:
|
|
|
65
65
|
version: '0'
|
|
66
66
|
type: :development
|
|
67
67
|
prerelease: false
|
|
68
|
-
version_requirements: *
|
|
68
|
+
version_requirements: *70240106084680
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
70
|
name: guard-rspec
|
|
71
|
-
requirement: &
|
|
71
|
+
requirement: &70240106083380 !ruby/object:Gem::Requirement
|
|
72
72
|
none: false
|
|
73
73
|
requirements:
|
|
74
74
|
- - ! '>='
|
|
@@ -76,10 +76,10 @@ dependencies:
|
|
|
76
76
|
version: '0'
|
|
77
77
|
type: :development
|
|
78
78
|
prerelease: false
|
|
79
|
-
version_requirements: *
|
|
79
|
+
version_requirements: *70240106083380
|
|
80
80
|
- !ruby/object:Gem::Dependency
|
|
81
81
|
name: guard-bundler
|
|
82
|
-
requirement: &
|
|
82
|
+
requirement: &70240106081940 !ruby/object:Gem::Requirement
|
|
83
83
|
none: false
|
|
84
84
|
requirements:
|
|
85
85
|
- - ! '>='
|
|
@@ -87,10 +87,10 @@ dependencies:
|
|
|
87
87
|
version: '0'
|
|
88
88
|
type: :development
|
|
89
89
|
prerelease: false
|
|
90
|
-
version_requirements: *
|
|
90
|
+
version_requirements: *70240106081940
|
|
91
91
|
- !ruby/object:Gem::Dependency
|
|
92
92
|
name: rb-fsevent
|
|
93
|
-
requirement: &
|
|
93
|
+
requirement: &70240106080280 !ruby/object:Gem::Requirement
|
|
94
94
|
none: false
|
|
95
95
|
requirements:
|
|
96
96
|
- - ! '>='
|
|
@@ -98,10 +98,10 @@ dependencies:
|
|
|
98
98
|
version: '0'
|
|
99
99
|
type: :development
|
|
100
100
|
prerelease: false
|
|
101
|
-
version_requirements: *
|
|
101
|
+
version_requirements: *70240106080280
|
|
102
102
|
- !ruby/object:Gem::Dependency
|
|
103
103
|
name: growl
|
|
104
|
-
requirement: &
|
|
104
|
+
requirement: &70240106078640 !ruby/object:Gem::Requirement
|
|
105
105
|
none: false
|
|
106
106
|
requirements:
|
|
107
107
|
- - ! '>='
|
|
@@ -109,31 +109,38 @@ dependencies:
|
|
|
109
109
|
version: '0'
|
|
110
110
|
type: :development
|
|
111
111
|
prerelease: false
|
|
112
|
-
version_requirements: *
|
|
112
|
+
version_requirements: *70240106078640
|
|
113
113
|
description: Your home directory package management system
|
|
114
114
|
email:
|
|
115
115
|
- docwhat@gerf.org
|
|
116
|
-
executables:
|
|
116
|
+
executables:
|
|
117
|
+
- homedir
|
|
117
118
|
extensions: []
|
|
118
119
|
extra_rdoc_files: []
|
|
119
120
|
files:
|
|
120
121
|
- .gitignore
|
|
121
122
|
- .travis.yml
|
|
123
|
+
- .yardopts
|
|
122
124
|
- Gemfile
|
|
123
125
|
- Guardfile
|
|
126
|
+
- LICENSE
|
|
124
127
|
- README.mkd
|
|
125
128
|
- Rakefile
|
|
129
|
+
- bin/homedir
|
|
126
130
|
- homedir.gemspec
|
|
127
131
|
- lib/homedir.rb
|
|
132
|
+
- lib/homedir/catalog.rb
|
|
133
|
+
- lib/homedir/cli.rb
|
|
134
|
+
- lib/homedir/errors.rb
|
|
128
135
|
- lib/homedir/package.rb
|
|
129
|
-
- lib/homedir/repository.rb
|
|
130
136
|
- lib/homedir/version.rb
|
|
131
137
|
- spec/factories.rb
|
|
138
|
+
- spec/lib/homedir/catalog_spec.rb
|
|
132
139
|
- spec/lib/homedir/package_spec.rb
|
|
133
|
-
- spec/lib/homedir/repository_spec.rb
|
|
134
140
|
- spec/spec_helper.rb
|
|
135
141
|
homepage: http://home-dir.org/
|
|
136
|
-
licenses:
|
|
142
|
+
licenses:
|
|
143
|
+
- MIT
|
|
137
144
|
post_install_message:
|
|
138
145
|
rdoc_options: []
|
|
139
146
|
require_paths:
|
|
@@ -143,10 +150,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
143
150
|
requirements:
|
|
144
151
|
- - ! '>='
|
|
145
152
|
- !ruby/object:Gem::Version
|
|
146
|
-
version:
|
|
147
|
-
segments:
|
|
148
|
-
- 0
|
|
149
|
-
hash: -3141288371879137994
|
|
153
|
+
version: 1.8.7
|
|
150
154
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
151
155
|
none: false
|
|
152
156
|
requirements:
|
|
@@ -161,6 +165,7 @@ specification_version: 3
|
|
|
161
165
|
summary: Manage your home manager
|
|
162
166
|
test_files:
|
|
163
167
|
- spec/factories.rb
|
|
168
|
+
- spec/lib/homedir/catalog_spec.rb
|
|
164
169
|
- spec/lib/homedir/package_spec.rb
|
|
165
|
-
- spec/lib/homedir/repository_spec.rb
|
|
166
170
|
- spec/spec_helper.rb
|
|
171
|
+
has_rdoc:
|
data/lib/homedir/repository.rb
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
require 'pathname'
|
|
2
|
-
require 'homedir/package'
|
|
3
|
-
|
|
4
|
-
class Homedir::Repository
|
|
5
|
-
attr_reader :directory, :package_loader, :packages, :name
|
|
6
|
-
|
|
7
|
-
def initialize(directory, options={})
|
|
8
|
-
options = {
|
|
9
|
-
:package_loader => Homedir::Package,
|
|
10
|
-
}.merge(options)
|
|
11
|
-
@directory = Pathname.new(directory)
|
|
12
|
-
@name = @directory.basename.to_s
|
|
13
|
-
@package_loader = options[:package_loader]
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def scan
|
|
17
|
-
packages = []
|
|
18
|
-
directory.each_entry do |entry|
|
|
19
|
-
next if entry.to_s.start_with? '.'
|
|
20
|
-
path = directory + entry
|
|
21
|
-
packages << package_loader.load_directory(path)
|
|
22
|
-
end
|
|
23
|
-
@packages = packages.freeze
|
|
24
|
-
return @packages
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
end
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'homedir/repository'
|
|
3
|
-
require 'pathname'
|
|
4
|
-
|
|
5
|
-
describe Homedir::Repository do
|
|
6
|
-
subject { Homedir::Repository.new directory, :package_loader => package_loader }
|
|
7
|
-
let(:package_loader) do
|
|
8
|
-
double().tap do |pl|
|
|
9
|
-
# :package is a placeholder for a Package instance
|
|
10
|
-
pl.stub(:load_directory) { :package }
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
let(:directory) { Pathname.new('/') } # an absolute directory
|
|
14
|
-
let(:package_dirs) { (1..10).map { |n| directory + "package-#{n}" } }
|
|
15
|
-
|
|
16
|
-
before(:each) do
|
|
17
|
-
# We need to make the directories exist so it can be scaned
|
|
18
|
-
package_dirs.each { |p| p.mkdir }
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
describe "#new" do
|
|
22
|
-
subject { Homedir::Repository }
|
|
23
|
-
|
|
24
|
-
it "should take a directory name" do
|
|
25
|
-
subject.new directory.to_s
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
it "should accept a pathname object" do
|
|
29
|
-
subject.new directory
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it "should accept a Package class" do
|
|
33
|
-
subject.new directory, :package_loader => double()
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
describe ".scan" do
|
|
38
|
-
it "should load each package" do
|
|
39
|
-
package_dirs.each do |p|
|
|
40
|
-
package_loader.should_receive(:load_directory).with(p)
|
|
41
|
-
end
|
|
42
|
-
subject.scan.size.should == package_dirs.size
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
describe ".packages" do
|
|
47
|
-
it "should contain package objects" do
|
|
48
|
-
subject.scan
|
|
49
|
-
subject.packages.each do |p|
|
|
50
|
-
p.should == :package
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
describe ".name" do
|
|
56
|
-
it "should return the basename of the directory" do
|
|
57
|
-
repo = Homedir::Repository.new Pathname.new('/a/b/my-name')
|
|
58
|
-
repo.name.should == 'my-name'
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
end
|