smallcage 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/History.txt +15 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +70 -0
  4. data/README.txt +1 -0
  5. data/Rakefile +4 -0
  6. data/bin/smc +136 -0
  7. data/config/hoe.rb +70 -0
  8. data/config/requirements.rb +17 -0
  9. data/lib/smallcage/commands/Manifest.erb +19 -0
  10. data/lib/smallcage/commands/auto.rb +52 -0
  11. data/lib/smallcage/commands/clean.rb +24 -0
  12. data/lib/smallcage/commands/import.rb +212 -0
  13. data/lib/smallcage/commands/manifest.rb +39 -0
  14. data/lib/smallcage/commands/server.rb +24 -0
  15. data/lib/smallcage/commands/update.rb +40 -0
  16. data/lib/smallcage/erb_base.rb +16 -0
  17. data/lib/smallcage/loader.rb +239 -0
  18. data/lib/smallcage/misc.rb +13 -0
  19. data/lib/smallcage/renderer.rb +19 -0
  20. data/lib/smallcage/runner.rb +36 -0
  21. data/lib/smallcage/version.rb +9 -0
  22. data/lib/smallcage.rb +22 -0
  23. data/log/debug.log +0 -0
  24. data/project/default/_smc/helpers/base_helper.rb +34 -0
  25. data/project/default/_smc/helpers/site_helper.rb +5 -0
  26. data/project/default/_smc/templates/default.rhtml +5 -0
  27. data/project/default/_smc/templates/footer.rhtml +0 -0
  28. data/project/default/_smc/templates/header.rhtml +0 -0
  29. data/project/nkf/_smc/filters/filters.yml +3 -0
  30. data/project/nkf/_smc/filters/nkf_filter.rb +15 -0
  31. data/project/relpath/_smc/filters/filters.yml +2 -0
  32. data/project/relpath/_smc/filters/relpath_filter.rb +13 -0
  33. data/project/standard/_dir.smc +2 -0
  34. data/project/standard/_smc/helpers/menu_helper.rb +23 -0
  35. data/project/standard/_smc/templates/footer.rhtml +12 -0
  36. data/project/standard/_smc/templates/header.rhtml +35 -0
  37. data/project/standard/_smc/templates/redirect.rhtml +13 -0
  38. data/project/standard/_smc/templates/sidebar.rhtml +9 -0
  39. data/project/standard/_smc/templates/topic_path.rhtml +6 -0
  40. data/project/standard/about/_dir.smc +1 -0
  41. data/project/standard/about/index.html.smc +3 -0
  42. data/project/standard/common/css/default.css +97 -0
  43. data/project/standard/common/css/print.css +0 -0
  44. data/project/standard/index.html.smc +3 -0
  45. data/project/standard/sample1/_dir.smc +1 -0
  46. data/project/standard/sample1/index.html.smc +7 -0
  47. data/project/standard/sample1/index2.html.smc +5 -0
  48. data/project/standard/sample1/redirect.html.smc +2 -0
  49. data/project/standard/sample2/_dir.smc +1 -0
  50. data/project/standard/sample2/index.html.smc +3 -0
  51. data/script/destroy +14 -0
  52. data/script/destroy.cmd +1 -0
  53. data/script/generate +14 -0
  54. data/script/generate.cmd +1 -0
  55. data/setup.rb +1585 -0
  56. data/spec/data/htdocs1/_dir.smc +0 -0
  57. data/spec/data/htdocs1/a/b/c/index.html.smc +1 -0
  58. data/spec/import_spec.rb +20 -0
  59. data/spec/loader_spec.rb +41 -0
  60. data/spec/manifest_spec.rb +32 -0
  61. data/spec/misc_spec.rb +25 -0
  62. data/spec/smallcage_spec.rb +34 -0
  63. data/spec/spec.opts +1 -0
  64. data/spec/spec_helper.rb +9 -0
  65. data/tasks/deployment.rake +27 -0
  66. data/tasks/environment.rake +7 -0
  67. data/tasks/rspec.rake +21 -0
  68. data/tasks/website.rake +9 -0
  69. data/test/test_helper.rb +2 -0
  70. data/test/test_smallcage.rb +11 -0
  71. metadata +132 -0
