ratch 0.2.3 → 0.3.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/bin/ratch +60 -47
- data/bin/ratch-find +21 -0
- data/demo/{README → XR} +0 -0
- data/demo/task/stats +0 -2
- data/doc/images/clipboard.jpg +0 -0
- data/doc/images/clipboard2.png +0 -0
- data/doc/images/milles-tn.jpg +0 -0
- data/doc/images/mints.png +0 -0
- data/doc/images/ratch2.png +0 -0
- data/doc/images/ruby-sm.png +0 -0
- data/doc/images/silver.gif +0 -0
- data/doc/images/toolbox.jpg +0 -0
- data/doc/index.html +181 -0
- data/doc/notes/original.rb +308 -0
- data/doc/rdoc/classes/Array.html +194 -0
- data/doc/rdoc/classes/Dir.html +317 -0
- data/doc/rdoc/classes/Hash.html +217 -0
- data/doc/rdoc/classes/Ratch.html +201 -0
- data/doc/rdoc/classes/Ratch/ArgvUtils.html +173 -0
- data/doc/rdoc/classes/Ratch/ArgvUtils/Ext.html +285 -0
- data/doc/rdoc/classes/Ratch/BatchFile.html +207 -0
- data/doc/rdoc/classes/Ratch/BatchManager.html +250 -0
- data/doc/rdoc/classes/Ratch/BatchScript.html +127 -0
- data/doc/rdoc/classes/Ratch/Batchable.html +373 -0
- data/doc/rdoc/classes/Ratch/Build.html +321 -0
- data/doc/rdoc/classes/Ratch/BuildManager.html +319 -0
- data/doc/rdoc/classes/Ratch/Buildable.html +202 -0
- data/doc/rdoc/classes/Ratch/ConfigUtils.html +281 -0
- data/doc/rdoc/classes/Ratch/ConsoleUtils.html +189 -0
- data/doc/rdoc/classes/Ratch/EmailUtils.html +209 -0
- data/doc/rdoc/classes/Ratch/FileUtils.html +674 -0
- data/doc/rdoc/classes/Ratch/GeneralOptions.html +430 -0
- data/doc/rdoc/classes/Ratch/Task.html +201 -0
- data/doc/rdoc/classes/Ratch/TaskManager.html +330 -0
- data/doc/rdoc/classes/Ratch/Taskable.html +231 -0
- data/doc/rdoc/classes/Ratch/UploadUtils.html +566 -0
- data/doc/rdoc/created.rid +1 -0
- data/doc/rdoc/files/COPYING.html +1003 -0
- data/{demo/doc → doc}/rdoc/files/README.html +36 -5
- data/doc/rdoc/files/lib/ratch/argvutils_rb.html +131 -0
- data/doc/rdoc/files/lib/ratch/batch_rb.html +155 -0
- data/doc/rdoc/files/lib/ratch/batchable_rb.html +131 -0
- data/doc/rdoc/files/lib/ratch/batchfile_rb.html +148 -0
- data/doc/rdoc/files/lib/ratch/buildable_rb.html +131 -0
- data/doc/rdoc/files/lib/ratch/consoleutils_rb.html +131 -0
- data/{demo/doc/rdoc/files/lib/foo/foo_rb.html → doc/rdoc/files/lib/ratch/emailutils_rb.html} +35 -41
- data/doc/rdoc/files/lib/ratch/facets/multiglob_rb.html +137 -0
- data/doc/rdoc/files/lib/ratch/fileutils_rb.html +139 -0
- data/doc/rdoc/files/lib/ratch/options_rb.html +131 -0
- data/doc/rdoc/files/lib/ratch/taskable_rb.html +131 -0
- data/doc/rdoc/files/lib/ratch/uploadutils_rb.html +150 -0
- data/doc/rdoc/fr_class_index.html +48 -0
- data/doc/rdoc/fr_file_index.html +41 -0
- data/doc/rdoc/fr_method_index.html +133 -0
- data/{demo/doc → doc}/rdoc/index.html +1 -1
- data/{demo/doc → doc}/rdoc/rdoc-style.css +0 -0
- data/doc/scrap/flexihead-flip.jpg +0 -0
- data/doc/scrap/flexihead.jpg +0 -0
- data/doc/scrap/head1.jpg +0 -0
- data/doc/scrap/ratch.jpg +0 -0
- data/doc/scrap/ratch1.png +0 -0
- data/doc/scrap/ratch2.jpg +0 -0
- data/doc/scrap/ratch3.png +0 -0
- data/doc/scrap/red-ratch.jpg +0 -0
- data/doc/scrap/redratchet.jpg +0 -0
- data/doc/scrap/ruby-kit/ruby.png +0 -0
- data/doc/scrap/scrap.red +256 -0
- data/doc/sitemap.yaml +10 -0
- data/doc/siteparts/index.red +100 -0
- data/doc/siteparts/layout.rhtml +56 -0
- data/doc/siteparts/tutorial.red +578 -0
- data/doc/style.css +112 -0
- data/doc/tutorial.html +722 -0
- data/lib/ratch/batch.rb +417 -30
- data/lib/ratch/{argvutils.rb → batch/argvutils.rb} +27 -19
- data/lib/ratch/batch/build.rb +95 -0
- data/lib/ratch/{consoleutils.rb → batch/consoleutils.rb} +0 -0
- data/lib/ratch/{emailutils.rb → batch/emailutils.rb} +0 -0
- data/lib/ratch/{fileutils.rb → batch/fileutils.rb} +32 -32
- data/lib/ratch/{options.rb → batch/options.rb} +0 -0
- data/lib/ratch/batch/task.rb +43 -0
- data/lib/ratch/manager.rb +34 -0
- data/lib/ratch/project/information.rb +257 -0
- data/lib/ratch/project/package.rb +82 -0
- data/lib/ratch/project/project.rb +531 -0
- data/lib/ratch/project/release.rb +112 -0
- data/lib/ratch/support/filetest.rb +29 -0
- data/lib/ratch/support/setuputils.rb +124 -0
- data/lib/ratch/support/signiture.rb +252 -0
- data/lib/ratch/support/stage.rb +292 -0
- data/lib/ratch/toolset/ruby/pack/gem +85 -0
- data/lib/ratch/toolset/ruby/pack/tgz +85 -0
- data/lib/ratch/toolset/ruby/{crosstest → test/crosstest} +0 -0
- data/lib/ratch/toolset/ruby/{extest → test/extest} +0 -0
- data/lib/ratch/toolset/ruby/{isotest → test/isotest} +0 -0
- data/lib/ratch/toolset/ruby/{load → test/load} +0 -0
- data/lib/ratch/toolset/ruby/{loadtest → test/loadtest} +0 -0
- data/lib/ratch/toolset/ruby/{syntax → test/syntax} +0 -0
- data/lib/ratch/toolset/ruby/{test → test/test} +0 -0
- data/log/{history.rd → history} +6 -0
- data/log/{todo.rd → todo} +0 -0
- data/meta/MANIFEST +52 -36
- data/meta/ROLLRC +2 -0
- data/meta/icli.yaml +16 -0
- data/meta/{ratch-0.2.3.roll → project.yaml} +1 -7
- data/task/release +12 -0
- data/{lib/ratch → work/old}/batchfile.rb +0 -0
- data/work/project-old.rb +67 -0
- data/work/scrap/install +89 -0
- data/work/scrap/install.0 +49 -0
- data/work/scrap/install.1 +63 -0
- data/work/scrap/ludo +25 -0
- data/work/scrap/oldtaskable.rb +573 -0
- data/work/scrap/ratch.man +39 -0
- data/work/scrap/taskable-simple.rb +42 -0
- data/work/scrap/taskable.rb +120 -0
- metadata +170 -72
- data/demo/doc/rdoc/created.rid +0 -1
- data/demo/doc/rdoc/fr_class_index.html +0 -26
- data/demo/doc/rdoc/fr_file_index.html +0 -28
- data/demo/doc/rdoc/fr_method_index.html +0 -27
- data/demo/task/config.yaml +0 -2
- data/lib/ratch/batchable.rb +0 -169
- data/lib/ratch/buildable.rb +0 -182
- data/lib/ratch/configutils.rb +0 -132
- data/lib/ratch/facets/multiglob.rb +0 -160
- data/lib/ratch/taskable.rb +0 -152
- data/log/recent.rd +0 -8
- data/task/config.yaml +0 -10
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# = TITLE:
|
|
2
|
+
#
|
|
3
|
+
# Release
|
|
4
|
+
#
|
|
5
|
+
# = COPYING:
|
|
6
|
+
#
|
|
7
|
+
# Copyright (c) 2007 Psi T Corp.
|
|
8
|
+
#
|
|
9
|
+
# This file is part of the ProUtils' Ratch program.
|
|
10
|
+
#
|
|
11
|
+
# Ratch is free software: you can redistribute it and/or modify
|
|
12
|
+
# it under the terms of the GNU General Public License as published by
|
|
13
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
14
|
+
# (at your option) any later version.
|
|
15
|
+
#
|
|
16
|
+
# Ratch is distributed in the hope that it will be useful,
|
|
17
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
18
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
19
|
+
# GNU General Public License for more details.
|
|
20
|
+
#
|
|
21
|
+
# You should have received a copy of the GNU General Public License
|
|
22
|
+
# along with Ratch. If not, see <http://www.gnu.org/licenses/>.
|
|
23
|
+
|
|
24
|
+
require 'ratch/project/information'
|
|
25
|
+
|
|
26
|
+
module Ratch
|
|
27
|
+
|
|
28
|
+
# = Release class
|
|
29
|
+
#
|
|
30
|
+
|
|
31
|
+
class Release < Information
|
|
32
|
+
|
|
33
|
+
# Name of release package.
|
|
34
|
+
|
|
35
|
+
attr_accessor :name
|
|
36
|
+
|
|
37
|
+
validate "name is required" do
|
|
38
|
+
name
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Version number.
|
|
42
|
+
|
|
43
|
+
attr_accessor :version
|
|
44
|
+
|
|
45
|
+
validate "version is required" do
|
|
46
|
+
version
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
#
|
|
50
|
+
|
|
51
|
+
attr_accessor :buildno do
|
|
52
|
+
@buildno = Time.now.strftime("%y%m%d%H%M") if TrueClass === @buildno
|
|
53
|
+
@buildno
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Status of this release: alpha, beta, RC1, etc.
|
|
57
|
+
|
|
58
|
+
attr_accessor :status
|
|
59
|
+
|
|
60
|
+
# Date of release (defaults to Time.now).
|
|
61
|
+
|
|
62
|
+
attr_accessor :date, :released do
|
|
63
|
+
@date || Time.now.strftime("%Y-%m-%d")
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Codename of this release.
|
|
67
|
+
|
|
68
|
+
attr_accessor :codename
|
|
69
|
+
|
|
70
|
+
#
|
|
71
|
+
|
|
72
|
+
ROLLRC_FILE = '{.,meta/}{roll}{rc,}'
|
|
73
|
+
|
|
74
|
+
# Load release information.
|
|
75
|
+
|
|
76
|
+
def self.load
|
|
77
|
+
file = Dir.glob(ROLLRC_FILE, File::FNM_CASEFOLD).first
|
|
78
|
+
if file
|
|
79
|
+
Release.new(parse_rollrc(File.open(file)))
|
|
80
|
+
else
|
|
81
|
+
raise LoadError, "release file required -- #{RELEASE_FILE}"
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Parse ROLLRC file for release information.
|
|
86
|
+
|
|
87
|
+
def self.parse_rollrc(io)
|
|
88
|
+
if IO === io
|
|
89
|
+
begin
|
|
90
|
+
str = io.read
|
|
91
|
+
ensure
|
|
92
|
+
io.close
|
|
93
|
+
end
|
|
94
|
+
else
|
|
95
|
+
str = io.to_s
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
str = str.strip.split(/\n/).first
|
|
99
|
+
|
|
100
|
+
name, version, status, date, *null = *str.split(/\s+/)
|
|
101
|
+
|
|
102
|
+
{ :name => name,
|
|
103
|
+
:version => version,
|
|
104
|
+
:status => status,
|
|
105
|
+
:date => date #,
|
|
106
|
+
#:codename => codename
|
|
107
|
+
}
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
|
|
2
|
+
module FileTest
|
|
3
|
+
|
|
4
|
+
module_function
|
|
5
|
+
|
|
6
|
+
# Is a file a command executable?
|
|
7
|
+
# TODO: Make more robust (Windows?)
|
|
8
|
+
|
|
9
|
+
def bin?(fname)
|
|
10
|
+
@command_paths ||= ENV['PATH'].split(/[:;]/)
|
|
11
|
+
is_bin = @command_paths.any? do |f|
|
|
12
|
+
FileTest.exist?(File.join(f, fname))
|
|
13
|
+
end
|
|
14
|
+
#is_bin ? File.basename(fname) : false
|
|
15
|
+
is_bin ? fname : false
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Is a path considered reasonably "safe"?
|
|
19
|
+
# TODO: Make more robust.
|
|
20
|
+
|
|
21
|
+
def safe?(path)
|
|
22
|
+
case path
|
|
23
|
+
when *[ '/', '/*', '/**/*' ]
|
|
24
|
+
return false
|
|
25
|
+
end
|
|
26
|
+
true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# FILE:
|
|
2
|
+
#
|
|
3
|
+
# setup.rb
|
|
4
|
+
#
|
|
5
|
+
# SUMMARY:
|
|
6
|
+
#
|
|
7
|
+
# Mixen used to setup a package, eg. a manual install.
|
|
8
|
+
#
|
|
9
|
+
# COPYING:
|
|
10
|
+
#
|
|
11
|
+
# Copyright (c) 2007 Psi T Corp.
|
|
12
|
+
#
|
|
13
|
+
# This file is part of the ProUtils' Box program.
|
|
14
|
+
#
|
|
15
|
+
# Box is free software: you can redistribute it and/or modify
|
|
16
|
+
# it under the terms of the GNU General Public License as published by
|
|
17
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
18
|
+
# (at your option) any later version.
|
|
19
|
+
#
|
|
20
|
+
# Box is distributed in the hope that it will be useful,
|
|
21
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
22
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
23
|
+
# GNU General Public License for more details.
|
|
24
|
+
#
|
|
25
|
+
# You should have received a copy of the GNU General Public License
|
|
26
|
+
# along with Box. If not, see <http://www.gnu.org/licenses/>.
|
|
27
|
+
|
|
28
|
+
#
|
|
29
|
+
module Box
|
|
30
|
+
|
|
31
|
+
# = setup utilties
|
|
32
|
+
#
|
|
33
|
+
# Setup utilities provides a convenient way to install
|
|
34
|
+
# a ruby project via setup.rb.
|
|
35
|
+
|
|
36
|
+
module SetupUtils
|
|
37
|
+
|
|
38
|
+
# If setup.rb is not found add a copy to the project.
|
|
39
|
+
|
|
40
|
+
def setup_rb
|
|
41
|
+
unless File.exist?('setup.rb')
|
|
42
|
+
f = File.join(libdir,'vendor','setup.rb')
|
|
43
|
+
if File.exist?(f)
|
|
44
|
+
cp(f,'.')
|
|
45
|
+
else
|
|
46
|
+
abort "setup.rb is not avaialble"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
true
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Installation to a prefix destination using setup.rb.
|
|
53
|
+
# Some package types need this.
|
|
54
|
+
|
|
55
|
+
def prefix_install( prefix )
|
|
56
|
+
FileUtils.mkdir_p( prefix )
|
|
57
|
+
Dir.chdir( folder ) do
|
|
58
|
+
unless setup_rb
|
|
59
|
+
raise "Setup.rb is missing. Forced to abort."
|
|
60
|
+
end
|
|
61
|
+
# mock install
|
|
62
|
+
cmd = ''
|
|
63
|
+
cmd << 'ruby setup.rb '
|
|
64
|
+
cmd << '-q ' unless project.verbose?
|
|
65
|
+
cmd << 'config --installdirs=std ; '
|
|
66
|
+
cmd << 'ruby setup.rb '
|
|
67
|
+
cmd << '-q ' unless project.verbose?
|
|
68
|
+
cmd << "install --prefix=#{prefix}"
|
|
69
|
+
sh cmd
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Setup and install. This builds and installs a project
|
|
74
|
+
# using setup.rb or install.rb. If neither exist setup.rb
|
|
75
|
+
# will be created for the purpose.
|
|
76
|
+
#
|
|
77
|
+
# options Command line options to add to shell command.
|
|
78
|
+
# script Install script, default is install.rb or setup.rb
|
|
79
|
+
#--
|
|
80
|
+
# source Location of source. (Defaults to current directory)
|
|
81
|
+
#++
|
|
82
|
+
|
|
83
|
+
def setup( keys={} )
|
|
84
|
+
#keys |= project.select(:options=>:setup_options, :script=>:setup_script)
|
|
85
|
+
|
|
86
|
+
options = keys['options']
|
|
87
|
+
script = keys['script']
|
|
88
|
+
#source = keys.source || Dir.pwd
|
|
89
|
+
|
|
90
|
+
options = [options].flatten.compact
|
|
91
|
+
|
|
92
|
+
if script
|
|
93
|
+
exe = script + ' '
|
|
94
|
+
exe << options.join(' ')
|
|
95
|
+
elsif File.exist?('install.rb')
|
|
96
|
+
exe = 'ruby install.rb '
|
|
97
|
+
exe << options.join(' ')
|
|
98
|
+
elsif File.exist?('setup.rb') or setup_rb
|
|
99
|
+
exe = 'ruby setup.rb '
|
|
100
|
+
exe << '-q ' unless project.verbose?
|
|
101
|
+
exe << options.join(' ')
|
|
102
|
+
exe << ' all'
|
|
103
|
+
else
|
|
104
|
+
puts "Script setup.rb or install.rb is missing."
|
|
105
|
+
return nil
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# SHELLS OUT!
|
|
109
|
+
|
|
110
|
+
#Dir.chdir(source) do
|
|
111
|
+
#begin
|
|
112
|
+
success = sh( exe )
|
|
113
|
+
puts "Installation complete!" if success
|
|
114
|
+
#rescue Errno::EACCES
|
|
115
|
+
# puts "Permission denied"
|
|
116
|
+
# exit -1
|
|
117
|
+
#end
|
|
118
|
+
#end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
end
|
|
124
|
+
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# TITLE:
|
|
2
|
+
#
|
|
3
|
+
# Sign
|
|
4
|
+
#
|
|
5
|
+
# COPYING:
|
|
6
|
+
#
|
|
7
|
+
# Copyright (c) 2007 Psi T Corp.
|
|
8
|
+
#
|
|
9
|
+
# This file is part of the ProUtils' Box program.
|
|
10
|
+
#
|
|
11
|
+
# Box is free software: you can redistribute it and/or modify
|
|
12
|
+
# it under the terms of the GNU General Public License as published by
|
|
13
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
14
|
+
# (at your option) any later version.
|
|
15
|
+
#
|
|
16
|
+
# Box is distributed in the hope that it will be useful,
|
|
17
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
18
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
19
|
+
# GNU General Public License for more details.
|
|
20
|
+
#
|
|
21
|
+
# You should have received a copy of the GNU General Public License
|
|
22
|
+
# along with Box. If not, see <http://www.gnu.org/licenses/>.
|
|
23
|
+
#
|
|
24
|
+
# TODO:
|
|
25
|
+
# - Do signitures belong under data/{name}/?
|
|
26
|
+
# Heck do all these metadata files belong there?
|
|
27
|
+
# OTOH using remote require, how would one access these?
|
|
28
|
+
# should they be contigious to the libs themselves?
|
|
29
|
+
|
|
30
|
+
#require 'autorake/tasks/manifest'
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
module Box
|
|
34
|
+
|
|
35
|
+
# Create signitures for libraries.
|
|
36
|
+
#
|
|
37
|
+
class Sign #< Tool
|
|
38
|
+
|
|
39
|
+
# Define signiture tasks.
|
|
40
|
+
|
|
41
|
+
def task_sign
|
|
42
|
+
|
|
43
|
+
desc "Generate file signitures"
|
|
44
|
+
task :sign do
|
|
45
|
+
project.sign
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Default set of files to sign.
|
|
51
|
+
DEFAULT_SIGN_FILES = ['lib/**/*', 'ext/**/*']
|
|
52
|
+
|
|
53
|
+
DEFAULT_PUBLIC_KEY = 'pubkey.pem'
|
|
54
|
+
DEFAULT_PRIVATE_KEY = '_privkey.pem'
|
|
55
|
+
|
|
56
|
+
# Generate file signitures. This task generates signitures
|
|
57
|
+
# for each library file using public/private keys.
|
|
58
|
+
# The sign script will generate encrypted signitures for
|
|
59
|
+
# files in the project --by default the lib/ and ext/ files.
|
|
60
|
+
#
|
|
61
|
+
# name Project name [name]
|
|
62
|
+
# keyfile Pathname to .pem file for private key
|
|
63
|
+
# files Files to include/exclude.
|
|
64
|
+
# output Directory to store signiture files
|
|
65
|
+
# [data/{name}/signitures/]
|
|
66
|
+
#
|
|
67
|
+
# By default the keyfile is '_privkey.pem'. (BE SURE NEVER
|
|
68
|
+
# TO PUBLISH THIS FILE!!!) But if no a private key file is
|
|
69
|
+
# given/found, this will ask if you would like to
|
|
70
|
+
# generate one. It also can generate a public key for the
|
|
71
|
+
# project if it does not have one.
|
|
72
|
+
#
|
|
73
|
+
# There are two ways to approach key usage here. Either
|
|
74
|
+
# a per project key pair, or use a personal key pair.
|
|
75
|
+
|
|
76
|
+
def sign( override=nil )
|
|
77
|
+
name = info.project
|
|
78
|
+
keyfile = info.private_key
|
|
79
|
+
|
|
80
|
+
output = info.sign_output
|
|
81
|
+
files = info.sign_files
|
|
82
|
+
|
|
83
|
+
files ||= DEFAULT_SIGN_FILES
|
|
84
|
+
keyfile ||= DEFAULT_PRIVATE_KEY
|
|
85
|
+
output ||= File.join('data',name,'signitures')
|
|
86
|
+
|
|
87
|
+
files = Dir.multiglob_with_default(DEFAULT_SIGN_FILES, files)
|
|
88
|
+
|
|
89
|
+
unless File.directory?( dir = File.dirname(output) )
|
|
90
|
+
puts "Output directory #{dir} doesn't exist."
|
|
91
|
+
return nil
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
output = File.expand_path(output)
|
|
95
|
+
|
|
96
|
+
unless keyfile and File.exist?(keyfile)
|
|
97
|
+
ans = ask("Private key file required. Generate one?", "yN")
|
|
98
|
+
case ans
|
|
99
|
+
when 'y', 'Y'
|
|
100
|
+
keyfile = genkey(name)
|
|
101
|
+
puts "\nFile '#{keyfile}' created. Be sure to keep this file private and secure."
|
|
102
|
+
else
|
|
103
|
+
puts "Task cancelled."
|
|
104
|
+
exit -1
|
|
105
|
+
#return nil
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
keyfile = File.expand_path(keyfile)
|
|
110
|
+
|
|
111
|
+
generate_signitures(keyfile, files, output)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
private
|
|
115
|
+
|
|
116
|
+
# Generate a signiture for a file.
|
|
117
|
+
|
|
118
|
+
def generate_signitures( keyfile, files, to_folder )
|
|
119
|
+
privkey = load_key(keyfile)
|
|
120
|
+
|
|
121
|
+
dir = File.dirname(to_folder)
|
|
122
|
+
save_key(privkey.public_key, File.join(dir, DEFAULT_PUBLIC_KEY))
|
|
123
|
+
|
|
124
|
+
fu.mkdir_p(to_folder)
|
|
125
|
+
files.each do |file|
|
|
126
|
+
next if File.directory?(file)
|
|
127
|
+
sig = sign_file(privkey, file)
|
|
128
|
+
write_signiture(to_folder, file, sig)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Write signiture to file.
|
|
133
|
+
|
|
134
|
+
def write_signiture( to_folder, file, sig )
|
|
135
|
+
sigfile = File.join(to_folder, file + '.sig')
|
|
136
|
+
fu.mkdir_p(File.dirname(sigfile))
|
|
137
|
+
if project.dryrun?
|
|
138
|
+
puts "(save #{sigfile})" unless project.quiet?
|
|
139
|
+
else
|
|
140
|
+
File.open( sigfile, 'w' ) do |f|
|
|
141
|
+
f << sig
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Generate a signiture of a file.
|
|
147
|
+
|
|
148
|
+
def sign_file( key, file )
|
|
149
|
+
plain = File.read( file )
|
|
150
|
+
dig = digester(info.digest||'sha256').new
|
|
151
|
+
sig = key.sign(dig, plain)
|
|
152
|
+
return sig
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Verify a signiture of a file.
|
|
156
|
+
|
|
157
|
+
def verify_signiture?( pubkey, sig, plain )
|
|
158
|
+
plain = plain.read if IO === plain
|
|
159
|
+
dig = digester(info.digest||'sha256').new
|
|
160
|
+
success = pubkey.verify(dig, sig, plain)
|
|
161
|
+
return success
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Generate a public key from a private key.
|
|
165
|
+
#
|
|
166
|
+
#def pubkey( privkey )
|
|
167
|
+
# pubkey = privkey.public_key
|
|
168
|
+
# return pubkey
|
|
169
|
+
#end
|
|
170
|
+
|
|
171
|
+
# Load key.
|
|
172
|
+
|
|
173
|
+
def load_key( file )
|
|
174
|
+
key = OpenSSL::PKey::RSA.new(File.read(file))
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Save key.
|
|
178
|
+
|
|
179
|
+
def save_key( key, file )
|
|
180
|
+
if project.dryrun?
|
|
181
|
+
puts "(save #{file})" unless project.quiet?
|
|
182
|
+
else
|
|
183
|
+
File.open( file, 'w' ) do |f|
|
|
184
|
+
f << key.to_pem
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Generate a private key and save it to '_privkey.pem'.
|
|
190
|
+
|
|
191
|
+
def genkey( name )
|
|
192
|
+
key = OpenSSL::PKey::RSA.new(2048){ print "." } # @name }
|
|
193
|
+
save_key( key, PRIVATE_KEY )
|
|
194
|
+
return PRIVATE_KEY
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# def write_keypair( libname )
|
|
198
|
+
# privkey = genkey( libname )
|
|
199
|
+
# pubkey = privkey.public_key
|
|
200
|
+
# save_key( privkey, "privkey.pem" )
|
|
201
|
+
# save_key( pubkey, "pubkey.pem" )
|
|
202
|
+
# puts "Key pair generated. Please secure privkey.pem."
|
|
203
|
+
# end
|
|
204
|
+
#
|
|
205
|
+
# # Generate a private key.
|
|
206
|
+
#
|
|
207
|
+
# def genkey( libname='.' )
|
|
208
|
+
# key = OpenSSL::PKey::RSA.new(2048) { print "." } # libname }
|
|
209
|
+
# return key
|
|
210
|
+
# end
|
|
211
|
+
#
|
|
212
|
+
# # Generate a public key from a private key.
|
|
213
|
+
#
|
|
214
|
+
# def pubkey( privkey )
|
|
215
|
+
# pubkey = privkey.public_key
|
|
216
|
+
# return pubkey
|
|
217
|
+
# end
|
|
218
|
+
|
|
219
|
+
# Return a digest class for given +type+.
|
|
220
|
+
# Supported digests are:
|
|
221
|
+
#
|
|
222
|
+
# * md5
|
|
223
|
+
# * sha1
|
|
224
|
+
# * sha128 (same as sha1)
|
|
225
|
+
# * sha256
|
|
226
|
+
# * sha512
|
|
227
|
+
#
|
|
228
|
+
# Default digest type is sha256.
|
|
229
|
+
|
|
230
|
+
# def digester( type=nil )
|
|
231
|
+
# require 'openssl'
|
|
232
|
+
# type = 'sha256' unless type
|
|
233
|
+
# case type.to_s.downcase
|
|
234
|
+
# when 'md5'
|
|
235
|
+
# require 'digest/md5'
|
|
236
|
+
# Digest::MD5
|
|
237
|
+
# when 'sha128', 'sha1'
|
|
238
|
+
# require 'digest/sha1' #need?
|
|
239
|
+
# OpenSSL::Digest::SHA1
|
|
240
|
+
# when 'sha256'
|
|
241
|
+
# require 'digest/sha1' #need?
|
|
242
|
+
# OpenSSL::Digest::SHA256
|
|
243
|
+
# when 'sha512'
|
|
244
|
+
# require 'digest/sha1' #need?
|
|
245
|
+
# OpenSSL::Digest::SHA512
|
|
246
|
+
# end
|
|
247
|
+
# end
|
|
248
|
+
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
end
|
|
252
|
+
|