jeni 0.2.0
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/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
|
+
|