data/History.txt ADDED
@@ -0,0 +1,15 @@
1
+ == 0.0.6 2007-11-04
2
+
3
+ * smcオブジェクトのpathがStringだったのをPathnameを保持するように修正。ファイルアクセスで使う値なのでPathnameの方が良いと判断しました。
4
+ * updateで拡張子smcを省略するとエラーになる問題を修正。
5
+ * ドキュメントルートが見つからない場合にループしてしまう問題を修正。
6
+ * ドキュメントルート以下に移動してupdateするとエラーになる問題を修正。
7
+
8
+ == 0.0.5 2007-11-01
9
+
10
+ * smcファイル内でerbを使うためにRendererにメソッドを追加。
11
+
12
+ == 0.0.1 2007-08-22
13
+
14
+ * 1 major enhancement:
15
+ * Initial release
data/License.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007 FIXME full name
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt ADDED
@@ -0,0 +1,70 @@
1
+ History.txt
2
+ License.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ bin/smc
7
+ config/hoe.rb
8
+ config/requirements.rb
9
+ lib/smallcage.rb
10
+ lib/smallcage/commands/Manifest.erb
11
+ lib/smallcage/commands/auto.rb
12
+ lib/smallcage/commands/clean.rb
13
+ lib/smallcage/commands/import.rb
14
+ lib/smallcage/commands/manifest.rb
15
+ lib/smallcage/commands/server.rb
16
+ lib/smallcage/commands/update.rb
17
+ lib/smallcage/erb_base.rb
18
+ lib/smallcage/loader.rb
19
+ lib/smallcage/misc.rb
20
+ lib/smallcage/renderer.rb
21
+ lib/smallcage/runner.rb
22
+ lib/smallcage/version.rb
23
+ log/debug.log
24
+ project/default/_smc/helpers/base_helper.rb
25
+ project/default/_smc/helpers/site_helper.rb
26
+ project/default/_smc/templates/default.rhtml
27
+ project/default/_smc/templates/footer.rhtml
28
+ project/default/_smc/templates/header.rhtml
29
+ project/nkf/_smc/filters/filters.yml
30
+ project/nkf/_smc/filters/nkf_filter.rb
31
+ project/relpath/_smc/filters/filters.yml
32
+ project/relpath/_smc/filters/relpath_filter.rb
33
+ project/standard/_dir.smc
34
+ project/standard/_smc/helpers/menu_helper.rb
35
+ project/standard/_smc/templates/footer.rhtml
36
+ project/standard/_smc/templates/header.rhtml
37
+ project/standard/_smc/templates/redirect.rhtml
38
+ project/standard/_smc/templates/sidebar.rhtml
39
+ project/standard/_smc/templates/topic_path.rhtml
40
+ project/standard/about/_dir.smc
41
+ project/standard/about/index.html.smc
42
+ project/standard/common/css/default.css
43
+ project/standard/common/css/print.css
44
+ project/standard/index.html.smc
45
+ project/standard/sample1/_dir.smc
46
+ project/standard/sample1/index.html.smc
47
+ project/standard/sample1/index2.html.smc
48
+ project/standard/sample1/redirect.html.smc
49
+ project/standard/sample2/_dir.smc
50
+ project/standard/sample2/index.html.smc
51
+ script/destroy
52
+ script/destroy.cmd
53
+ script/generate
54
+ script/generate.cmd
55
+ setup.rb
56
+ spec/data/htdocs1/_dir.smc
57
+ spec/data/htdocs1/a/b/c/index.html.smc
58
+ spec/import_spec.rb
59
+ spec/loader_spec.rb
60
+ spec/manifest_spec.rb
61
+ spec/misc_spec.rb
62
+ spec/smallcage_spec.rb
63
+ spec/spec.opts
64
+ spec/spec_helper.rb
65
+ tasks/deployment.rake
66
+ tasks/environment.rake
67
+ tasks/rspec.rake
68
+ tasks/website.rake
69
+ test/test_helper.rb
70
+ test/test_smallcage.rb
data/README.txt ADDED
@@ -0,0 +1 @@
1
+ README
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require 'config/requirements'
2
+ require 'config/hoe' # setup Hoe + all gem configuration
3
+
4
+ Dir['tasks/**/*.rake'].each { |rake| load rake }
data/bin/smc ADDED
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created on 2007-8-22.
4
+ # Copyright (c) 2007. All rights reserved.
5
+
6
+ begin
7
+ require 'rubygems'
8
+ rescue LoadError
9
+ # no rubygems to load, so we fail silently
10
+ end
11
+
12
+ require 'smallcage'
13
+ require 'optparse'
14
+
15
+ STDOUT.sync = true
16
+
17
+ VERSION_NOTE = "SmallCage #{SmallCage::VERSION::STRING} - Lightweight CMS Package."
18
+ OPTIONS = {}
19
+ OPTIONS[:original_argv] = ARGV.clone
20
+
21
+ OptionParser.new do |opts|
22
+
23
+ opts.banner =<<BANNER
24
+ Usage: #{File.basename($0)} <subcommand> [options]
25
+ #{VERSION_NOTE}
26
+ Subcommands are:
27
+ update [path] Build smc contents.
28
+ clean [path] Remove files generated from *.smc source.
29
+ server [path] [port] Start HTTP server.
30
+ auto [path] Start auto update daemon.
31
+ import [name|uri] Import project.
32
+ manifest [path] Generate Manifest.html file.
33
+
34
+ Options are:
35
+ BANNER
36
+
37
+ opts.separator ""
38
+ opts.on("-h", "--help", "Show this help message.") do
39
+ puts opts
40
+ exit
41
+ end
42
+ opts.on("-v", "--version", "Show version info.") do
43
+ puts VERSION_NOTE
44
+ exit
45
+ end
46
+
47
+ subparsers = Hash.new do |h,k|
48
+ $stderr.puts "no such subcommand: #{k}"
49
+ exit 1
50
+ end
51
+
52
+ subparsers[:update] = OptionParser.new do |subp|
53
+ subp.banner =<<EOT
54
+ Usage: update [PATH]
55
+ EOT
56
+ end
57
+
58
+ subparsers[:server] = OptionParser.new do |subp|
59
+ subp.banner =<<EOT
60
+ Usage: server [PATH] [PORT]
61
+ EOT
62
+ end
63
+
64
+ subparsers[:auto] = OptionParser.new do |subp|
65
+ subp.banner =<<EOT
66
+ Usage: auto [PATH]
67
+ EOT
68
+ end
69
+
70
+ subparsers[:generate] = OptionParser.new do |subp|
71
+ end
72
+ subparsers[:release] = OptionParser.new do |subp|
73
+ end
74
+ subparsers[:help] = OptionParser.new do |subp|
75
+ end
76
+ subparsers[:import] = OptionParser.new do |subp|
77
+ end
78
+ subparsers[:manifest] = OptionParser.new do |subp|
79
+ end
80
+ subparsers[:clean] = OptionParser.new do |subp|
81
+ end
82
+
83
+ commands = Hash.new {|h,k| k}
84
+ commands.merge!({
85
+ :up => :update,
86
+ :sv => :server,
87
+ :au => :auto,
88
+ :gen => :generate,
89
+ :rel => :release,
90
+ :st => :status,
91
+ })
92
+
93
+ opts.order!(ARGV)
94
+ unless ARGV.empty?
95
+ OPTIONS[:command] = commands[ARGV.shift.to_sym]
96
+ subparsers[OPTIONS[:command]].parse!(ARGV)
97
+ end
98
+
99
+ if OPTIONS[:command].nil?
100
+ puts opts
101
+ exit
102
+ elsif OPTIONS[:command] == :help
103
+ subcmd = ARGV.shift
104
+ if subcmd.nil?
105
+ puts opts
106
+ else
107
+ puts subparsers[subcmd.to_sym]
108
+ end
109
+ exit
110
+ elsif OPTIONS[:command] == :update
111
+ OPTIONS[:path] = ARGV.shift
112
+ OPTIONS[:path] ||= "."
113
+ elsif OPTIONS[:command] == :server
114
+ OPTIONS[:path] = ARGV.shift
115
+ OPTIONS[:port] = ARGV.shift
116
+ OPTIONS[:path] ||= "."
117
+ OPTIONS[:port] ||= 80
118
+ elsif OPTIONS[:command] == :auto
119
+ OPTIONS[:path] = ARGV.shift
120
+ OPTIONS[:path] ||= "."
121
+ elsif OPTIONS[:command] == :import
122
+ OPTIONS[:from] = ARGV.shift
123
+ OPTIONS[:from] ||= "default"
124
+
125
+ OPTIONS[:to] = ARGV.shift
126
+ OPTIONS[:to] ||= "."
127
+ elsif OPTIONS[:command] == :manifest
128
+ OPTIONS[:path] = ARGV.shift
129
+ OPTIONS[:path] ||= "."
130
+ elsif OPTIONS[:command] == :clean
131
+ OPTIONS[:path] = ARGV.shift
132
+ OPTIONS[:path] ||= "."
133
+ end
134
+ end
135
+
136
+ SmallCage::Runner.run(OPTIONS)
data/config/hoe.rb ADDED
@@ -0,0 +1,70 @@
1
+ require 'smallcage/version'
2
+
3
+ AUTHOR = ['SAITO Toshihiro', 'KOSEKI Kengo', 'SATO Akihiko'] # can also be an array of Authors
4
+ EMAIL = ["saito@bluemark.jp", "koseki@bluemark.jp", "gom@bluemark.jp"]
5
+ DESCRIPTION = "Lightweigt CMS Package."
6
+ GEM_NAME = 'smallcage' # what ppl will type to install your gem
7
+ RUBYFORGE_PROJECT = 'smallcage' # The unix name for your project
8
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
9
+ DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
10
+
11
+ @config_file = "~/.rubyforge/user-config.yml"
12
+ @config = nil
13
+ RUBYFORGE_USERNAME = "unknown"
14
+ def rubyforge_username
15
+ unless @config
16
+ begin
17
+ @config = YAML.load(File.read(File.expand_path(@config_file)))
18
+ rescue
19
+ puts <<-EOS
20
+ ERROR: No rubyforge config file found: #{@config_file}"
21
+ Run 'rubyforge setup' to prepare your env for access to Rubyforge
22
+ - See http://newgem.rubyforge.org/rubyforge.html for more details
23
+ EOS
24
+ exit
25
+ end
26
+ end
27
+ RUBYFORGE_USERNAME.replace @config["username"]
28
+ end
29
+
30
+
31
+ REV = nil
32
+ # UNCOMMENT IF REQUIRED:
33
+ # REV = `svn info`.each {|line| if line =~ /^Revision:/ then k,v = line.split(': '); break v.chomp; else next; end} rescue nil
34
+ VERS = SmallCage::VERSION::STRING + (REV ? ".#{REV}" : "")
35
+ RDOC_OPTS = ['--quiet', '--title', 'smallcage documentation',
36
+ "--opname", "index.html",
37
+ "--line-numbers",
38
+ "--main", "README",
39
+ "--inline-source"]
40
+
41
+ class Hoe
42
+ def extra_deps
43
+ @extra_deps.reject! { |x| Array(x).first == 'hoe' }
44
+ @extra_deps
45
+ end
46
+ end
47
+
48
+ # Generate all the Rake tasks
49
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
50
+ hoe = Hoe.new(GEM_NAME, VERS) do |p|
51
+ p.author = AUTHOR
52
+ p.description = DESCRIPTION
53
+ p.email = EMAIL
54
+ p.summary = DESCRIPTION
55
+ p.url = HOMEPATH
56
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
57
+ p.test_globs = ["test/**/test_*.rb"]
58
+ p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
59
+
60
+ # == Optional
61
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\\n\\n")
62
+ #p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
63
+
64
+ #p.spec_extras = {} # A hash of extra values to set in the gemspec.
65
+
66
+ end
67
+
68
+ CHANGES = hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
69
+ PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
70
+ hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
@@ -0,0 +1,17 @@
1
+ require 'fileutils'
2
+ include FileUtils
3
+
4
+ require 'rubygems'
5
+ %w[rake hoe newgem rubigen].each do |req_gem|
6
+ begin
7
+ require req_gem
8
+ rescue LoadError
9
+ puts "This Rakefile requires the '#{req_gem}' RubyGem."
10
+ puts "Installation: gem install #{req_gem} -y"
11
+ exit
12
+ end
13
+ end
14
+
15
+ $:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
16
+
17
+ require 'smallcage'
@@ -0,0 +1,19 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml">
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6
+ <title>SmallCage Project Files</title>
7
+ </head>
8
+ <body>
9
+
10
+ <h1>SmallCage Project Files</h1>
11
+
12
+ <ul class="files">
13
+ <%- entries.each do |e| -%>
14
+ <li><a href="<%= e %>"><%= e %></a></li>
15
+ <%- end -%>
16
+ </ul>
17
+
18
+ </body>
19
+ </html>
@@ -0,0 +1,52 @@
1
+ module SmallCage::Commands
2
+ class Auto
3
+ def self.execute(opts)
4
+ self.new(opts).execute
5
+ end
6
+
7
+ def initialize(opts)
8
+ @opts = opts
9
+ @target = Pathname.new(opts[:path])
10
+ @sleep = 1
11
+ @mtimes = {}
12
+ end
13
+
14
+ def execute
15
+ puts "SmallCage Auto Update"
16
+ puts "-" * 60
17
+
18
+ ['INT', 'TERM'].each do |signal|
19
+ Signal.trap(signal) do
20
+ puts
21
+ puts "exit."
22
+ exit
23
+ end
24
+ end
25
+
26
+ loop do
27
+ sleep @sleep
28
+
29
+ loader = SmallCage::Loader.new(@target)
30
+
31
+ do_update = false
32
+ loader.each_smc_file do |f|
33
+ mtime = File.stat(f).mtime
34
+ if @mtimes[f] != mtime
35
+ @mtimes[f] = mtime
36
+ do_update = true
37
+ end
38
+ end
39
+
40
+ if do_update
41
+ runner = SmallCage::Runner.new({ :path => @target })
42
+ runner.update
43
+ print "\a"
44
+ puts "-" * 60
45
+ end
46
+
47
+ end
48
+
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,24 @@
1
+ module SmallCage::Commands
2
+ class Clean
3
+ def self.execute(opts)
4
+ self.new(opts).execute
5
+ end
6
+
7
+ def initialize(opts)
8
+ @opts = opts
9
+ end
10
+
11
+ def execute
12
+ target = Pathname.new(@opts[:path])
13
+ unless target.exist?
14
+ raise "target directory or file does not exist.: " + target.to_s
15
+ end
16
+
17
+ loader = SmallCage::Loader.new(target)
18
+ loader.each_smc_obj do |obj|
19
+ obj["path"].delete
20
+ puts "remove: " + obj["uri"]
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,212 @@
1
+ module SmallCage::Commands
2
+ class Import
3
+ def self.execute(opts)
4
+ self.new(opts).execute
5
+ end
6
+
7
+ def initialize(opts)
8
+ @opts = opts
9
+ @project_dir = Pathname.new(__FILE__) + "../../../../project"
10
+ end
11
+
12
+ def qp(str = "")
13
+ print str unless @opts[:quiet]
14
+ end
15
+
16
+ def qps(str = "")
17
+ puts str unless @opts[:quiet]
18
+ end
19
+
20
+ def execute
21
+ @dest = Pathname.new(@opts[:to])
22
+
23
+ Dir.mkdir(@dest) unless @dest.exist?
24
+ return unless @dest.directory?
25
+
26
+ from = @opts[:from].split(/,/)
27
+ from.each do |f|
28
+ qps
29
+ qps "Import: #{f}"
30
+ if f =~ %r{^https?://}
31
+ import_external(f)
32
+ elsif f =~ %r{^\w+$}
33
+ import(f)
34
+ else
35
+ end
36
+ end
37
+ end
38
+
39
+ def import(from)
40
+ d = @project_dir + from
41
+ return unless d.directory?
42
+ @entries = local_entries(d)
43
+ unless @opts[:quiet]
44
+ return unless confirm_entries
45
+ end
46
+ import_entries
47
+ end
48
+
49
+ def import_external
50
+ @entries = external_entries
51
+ unless @opts[:quiet]
52
+ return unless confirm_entries
53
+ end
54
+ import_entries
55
+ end
56
+
57
+ def import_entries
58
+ failed = []
59
+ @entries.each do |e|
60
+ if e.overwrite?
61
+ qp "*"
62
+ elsif ! e.exist?
63
+ qp "+"
64
+ else
65
+ qp " "
66
+ end
67
+ qps " " + e.path
68
+ begin
69
+ e.import
70
+ rescue
71
+ failed << e
72
+ qps "F " + e.path
73
+ end
74
+ end
75
+
76
+ unless failed.empty?
77
+ qps "FAILED:"
78
+ failed.each do |e|
79
+ qps " " + e.path
80
+ end
81
+ end
82
+ end
83
+ private :import_entries
84
+
85
+ def local_entries(d)
86
+ result = []
87
+ Dir.chdir(d) do
88
+ Dir.glob("**/*") do |f|
89
+ e = ImportEntry.new
90
+ e.path = f
91
+ e.from = d + f
92
+ e.to = @dest + f
93
+ result << e
94
+ end
95
+ end
96
+ return result
97
+ end
98
+ private :local_entries
99
+
100
+ def external_entries(uri)
101
+ if uri !~ %r{/$}
102
+ uri += "/"
103
+ end
104
+ mfuri = uri + "Manifest.html"
105
+
106
+ source = open(mfuri) {|io| io.read }
107
+ result = []
108
+
109
+ files = source.scan(%r{<li><a href="(./[^"]+)">(./[^<]+)</a></li>})
110
+ files.each do |f|
111
+ raise "illegal path:#{f[0]},#{f[1]}" if f[0] != f[1]
112
+ raise "illegal path:#{f[0]}" if f[0] =~ %r{/\.\.}
113
+ path = f[0]
114
+ e = ImportEntry.new
115
+ e.path = path
116
+ e.from = uri + path
117
+ e.to = @dest + path
118
+ result << e
119
+ end
120
+
121
+ return result
122
+ end
123
+ private :external_entries
124
+
125
+ def confirm_entries
126
+ overwrite = []
127
+
128
+ qps "Create:"
129
+ @entries.each do |e|
130
+ if e.overwrite?
131
+ overwrite << e
132
+ elsif ! e.exist?
133
+ qps " " + e.path
134
+ end
135
+ end
136
+ qps
137
+
138
+ unless overwrite.empty?
139
+ qps "Overwrite:"
140
+ overwrite.each do |e|
141
+ qps " " + e.path
142
+ end
143
+ qps
144
+ end
145
+
146
+ return y_or_n("Import these files?[yN]: ", false)
147
+ end
148
+ private :confirm_entries
149
+
150
+ def y_or_n(prompt, default)
151
+ loop do
152
+ print prompt
153
+ yn = STDIN.gets.strip
154
+ if yn =~ /^(y|yes)$/i
155
+ return true
156
+ elsif yn =~ /^(n|no)$/i
157
+ return false
158
+ elsif yn == ""
159
+ return default
160
+ end
161
+ end
162
+ end
163
+ private :y_or_n
164
+
165
+
166
+ class ImportEntry
167
+ attr_accessor :path, :from, :to
168
+
169
+ def import
170
+ if external?
171
+ copy_external
172
+ else
173
+ copy_local
174
+ end
175
+ end
176
+
177
+ def external?
178
+ from =~ %r{^https?://}
179
+ end
180
+
181
+ def exist?
182
+ to.exist?
183
+ end
184
+
185
+ def overwrite?
186
+ to.file?
187
+ end
188
+
189
+ def copy_local
190
+ if from.directory?
191
+ FileUtils.makedirs(to)
192
+ else
193
+ FileUtils.makedirs(to.parent)
194
+ FileUtils.copy(from, to)
195
+ end
196
+ end
197
+ private :copy_local
198
+
199
+ def copy_external
200
+ if from =~ %r{/$}
201
+ FileUtils.makedirs(to)
202
+ else
203
+ FileUtils.makedirs(to.parent)
204
+ s = open(from) {|io| io.read }
205
+ open(to, "w") {|io| io << s }
206
+ end
207
+ end
208
+ private :copy_external
209
+
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,39 @@
1
+ module SmallCage::Commands
2
+ class Manifest
3
+ def self.execute(opts)
4
+ self.new(opts).execute
5
+ end
6
+
7
+ def initialize(opts)
8
+ @opts = opts
9
+ end
10
+
11
+ def execute
12
+ entries = []
13
+ root = Pathname.new(@opts[:path])
14
+ Dir.chdir(root) do
15
+ Dir.glob("**/*") do |f|
16
+ entries << f
17
+ end
18
+ end
19
+
20
+ tmp = []
21
+ entries.each do |f|
22
+ path = root + f
23
+ f = "./" + f
24
+ if path.directory?
25
+ f = f + "/"
26
+ end
27
+ next if path.basename.to_s == "Manifest.html"
28
+ tmp << f
29
+ end
30
+ entries = tmp
31
+
32
+ template = File.dirname(__FILE__) + "/Manifest.erb"
33
+ source = ERB.new(File.read(template), nil, "-").result(binding)
34
+ open(root + "Manifest.html", "w") do |io|
35
+ io << source
36
+ end
37
+ end
38
+ end
39
+ end