jeni 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Bugs.rdoc +6 -0
- data/Gemfile +14 -0
- data/History.txt +9 -0
- data/Intro.txt +3 -0
- data/LICENCE.rdoc +159 -0
- data/README.md +188 -0
- data/lib/jeni.rb +374 -0
- data/lib/jeni/actions.rb +400 -0
- data/lib/jeni/errors.rb +22 -0
- data/lib/jeni/io.rb +71 -0
- data/lib/jeni/options.rb +68 -0
- data/lib/jeni/optparse.rb +84 -0
- data/lib/jeni/utils.rb +181 -0
- data/lib/jeni/version.rb +13 -0
- data/spec/jeni_spec.rb +85 -0
- data/spec/jeni_utils_spec.rb +297 -0
- data/spec/spec_helper.rb +26 -0
- data/test/examples/source/coati.haml.conf +37 -0
- data/test/examples/source/executable +3 -0
- data/test/examples/source/jenny-diff.rb +64 -0
- data/test/examples/source/jenny.rb +63 -0
- data/test/examples/source/shebang.rb +3 -0
- data/test/examples/source/subfiles/subfile_1.rb +63 -0
- data/test/examples/source/template.haml.rb +10 -0
- data/test/examples/target/archive/coati.haml.conf +37 -0
- data/test/examples/target/archive/executable +3 -0
- data/test/examples/target/archive/jenny-diff.rb +64 -0
- data/test/examples/target/archive/jenny.rb +63 -0
- data/test/examples/target/archive/shebang.rb +3 -0
- data/test/examples/target/archive/subfiles/subfile_1.rb +63 -0
- data/test/examples/target/archive/template.haml.rb +10 -0
- data/test/examples/target/jenny.rb +63 -0
- data/test/examples/target/jenny_link.rb +63 -0
- data/test/examples/target2/coati.conf +36 -0
- data/test/examples/target2/coati.haml.conf +37 -0
- data/test/examples/target2/executable +3 -0
- data/test/examples/target2/jenny-diff.rb +64 -0
- data/test/examples/target2/jenny.rb +63 -0
- data/test/examples/target2/jenny_link.rb +63 -0
- data/test/examples/target2/jenny_template.rb +10 -0
- data/test/examples/target2/jenny_test.rb +63 -0
- data/test/examples/target2/shebang.rb +3 -0
- data/test/examples/target2/std_template.rb +12 -0
- data/test/examples/target2/template.haml.rb +10 -0
- data/test/examples/test1.rb +30 -0
- data/test/examples/test2.rb +27 -0
- data/test/examples/test_args +24 -0
- data/test/examples/test_users +16 -0
- metadata +162 -0
data/lib/jeni/options.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#
|
2
|
+
#
|
3
|
+
# = Jeni::Options
|
4
|
+
#
|
5
|
+
# == Options module for the Jeni Installer
|
6
|
+
#
|
7
|
+
# Author:: Robert Sharp
|
8
|
+
# Copyright:: Copyright (c) 2012 Robert Sharp
|
9
|
+
# License:: Open Software Licence v3.0
|
10
|
+
#
|
11
|
+
# This software is licensed for use under the Open Software Licence v. 3.0
|
12
|
+
# The terms of this licence can be found at http://www.opensource.org/licenses/osl-3.0.php
|
13
|
+
# and in the file copyright.txt. Under the terms of this licence, all derivative works
|
14
|
+
# must themselves be licensed under the Open Software Licence v. 3.0
|
15
|
+
#
|
16
|
+
#
|
17
|
+
#
|
18
|
+
|
19
|
+
module Jeni
|
20
|
+
|
21
|
+
# Mixin included in {Jeni::Installer} that sets options for running the installer.
|
22
|
+
module Options
|
23
|
+
|
24
|
+
# show what would happen but do not actually install anything
|
25
|
+
# @param [Boolean] bool set to true to select option
|
26
|
+
def pretend(bool=true)
|
27
|
+
@pretend = bool
|
28
|
+
end
|
29
|
+
|
30
|
+
# allow answers to questions when pretending
|
31
|
+
# @param [Boolean] bool set to true to select option
|
32
|
+
def answer(bool=true)
|
33
|
+
@answer = bool
|
34
|
+
end
|
35
|
+
|
36
|
+
# provide additional messages to assist in debugging issues
|
37
|
+
# @param [Boolean] bool set to true to select option
|
38
|
+
def verbose(bool=true)
|
39
|
+
@verbose = bool
|
40
|
+
end
|
41
|
+
|
42
|
+
# suppress all messages
|
43
|
+
# @param [Boolean] bool set to true to select option
|
44
|
+
def quiet(bool=true)
|
45
|
+
@quiet = bool
|
46
|
+
end
|
47
|
+
|
48
|
+
# do not attempt to create directories that do not exist
|
49
|
+
# @param [Boolean] bool set to true to select option
|
50
|
+
def nomkdir(bool=true)
|
51
|
+
@nomkdir = bool
|
52
|
+
end
|
53
|
+
|
54
|
+
# set the default owner for all files
|
55
|
+
# @param [String] user to set as the default owner
|
56
|
+
def owner(user)
|
57
|
+
@owner = user
|
58
|
+
end
|
59
|
+
|
60
|
+
# set the default group for all files
|
61
|
+
# @param [String] group to set as the default
|
62
|
+
def group(group)
|
63
|
+
@group = group
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
#
|
2
|
+
#
|
3
|
+
# = Jeni
|
4
|
+
#
|
5
|
+
# == Optparse
|
6
|
+
#
|
7
|
+
# Author:: Robert Sharp
|
8
|
+
# Copyright:: Copyright (c) 2012 Robert Sharp
|
9
|
+
# License:: Open Software Licence v3.0
|
10
|
+
#
|
11
|
+
# This software is licensed for use under the Open Software Licence v. 3.0
|
12
|
+
# The terms of this licence can be found at http://www.opensource.org/licenses/osl-3.0.php
|
13
|
+
# and in the file copyright.txt. Under the terms of this licence, all derivative works
|
14
|
+
# must themselves be licensed under the Open Software Licence v. 3.0
|
15
|
+
#
|
16
|
+
#
|
17
|
+
#
|
18
|
+
require 'optparse'
|
19
|
+
|
20
|
+
module Jeni
|
21
|
+
|
22
|
+
# Mixin included in {Jeni::Installer} that adds optparse option processing.
|
23
|
+
module Optparse
|
24
|
+
|
25
|
+
# enables command line options to be processed directly. These correspond to the
|
26
|
+
# options in {Jeni::Options}.
|
27
|
+
#
|
28
|
+
# For example:
|
29
|
+
#
|
30
|
+
# Jeni::Installer.new_from_gem('jeni') do |jeni|
|
31
|
+
# jeni.optparse(ARGV)
|
32
|
+
# jeni.file(source, target)
|
33
|
+
# end.run!
|
34
|
+
#
|
35
|
+
def optparse(args)
|
36
|
+
opts = OptionParser.new
|
37
|
+
|
38
|
+
opts.banner = "Usage: #{$0} [options]"
|
39
|
+
opts.separator ''
|
40
|
+
opts.separator ' a post-install script to use with a gem after the main installation'
|
41
|
+
opts.separator ' in order to copy files etc where gem cannot reach.'
|
42
|
+
opts.separator ''
|
43
|
+
|
44
|
+
opts.on('-p', '--pretend', 'pretend to take actions but do nothing really') do
|
45
|
+
@pretend = true
|
46
|
+
end
|
47
|
+
|
48
|
+
opts.on('-a', '--answer', 'allow questions to be answered in pretend mode') do
|
49
|
+
@answer = true
|
50
|
+
end
|
51
|
+
|
52
|
+
opts.on('-v', '--verbose', 'increase the messages produced to help with problems') do
|
53
|
+
@verbose = true
|
54
|
+
end
|
55
|
+
|
56
|
+
opts.on('-q', '--quiet', 'suppress all output') do
|
57
|
+
@quiet = true
|
58
|
+
end
|
59
|
+
|
60
|
+
opts.on('-n', '--nodir', 'do not make any subdirectories if they do not already exist') do
|
61
|
+
@nomkdir = true
|
62
|
+
end
|
63
|
+
|
64
|
+
opts.on('-o', '--owner [NAME]', String, 'specify the default owner for installed files') do |o|
|
65
|
+
@owner = o
|
66
|
+
end
|
67
|
+
|
68
|
+
opts.on('-g', '--group [NAME]', String, 'specify the default group for installed files') do |g|
|
69
|
+
@group = g
|
70
|
+
end
|
71
|
+
|
72
|
+
opts.on_tail('-h', '--help', 'you are looking at it') do
|
73
|
+
puts opts
|
74
|
+
exit 0
|
75
|
+
end
|
76
|
+
|
77
|
+
opts.parse!(args)
|
78
|
+
|
79
|
+
@answer = false unless @pretend
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
data/lib/jeni/utils.rb
ADDED
@@ -0,0 +1,181 @@
|
|
1
|
+
#
|
2
|
+
#
|
3
|
+
# = Jeni::Utils
|
4
|
+
#
|
5
|
+
# == useful utilities to include in the main installer
|
6
|
+
#
|
7
|
+
# Author:: Robert Sharp
|
8
|
+
# Copyright:: Copyright (c) 2012 Robert Sharp
|
9
|
+
# License:: Open Software Licence v3.0
|
10
|
+
#
|
11
|
+
# This software is licensed for use under the Open Software Licence v. 3.0
|
12
|
+
# The terms of this licence can be found at http://www.opensource.org/licenses/osl-3.0.php
|
13
|
+
# and in the file copyright.txt. Under the terms of this licence, all derivative works
|
14
|
+
# must themselves be licensed under the Open Software Licence v. 3.0
|
15
|
+
#
|
16
|
+
#
|
17
|
+
#
|
18
|
+
require 'colored'
|
19
|
+
require 'diffy'
|
20
|
+
require 'rubygems' # legitimate cos this module uses Gem!
|
21
|
+
require 'haml'
|
22
|
+
|
23
|
+
module Jeni
|
24
|
+
|
25
|
+
# mixin of underlying utilities that users do not need to know about. Tests are in
|
26
|
+
# spec/jeni_utils_spec.rb
|
27
|
+
module Utils
|
28
|
+
|
29
|
+
|
30
|
+
# construct the path and
|
31
|
+
# check if file exists and create error if not
|
32
|
+
def check_file(file)
|
33
|
+
if file[0,1] == '/' then
|
34
|
+
# absolute path so leave unaltered
|
35
|
+
else
|
36
|
+
file = File.expand_path(File.join(@source_root, file))
|
37
|
+
end
|
38
|
+
@errors[:missing] = file unless FileTest.exists?(file)
|
39
|
+
return file
|
40
|
+
end
|
41
|
+
|
42
|
+
# check if target directory exists and is writeable
|
43
|
+
# this will create a target if it does not exist (and all intermediate paths) unless
|
44
|
+
# the nomkdir option is set
|
45
|
+
def check_target(target, owner=nil)
|
46
|
+
dir = File.dirname(target)
|
47
|
+
unless FileTest.directory?(dir)
|
48
|
+
unless @nomkdir
|
49
|
+
@commands << {:mkdir => dir}
|
50
|
+
if owner then
|
51
|
+
@commands << {:chown => {:file => dir, :owner => owner}}
|
52
|
+
end
|
53
|
+
return
|
54
|
+
end
|
55
|
+
@errors[:missing] = dir
|
56
|
+
end
|
57
|
+
@errors[:unwritable] = dir unless FileTest.writable?(dir)
|
58
|
+
rescue
|
59
|
+
@errors[:unwritable] = dir unless FileTest.writable?(dir)
|
60
|
+
end
|
61
|
+
|
62
|
+
# ensure this is called for a gem
|
63
|
+
def check_gem(method)
|
64
|
+
@errors[method] = "The source needs to be a gem" unless @gem
|
65
|
+
end
|
66
|
+
|
67
|
+
def check_executable(file)
|
68
|
+
unless FileTest.executable?(file)
|
69
|
+
@errors[:no_exec] = file
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# check if a given user exists (e.g. for changing ownership)
|
74
|
+
def check_user(user)
|
75
|
+
Etc.getpwnam(user)
|
76
|
+
rescue ArgumentError
|
77
|
+
@errors[:no_user] = "User does not exist: #{user}"
|
78
|
+
end
|
79
|
+
|
80
|
+
def check_group(group)
|
81
|
+
Etc.getgrnam(group)
|
82
|
+
rescue ArgumentError
|
83
|
+
@errors[:group] = "Group does not exist: #{group}"
|
84
|
+
end
|
85
|
+
|
86
|
+
# check there is no user
|
87
|
+
def check_new_user(user, opts, skip)
|
88
|
+
if opts.has_key?(:uid) then
|
89
|
+
# check that it is not already in use
|
90
|
+
begin
|
91
|
+
Etc.getpwuid(opts[:uid])
|
92
|
+
@errors[:user] = "Given uid is already in use: #{opts[:uid]}" unless skip
|
93
|
+
rescue ArgumentError
|
94
|
+
# no uid - so good
|
95
|
+
end
|
96
|
+
end
|
97
|
+
if opts.has_key?(:gid) then
|
98
|
+
# check the group DOES exist
|
99
|
+
begin
|
100
|
+
Etc.getgrgid(opts[:gid])
|
101
|
+
rescue ArgumentError
|
102
|
+
@errors[:user] = "Group id does not exist: #{opts[:gid]}"
|
103
|
+
return
|
104
|
+
end
|
105
|
+
end
|
106
|
+
Etc.getpwnam(user)
|
107
|
+
# user exists, so ignore it
|
108
|
+
@errors[:user] = "New user already exists: #{user}" unless skip
|
109
|
+
return skip
|
110
|
+
rescue ArgumentError
|
111
|
+
# will get here if user does NOT exist
|
112
|
+
return false # do not skip!
|
113
|
+
end
|
114
|
+
|
115
|
+
# check there is no group
|
116
|
+
def check_new_group(group, opts, skip)
|
117
|
+
if opts.has_key?(:gid) then
|
118
|
+
# check that it is not already in use
|
119
|
+
begin
|
120
|
+
Etc.getgrgid(opts[:gid])
|
121
|
+
@errors[:group] = "Given gid is already in use: #{opts[:gid]}" unless skip
|
122
|
+
rescue ArgumentError
|
123
|
+
# no uid - so good
|
124
|
+
end
|
125
|
+
end
|
126
|
+
Etc.getgrnam(group)
|
127
|
+
# user exists, so ignore it
|
128
|
+
@errors[:group] = "New group already exists: #{group}" unless skip
|
129
|
+
return skip
|
130
|
+
rescue ArgumentError
|
131
|
+
# will get here if user does NOT exist
|
132
|
+
return false
|
133
|
+
end
|
134
|
+
|
135
|
+
# ensure user is root
|
136
|
+
def check_root(skip)
|
137
|
+
return false if skip
|
138
|
+
@errors[:root] = "You do not have sufficient privileges for this operation" unless Process.uid == 0
|
139
|
+
end
|
140
|
+
|
141
|
+
# ensure the mode given is valid
|
142
|
+
def check_chmod(mode)
|
143
|
+
return unless mode #called with a nil mode
|
144
|
+
if mode >= 512 || mode <= 0 then
|
145
|
+
@errors[:invalid] = "mode: #{mode.to_s(8)}"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
# helper to add commands for options
|
151
|
+
def process_options(opts, target)
|
152
|
+
owner = opts[:chown] || @owner
|
153
|
+
group = opts[:chgrp] || @group
|
154
|
+
chmod = opts[:chmod]
|
155
|
+
if owner then
|
156
|
+
check_user(owner)
|
157
|
+
@commands << {:chown => {:owner => owner, :file => target}}
|
158
|
+
end
|
159
|
+
if group then
|
160
|
+
check_group(group)
|
161
|
+
@commands << {:chgrp => {:group => group, :file => target}}
|
162
|
+
end
|
163
|
+
@commands << {:chmod => {:file => target, :mode => chmod}} if chmod
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
# helper that shows if any errors have been reported
|
168
|
+
def errors?
|
169
|
+
! @errors.empty?
|
170
|
+
end
|
171
|
+
|
172
|
+
# helper to process errors
|
173
|
+
def each_error(&block)
|
174
|
+
@errors.each_pair do |key, value|
|
175
|
+
block.call(key, value)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
data/lib/jeni/version.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Created by Jevoom
|
2
|
+
#
|
3
|
+
# 04-Oct-2012
|
4
|
+
# Application forked from local 'jeni' due to Gam-space name clash.
|
5
|
+
|
6
|
+
module Jeni
|
7
|
+
# version set to 0.2.0
|
8
|
+
Version = '0.2.0'
|
9
|
+
# date set to 04-Oct-2012
|
10
|
+
Version_Date = '04-Oct-2012'
|
11
|
+
#ident string set to: jeni-0.2.0 04-Oct-2012
|
12
|
+
Ident = 'jeni-0.2.0 04-Oct-2012'
|
13
|
+
end
|
data/spec/jeni_spec.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
#
|
2
|
+
# Author:: R.J.Sharp
|
3
|
+
# Email:: robert(a)osburn-sharp.ath.cx
|
4
|
+
# Copyright:: Copyright (c) 2012
|
5
|
+
# License:: Open Software Licence v3.0
|
6
|
+
#
|
7
|
+
# This software is licensed for use under the Open Software Licence v. 3.0
|
8
|
+
# The terms of this licence can be found at http://www.opensource.org/licenses/osl-3.0.php
|
9
|
+
# and in the file LICENCE. Under the terms of this licence, all derivative works
|
10
|
+
# must themselves be licensed under the Open Software Licence v. 3.0
|
11
|
+
#
|
12
|
+
#
|
13
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
14
|
+
|
15
|
+
source_dir = File.expand_path(File.dirname(__FILE__) + '/../test/examples/source')
|
16
|
+
target_dir = File.expand_path(File.dirname(__FILE__) + '/../test/examples/target')
|
17
|
+
FileUtils.rm_f Dir.glob("#{target_dir}/**")
|
18
|
+
|
19
|
+
describe Jeni do
|
20
|
+
|
21
|
+
it "should create a file" do
|
22
|
+
source_file = 'jeni.rb'
|
23
|
+
target_file = File.join(target_dir, source_file)
|
24
|
+
Jeni::Installer.new(source_dir, 'test') do |jeni|
|
25
|
+
jeni.quiet(true)
|
26
|
+
jeni.file(source_file, target_file)
|
27
|
+
end.run!
|
28
|
+
FileTest.exists?(target_file).should be_true
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should create a directory" do
|
32
|
+
target_file = File.join(target_dir, 'archive')
|
33
|
+
Jeni::Installer.new(source_dir, 'test') do |jeni|
|
34
|
+
jeni.quiet(true)
|
35
|
+
jeni.directory(source_dir, target_file)
|
36
|
+
end.run!
|
37
|
+
#FileTest.exists?(target_file).should be_true
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should create an empty directory" do
|
41
|
+
empty_dir = File.join(target_dir, 'cache')
|
42
|
+
Jeni::Installer.new(source_dir, 'test') do |jeni|
|
43
|
+
jeni.quiet(true)
|
44
|
+
jeni.empty_directory(empty_dir)
|
45
|
+
end.run!
|
46
|
+
FileTest.directory?(empty_dir). should be_true
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should check if a file exists" do
|
50
|
+
exec = File.join(source_dir, '..', 'test1.rb')
|
51
|
+
res = Jeni::Installer.new(source_dir, 'test') do |jeni|
|
52
|
+
jeni.quiet(true)
|
53
|
+
jeni.file_exists?(exec)
|
54
|
+
end.run!
|
55
|
+
res.should be_true
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should check if an executable exists" do
|
59
|
+
exec = File.join(source_dir, '..', 'test1.rb')
|
60
|
+
res = Jeni::Installer.new(source_dir, 'test') do |jeni|
|
61
|
+
jeni.quiet(true)
|
62
|
+
jeni.file_exists?(exec, :executable=>true)
|
63
|
+
end.run!
|
64
|
+
res.should be_true
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should fail if a file is not executable" do
|
68
|
+
exec = File.join(source_dir, 'jeni.rb')
|
69
|
+
res = Jeni::Installer.new(source_dir, 'test') do |jeni|
|
70
|
+
jeni.quiet(true)
|
71
|
+
jeni.file_exists?(exec, :executable=>true)
|
72
|
+
end.run!
|
73
|
+
res.should_not be_true
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should create a link" do
|
77
|
+
target_file = File.join(target_dir, 'jeni_link.rb')
|
78
|
+
Jeni::Installer.new(source_dir, 'test') do |jeni|
|
79
|
+
jeni.quiet(true)
|
80
|
+
jeni.link('jeni.rb', target_file)
|
81
|
+
end.run!
|
82
|
+
FileTest.symlink?(target_file).should be_true
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
@@ -0,0 +1,297 @@
|
|
1
|
+
#
|
2
|
+
# Author:: R.J.Sharp
|
3
|
+
# Email:: robert(a)osburn-sharp.ath.cx
|
4
|
+
# Copyright:: Copyright (c) 2012
|
5
|
+
# License:: Open Software Licence v3.0
|
6
|
+
#
|
7
|
+
# This software is licensed for use under the Open Software Licence v. 3.0
|
8
|
+
# The terms of this licence can be found at http://www.opensource.org/licenses/osl-3.0.php
|
9
|
+
# and in the file LICENCE. Under the terms of this licence, all derivative works
|
10
|
+
# must themselves be licensed under the Open Software Licence v. 3.0
|
11
|
+
#
|
12
|
+
# Tests out the Jeni::Utils module as a mixin for Jeni
|
13
|
+
#
|
14
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
15
|
+
require 'jeni/utils'
|
16
|
+
require 'jeni/options'
|
17
|
+
require 'jeni/errors'
|
18
|
+
require 'jeni/io'
|
19
|
+
require 'colored'
|
20
|
+
|
21
|
+
test_dir = File.expand_path(File.dirname(__FILE__) + '/../test/examples')
|
22
|
+
|
23
|
+
class JeniUtils
|
24
|
+
include Jeni::Utils
|
25
|
+
include Jeni::Options
|
26
|
+
include Jeni::IO
|
27
|
+
def initialize
|
28
|
+
@app_name = 'jeni'
|
29
|
+
@errors = {}
|
30
|
+
@commands = []
|
31
|
+
@source_root = File.expand_path(File.dirname(__FILE__) + '/../test/examples')
|
32
|
+
end
|
33
|
+
attr_accessor :errors
|
34
|
+
end
|
35
|
+
|
36
|
+
describe Jeni do
|
37
|
+
|
38
|
+
before(:each) do
|
39
|
+
@jeni = JeniUtils.new
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should print a message to stdout" do
|
43
|
+
@jeni.should_receive(:puts)
|
44
|
+
@jeni.say(:create, "/a/file")
|
45
|
+
end
|
46
|
+
it "should print a message of any type to stdout" do
|
47
|
+
@jeni.should_receive(:puts)
|
48
|
+
@jeni.say(:unknown, "/a/file")
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should ask a question and get a default response" do
|
52
|
+
@jeni.should_receive(:print)
|
53
|
+
@jeni.ask('Do you want to do this').should == :no
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should check a relatively file and provide an absolute path" do
|
57
|
+
@jeni.check_file('test1.rb').should == File.join(test_dir, 'test1.rb')
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should check and return an absolute path" do
|
61
|
+
@jeni.check_file('/etc/hosts').should == '/etc/hosts'
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should reject a non-existent source" do
|
65
|
+
nofile = '/a/nonexistent/file.rb'
|
66
|
+
response = @jeni.say(:missing, nofile, :error, true)
|
67
|
+
@jeni.should_receive(:puts).with(response)
|
68
|
+
@jeni.copy(nofile, '/who/cares').should be_nil
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should reject an unwritable target directory" do
|
72
|
+
udir = '/who/cares'
|
73
|
+
response = @jeni.say(:unwritable, udir, :error, true)
|
74
|
+
@jeni.should_receive(:puts).with(response)
|
75
|
+
FileUtils.touch("/tmp/jeni_utils.rb")
|
76
|
+
@jeni.copy("/tmp/jeni_utils.rb", "/who/cares/anyway.rb").should be_nil
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should just create a file that does not exist" do
|
80
|
+
source = File.join(test_dir, 'source', 'jeni.rb')
|
81
|
+
target = File.join(test_dir, 'target', 'jeni.rb')
|
82
|
+
FileUtils.rm(target) if FileTest.exists?(target)
|
83
|
+
response = @jeni.say(:create, target, :ok, true)
|
84
|
+
@jeni.should_receive(:puts).with(response)
|
85
|
+
@jeni.copy(source, target).should == target
|
86
|
+
FileTest.exists?(target).should be_true
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should spot a file that is identical" do
|
90
|
+
source = File.join(test_dir, 'source', 'jeni.rb')
|
91
|
+
target = File.join(test_dir, 'target', 'jeni.rb')
|
92
|
+
response = @jeni.say(:identical, target, :no_change, true)
|
93
|
+
@jeni.should_receive(:puts).with(response)
|
94
|
+
@jeni.copy(source, target).should == target
|
95
|
+
FileTest.exists?(target).should be_true
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should spot a file that would overwrite and skip it" do
|
99
|
+
source_old = File.join(test_dir, 'source', 'jeni.rb')
|
100
|
+
source = File.join(test_dir, 'source', 'jeni-diff.rb')
|
101
|
+
target = File.join(test_dir, 'target', 'jeni.rb')
|
102
|
+
response = @jeni.say(:exists, target, :warning, true)
|
103
|
+
response2 = @jeni.say(:skipping, target, :warning, true)
|
104
|
+
@jeni.should_receive(:puts).with(response)
|
105
|
+
@jeni.should_receive(:puts).with(response2)
|
106
|
+
@jeni.should_receive(:print)
|
107
|
+
@jeni.copy(source, target).should be_nil
|
108
|
+
FileTest.exists?(target).should be_true
|
109
|
+
FileUtils.compare_file(source_old, target).should be_true
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
it "should spot a file that would overwrite and diff it" do
|
114
|
+
source_old = File.join(test_dir, 'source', 'jeni.rb')
|
115
|
+
source = File.join(test_dir, 'source', 'jeni-diff.rb')
|
116
|
+
target = File.join(test_dir, 'target', 'jeni.rb')
|
117
|
+
diff = Diffy::Diff.new(source, target, :source=>'files').to_s(:color)
|
118
|
+
response = @jeni.say(:exists, target, :warning, true)
|
119
|
+
response2 = @jeni.say(:skipping, target, :warning, true)
|
120
|
+
@jeni.should_receive(:puts).with(response)
|
121
|
+
@jeni.should_receive(:puts).with(response2)
|
122
|
+
@jeni.should_receive(:print).twice
|
123
|
+
@jeni.should_receive(:gets).and_return('d', 'n')
|
124
|
+
@jeni.should_receive(:puts).with(diff)
|
125
|
+
#@jeni.should_receive(:print)
|
126
|
+
@jeni.copy(source, target).should be_nil
|
127
|
+
FileTest.exists?(target).should be_true
|
128
|
+
FileUtils.compare_file(source_old, target).should be_true
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should spot a file that would overwrite and overwrite it" do
|
132
|
+
source = File.join(test_dir, 'source', 'jeni-diff.rb')
|
133
|
+
target = File.join(test_dir, 'target', 'jeni.rb')
|
134
|
+
response = @jeni.say(:exists, target, :warning, true)
|
135
|
+
response2 = @jeni.say(:overwrite, target, :ok, true)
|
136
|
+
@jeni.should_receive(:puts).with(response)
|
137
|
+
@jeni.should_receive(:puts).with(response2)
|
138
|
+
@jeni.should_receive(:print)
|
139
|
+
@jeni.should_receive(:gets).and_return('y')
|
140
|
+
@jeni.copy(source, target).should == target
|
141
|
+
FileTest.exists?(target).should be_true
|
142
|
+
FileUtils.compare_file(source, target).should be_true
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should create a file from a template" do
|
146
|
+
temp = File.join(test_dir, 'source', 'template.haml.rb')
|
147
|
+
target = File.join(test_dir, 'target', 'jeni_template.rb')
|
148
|
+
FileUtils.rm(target) if FileTest.exists?(target)
|
149
|
+
response = @jeni.say(:create, target, :ok, true)
|
150
|
+
@jeni.should_receive(:puts).with(response)
|
151
|
+
@jeni.generate(temp, target, :greeting=>"Welcome", :author=>"Robert Sharp")
|
152
|
+
FileTest.exists?(target).should be_true
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should create a wrapper" do
|
156
|
+
source = 'source/jeni.rb'
|
157
|
+
full_source = File.join(test_dir, source)
|
158
|
+
wrapper = @jeni.wrap_file(source, full_source)
|
159
|
+
copy = File.readlines(File.join(test_dir, 'target', 'test.rb')).join('')
|
160
|
+
wrapper.should == copy
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should create a shebang" do
|
164
|
+
sb = @jeni.shebang(File.join(test_dir, 'source/jeni.rb'))
|
165
|
+
sb.should match(/\A#!\/usr\/bin\/env ruby18\z/)
|
166
|
+
#sb = @jeni.shebang(test_dir, 'source/shebang.rb')
|
167
|
+
#sb.should match(/\A#!\/usr\/bin\/env ruby18 -w\z/)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should check for a file that exists" do
|
171
|
+
file = File.join(test_dir, 'source', 'jeni.rb')
|
172
|
+
@jeni.check_file(file)
|
173
|
+
@jeni.errors.length.should == 0
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should check for a file that does not exist" do
|
177
|
+
file = File.join(test_dir, 'source', 'freddie.rb')
|
178
|
+
@jeni.check_file(file)
|
179
|
+
@jeni.errors.length.should == 1
|
180
|
+
@jeni.each_error do |key, value|
|
181
|
+
key.should == :missing
|
182
|
+
value.should == file
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should check that a target directory exists" do
|
187
|
+
target = File.join(test_dir, "target", "jeni.rb")
|
188
|
+
@jeni.check_target(target)
|
189
|
+
@jeni.errors?.should be_false
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should raise an error if target directory does not exist with nomkdir" do
|
193
|
+
target = File.join(test_dir, "target", 'another', "jeni.rb")
|
194
|
+
@jeni.nomkdir
|
195
|
+
@jeni.check_target(target)
|
196
|
+
@jeni.errors?.should be_true
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should mkdir if target directory does not exist" do
|
200
|
+
target = File.join(test_dir, "target", 'another', "jeni.rb")
|
201
|
+
@jeni.nomkdir(false)
|
202
|
+
@jeni.check_target(target)
|
203
|
+
@jeni.errors?.should be_false
|
204
|
+
end
|
205
|
+
|
206
|
+
it "should check a valid user" do
|
207
|
+
valid_user = 'root'
|
208
|
+
@jeni.check_user(valid_user)
|
209
|
+
@jeni.errors?.should be_false
|
210
|
+
end
|
211
|
+
|
212
|
+
it "should raise an error for an invalid user" do
|
213
|
+
invalid_user = "peppapigsgreataunt"
|
214
|
+
@jeni.check_user(invalid_user)
|
215
|
+
@jeni.errors?.should be_true
|
216
|
+
@jeni.each_error { |k,v| k.should == :no_user; v.should == "User does not exist: #{invalid_user}"}
|
217
|
+
end
|
218
|
+
|
219
|
+
it "should change the mode for a file" do
|
220
|
+
source = File.join(test_dir, "source", "shebang.rb")
|
221
|
+
target = File.join(test_dir, "target", "shebang.rb")
|
222
|
+
FileUtils.rm_f(target) if FileTest.exists?(target)
|
223
|
+
response = @jeni.say(:create, target, :ok, true)
|
224
|
+
response2 = @jeni.say(:chmod, "#{target} to 755", :ok, true)
|
225
|
+
@jeni.should_receive(:puts).with(response)
|
226
|
+
@jeni.should_receive(:puts).with(response2)
|
227
|
+
@jeni.copy(source, target)
|
228
|
+
@jeni.chmod(target, 0755)
|
229
|
+
FileTest.executable?(target).should be_true
|
230
|
+
end
|
231
|
+
|
232
|
+
it "should check a new user" do
|
233
|
+
@jeni.check_new_user("peppapig", {}, false)
|
234
|
+
@jeni.each_error do |err|
|
235
|
+
puts err
|
236
|
+
end
|
237
|
+
@jeni.errors?.should be_false
|
238
|
+
@jeni.check_new_user("peppapig", {:uid=>10101}, false)
|
239
|
+
@jeni.errors?.should be_false
|
240
|
+
@jeni.check_new_user("peppapig", {:uid=>10101, :home=>'/home/peppa', :shell=>'/bin/bourne'}, false)
|
241
|
+
@jeni.errors?.should be_false
|
242
|
+
end
|
243
|
+
|
244
|
+
it "should throw errors for invalid users" do
|
245
|
+
@jeni.check_new_user("daemon", {}, false)
|
246
|
+
@jeni.errors?.should be_true
|
247
|
+
@jeni.errors = {}
|
248
|
+
@jeni.check_new_user("peppapig", {:uid=>2}, false)
|
249
|
+
@jeni.errors?.should be_true
|
250
|
+
@jeni.errors = {}
|
251
|
+
@jeni.check_new_user("peppapig", {:gid=>10101}, false)
|
252
|
+
@jeni.errors?.should be_true
|
253
|
+
end
|
254
|
+
|
255
|
+
it "should create a new user" do
|
256
|
+
cmd = "/usr/sbin/useradd -d /home/peppapig -s /bin/bash -u 10101 -g 100 peppapig"
|
257
|
+
@jeni.should_receive(:system).with(cmd)
|
258
|
+
response = @jeni.say(:user, "Added user peppapig", :ok, true)
|
259
|
+
@jeni.should_receive(:puts).with(response)
|
260
|
+
@jeni.add_user("peppapig", :uid=>10101, :gid=>100)
|
261
|
+
end
|
262
|
+
|
263
|
+
it "should check a new group" do
|
264
|
+
@jeni.check_new_group("piglets", {}, false)
|
265
|
+
@jeni.errors?.should be_false
|
266
|
+
@jeni.check_new_group("piglets", {:gid=>10101}, false)
|
267
|
+
@jeni.errors?.should be_false
|
268
|
+
end
|
269
|
+
|
270
|
+
it "should throw errors for invalid groups" do
|
271
|
+
@jeni.check_new_group("users", {}, false)
|
272
|
+
@jeni.errors?.should be_true
|
273
|
+
@jeni.errors = {}
|
274
|
+
@jeni.check_new_group("piglets", {:gid=>100}, false)
|
275
|
+
@jeni.errors?.should be_true
|
276
|
+
end
|
277
|
+
|
278
|
+
it "should create a new group" do
|
279
|
+
cmd = "/usr/sbin/groupadd -g 10101 piglets"
|
280
|
+
@jeni.should_receive(:system).with(cmd)
|
281
|
+
response = @jeni.say(:group, "Added group piglets", :ok, true)
|
282
|
+
@jeni.should_receive(:puts).with(response)
|
283
|
+
@jeni.add_group("piglets", :gid=>10101)
|
284
|
+
end
|
285
|
+
|
286
|
+
end
|
287
|
+
|
288
|
+
|
289
|
+
|
290
|
+
|
291
|
+
|
292
|
+
|
293
|
+
|
294
|
+
|
295
|
+
|
296
|
+
|
297
|
+
|