andparcel 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/.document +5 -0
  2. data/.gitignore +23 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +7 -0
  5. data/Rakefile +60 -0
  6. data/TODO +92 -0
  7. data/VERSION +1 -0
  8. data/andparcel.gemspec +103 -0
  9. data/bin/parcel +161 -0
  10. data/lib/andparcel/base.rb +22 -0
  11. data/lib/andparcel/catalog.rb +75 -0
  12. data/lib/andparcel/fileref.rb +21 -0
  13. data/lib/andparcel/parcel.rb +533 -0
  14. data/lib/andparcel.rb +3 -0
  15. data/test/ParcelReceiver/AndroidManifest.xml +15 -0
  16. data/test/ParcelReceiver/build.properties +17 -0
  17. data/test/ParcelReceiver/build.xml +67 -0
  18. data/test/ParcelReceiver/default.properties +11 -0
  19. data/test/ParcelReceiver/local.properties +10 -0
  20. data/test/ParcelReceiver/res/layout/main.xml +13 -0
  21. data/test/ParcelReceiver/res/values/strings.xml +4 -0
  22. data/test/ParcelReceiver/src/com/commonsware/android/pr/ParcelReceiver.java +15 -0
  23. data/test/ParcelToPackage/AndroidManifest.xml +15 -0
  24. data/test/ParcelToPackage/build.properties +17 -0
  25. data/test/ParcelToPackage/build.xml +67 -0
  26. data/test/ParcelToPackage/default.properties +11 -0
  27. data/test/ParcelToPackage/docs/README +1 -0
  28. data/test/ParcelToPackage/docs/SomeOtherFile +0 -0
  29. data/test/ParcelToPackage/libs/one.jar +0 -0
  30. data/test/ParcelToPackage/libs/two.jar +0 -0
  31. data/test/ParcelToPackage/local.properties +10 -0
  32. data/test/ParcelToPackage/parcel.json +17 -0
  33. data/test/ParcelToPackage/res/layout/andParcel_test_row.xml +13 -0
  34. data/test/ParcelToPackage/res/values/strings.xml +4 -0
  35. data/test/ParcelToPackage/src/com/commonsware/android/p2pkg/ParcelToPackage.java +15 -0
  36. data/test/ParcelToPackage/tmp/andParcel-test_0.1.0.zip +0 -0
  37. data/test/test_init.rb +42 -0
  38. data/test/test_install.rb +170 -0
  39. data/test/test_package.rb +218 -0
  40. data/test/test_remove.rb +86 -0
  41. metadata +158 -0
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ *.kpf
23
+ TODO
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Mark Murphy
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/README.rdoc ADDED
@@ -0,0 +1,7 @@
1
+ = andparcel
2
+
3
+ Description goes here.
4
+
5
+ == Copyright
6
+
7
+ Copyright (c) 2010 CommonsWare, LLC. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,60 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "andparcel"
8
+ gem.summary = %Q{Support for Android Parcel packaging system}
9
+ gem.description = %Q{Supplies the parcel command for packaging, installing, and removing parcels from an Android project}
10
+ gem.email = "mmurphy@commonsware.com"
11
+ gem.homepage = "http://github.com/commonsguy/andparcel"
12
+ gem.authors = ["Mark Murphy"]
13
+ gem.add_development_dependency "protest", ">= 0"
14
+ gem.files.include %w(lib/**/*.rb)
15
+ gem.add_dependency('rubyzip', '>= 0.9.4')
16
+ gem.add_dependency('json', '>= 1.2.3')
17
+ gem.add_dependency('nokogiri', '>= 1.4.1')
18
+ gem.add_dependency('rio', '>= 0.4.2')
19
+ gem.add_dependency('trollop', '>= 1.15')
20
+
21
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
22
+ end
23
+ Jeweler::GemcutterTasks.new
24
+ rescue LoadError
25
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
26
+ end
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ begin
36
+ require 'rcov/rcovtask'
37
+ Rcov::RcovTask.new do |test|
38
+ test.libs << 'test'
39
+ test.pattern = 'test/**/test_*.rb'
40
+ test.verbose = true
41
+ end
42
+ rescue LoadError
43
+ task :rcov do
44
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
45
+ end
46
+ end
47
+
48
+ task :test => :check_dependencies
49
+
50
+ task :default => :test
51
+
52
+ require 'rake/rdoctask'
53
+ Rake::RDocTask.new do |rdoc|
54
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
55
+
56
+ rdoc.rdoc_dir = 'rdoc'
57
+ rdoc.title = "andparcel #{version}"
58
+ rdoc.rdoc_files.include('README*')
59
+ rdoc.rdoc_files.include('lib/**/*.rb')
60
+ end
data/TODO ADDED
@@ -0,0 +1,92 @@
1
+ Sunday
2
+ ------
3
+ test on clean Linux, Windows, OS X
4
+ home directory OK?
5
+ wrap AdvAndroid chapters, gen as PDFs w/ "excerpt" footer
6
+ need to get appendix generation going
7
+ RDoc comments
8
+ git repo & publish gem
9
+ VERSION NUMBER
10
+ .gitignore ignores TODO!
11
+ get git.andparcel.org redir to github
12
+ pour rest of this TODO into RTM and GitHub Issues
13
+
14
+ May 10
15
+ ------
16
+ parcelhelper
17
+ README
18
+ put CW logo/links on CWAC README's, add links to CWAC blog posts, other updates
19
+ adapterwrapper
20
+ put CW logo/links on CWAC README's, add links to CWAC blog posts, other updates
21
+ sackofviewsadapter
22
+ put CW logo/links on CWAC README's, add links to CWAC blog posts, other updates
23
+ colormixer
24
+ put CW logo/links on CWAC README's, add links to CWAC blog posts, other updates
25
+ commit all
26
+ parcel
27
+ CWAC mods (need .gitignore fixes)
28
+ Web site w/ pointers to documentation, committed
29
+ announce parcel system
30
+ CW newsletter
31
+ cw-android
32
+ twitter
33
+ my blog
34
+ AG blog -> Tuesday
35
+
36
+ Over Next Few Weeks
37
+ -------------------
38
+ get other key cwac- components parcel'd up
39
+ task
40
+ sample code into separate project
41
+ Ant builds
42
+ main
43
+ sample -- do replace
44
+ parcel.json
45
+ parcel & add to catalog
46
+ put CW logo/links on CWAC README's, add links to CWAC blog posts, other updates
47
+ wakefulintentservice
48
+ sample code into separate project
49
+ Ant builds
50
+ main
51
+ sample -- do replace
52
+ parcel.json
53
+ parcel & add to catalog
54
+ put CW logo/links on CWAC README's, add links to CWAC blog posts, other updates
55
+ endlessadapter
56
+ Ant builds
57
+ parcel.json
58
+ parcel & add to catalog
59
+ put CW logo/links on CWAC README's, add links to CWAC blog posts, other updates
60
+ mergeadapter
61
+ Ant builds
62
+ parcel.json
63
+ parcel & add to catalog
64
+ put CW logo/links on CWAC README's, add links to CWAC blog posts, other updates
65
+
66
+
67
+ Future
68
+ ------
69
+ deal with upgrade (if newer available, do...something)
70
+ support merging non-component manifest entries
71
+ deal with manifest collisions (e.g., sdk levels different)
72
+ input validation
73
+ regex on name, etc.
74
+ SemVer.org validation
75
+ support packaging assets/
76
+ multiple version support (a la gem versions)
77
+ mirror support
78
+ catalogs
79
+ parcels
80
+ fail remove if listed as a dependency of something else
81
+ catalog caching w/ If-Modified-Since/ETag support
82
+ 100% rcov coverage
83
+ rfc5261 support for manifest merges?
84
+ optional signed ZIPs?
85
+ battle plan for new components (see list in sketchpad)
86
+ smart --replace: doesn't download/replace if version same
87
+ dependency tests
88
+ dependency version checking
89
+ version pinning (don't auto-upgrade)
90
+ remove --full gets rid of dependencies
91
+ lint tests
92
+ 100% comments
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/andparcel.gemspec ADDED
@@ -0,0 +1,103 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{andparcel}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Mark Murphy"]
12
+ s.date = %q{2010-05-09}
13
+ s.default_executable = %q{parcel}
14
+ s.description = %q{Supplies the parcel command for packaging, installing, and removing parcels from an Android project}
15
+ s.email = %q{mmurphy@commonsware.com}
16
+ s.executables = ["parcel"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.rdoc",
20
+ "TODO"
21
+ ]
22
+ s.files = [
23
+ ".document",
24
+ ".gitignore",
25
+ "LICENSE",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "andparcel.gemspec",
30
+ "bin/parcel",
31
+ "lib/andparcel.rb",
32
+ "lib/andparcel/base.rb",
33
+ "lib/andparcel/catalog.rb",
34
+ "lib/andparcel/fileref.rb",
35
+ "lib/andparcel/parcel.rb",
36
+ "test/ParcelReceiver/AndroidManifest.xml",
37
+ "test/ParcelReceiver/build.properties",
38
+ "test/ParcelReceiver/build.xml",
39
+ "test/ParcelReceiver/default.properties",
40
+ "test/ParcelReceiver/local.properties",
41
+ "test/ParcelReceiver/res/layout/main.xml",
42
+ "test/ParcelReceiver/res/values/strings.xml",
43
+ "test/ParcelReceiver/src/com/commonsware/android/pr/ParcelReceiver.java",
44
+ "test/ParcelToPackage/AndroidManifest.xml",
45
+ "test/ParcelToPackage/build.properties",
46
+ "test/ParcelToPackage/build.xml",
47
+ "test/ParcelToPackage/default.properties",
48
+ "test/ParcelToPackage/docs/README",
49
+ "test/ParcelToPackage/docs/SomeOtherFile",
50
+ "test/ParcelToPackage/libs/one.jar",
51
+ "test/ParcelToPackage/libs/two.jar",
52
+ "test/ParcelToPackage/local.properties",
53
+ "test/ParcelToPackage/parcel.json",
54
+ "test/ParcelToPackage/res/layout/andParcel_test_row.xml",
55
+ "test/ParcelToPackage/res/values/strings.xml",
56
+ "test/ParcelToPackage/src/com/commonsware/android/p2pkg/ParcelToPackage.java",
57
+ "test/ParcelToPackage/tmp/andParcel-test_0.1.0.zip",
58
+ "test/test_init.rb",
59
+ "test/test_install.rb",
60
+ "test/test_package.rb",
61
+ "test/test_remove.rb"
62
+ ]
63
+ s.homepage = %q{http://github.com/commonsguy/andparcel}
64
+ s.rdoc_options = ["--charset=UTF-8"]
65
+ s.require_paths = ["lib"]
66
+ s.rubygems_version = %q{1.3.5}
67
+ s.summary = %q{Support for Android Parcel packaging system}
68
+ s.test_files = [
69
+ "test/test_remove.rb",
70
+ "test/test_package.rb",
71
+ "test/test_init.rb",
72
+ "test/test_install.rb"
73
+ ]
74
+
75
+ if s.respond_to? :specification_version then
76
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
77
+ s.specification_version = 3
78
+
79
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
80
+ s.add_development_dependency(%q<protest>, [">= 0"])
81
+ s.add_runtime_dependency(%q<rubyzip>, [">= 0.9.4"])
82
+ s.add_runtime_dependency(%q<json>, [">= 1.2.3"])
83
+ s.add_runtime_dependency(%q<nokogiri>, [">= 1.4.1"])
84
+ s.add_runtime_dependency(%q<rio>, [">= 0.4.2"])
85
+ s.add_runtime_dependency(%q<trollop>, [">= 1.15"])
86
+ else
87
+ s.add_dependency(%q<protest>, [">= 0"])
88
+ s.add_dependency(%q<rubyzip>, [">= 0.9.4"])
89
+ s.add_dependency(%q<json>, [">= 1.2.3"])
90
+ s.add_dependency(%q<nokogiri>, [">= 1.4.1"])
91
+ s.add_dependency(%q<rio>, [">= 0.4.2"])
92
+ s.add_dependency(%q<trollop>, [">= 1.15"])
93
+ end
94
+ else
95
+ s.add_dependency(%q<protest>, [">= 0"])
96
+ s.add_dependency(%q<rubyzip>, [">= 0.9.4"])
97
+ s.add_dependency(%q<json>, [">= 1.2.3"])
98
+ s.add_dependency(%q<nokogiri>, [">= 1.4.1"])
99
+ s.add_dependency(%q<rio>, [">= 0.4.2"])
100
+ s.add_dependency(%q<trollop>, [">= 1.15"])
101
+ end
102
+ end
103
+
data/bin/parcel ADDED
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # +parcel+ is the command-line interface to the Android parcel
4
+ # system -- a framework for creating reusable components
5
+ # for Android application development.
6
+ #
7
+ # Author:: Mark Murphy
8
+ # Copyright:: Copyright (c) 2010 CommonsWare, LLC
9
+ # License:: Apache Software License 2.0
10
+
11
+ require 'pathname'
12
+ require 'set'
13
+ require 'rubygems'
14
+ require 'trollop'
15
+ require 'andparcel'
16
+
17
+ module AndParcel
18
+ def self.commands
19
+ @commands||={}
20
+ end
21
+
22
+ class Command
23
+ def self.inherited(subclass)
24
+ if subclass.name.match(/AndParcel\:\:(.*)+Command/)
25
+ AndParcel.commands[$1.downcase]=subclass
26
+ end
27
+ end
28
+ end
29
+
30
+ class ListCommand < Command
31
+ def run
32
+ catalogs=AndParcel.catalogs
33
+ puts catalogs.names.sort.join("\n")
34
+ end
35
+ end
36
+
37
+ class PackageCommand < Command
38
+ def run
39
+ opts=Trollop::options do
40
+ banner "parcel package"
41
+ opt :project, "path to Android project (defaults to parcel JSON directory)", :short=>'p'
42
+ opt :dir, "directory for parcel output, relative to --project", :default=>'bin'
43
+ opt :jars, "paths to JARs to bundle (primary and libs)", :type=>:strings, :short=>'j', :required=>true
44
+ opt :docs, "files/directories of docs to package", :type=>:strings, :short=>'d'
45
+ opt :manifest, "manifest containing components to package (defaults to AndroidManifest.xml in project)", :type=>:string, :short=>'m'
46
+ # opt :dependencies, "names of parcels this parcel depends on", :type=>:strings
47
+ opt :res, "files/directories of resources to package (defaults to res/ in project)", :type=>:strings, :short=>'r'
48
+ end
49
+
50
+ pkg_info=ARGV.shift || "package.json"
51
+
52
+ Trollop::die "cannot find #{pkg_info}" if !File.exists?(pkg_info)
53
+
54
+ if !opts[:project]
55
+ opts[:project]=File.dirname(pkg_info)
56
+ pkg_info=File.basename(pkg_info)
57
+ end
58
+
59
+ if !opts[:res]
60
+ opts[:res]=['res']
61
+ end
62
+
63
+ if !opts[:manifest]
64
+ opts[:manifest]='AndroidManifest.xml'
65
+ end
66
+
67
+ AndParcel::Parcel.package(pkg_info, opts)
68
+ end
69
+ end
70
+
71
+ class InstallCommand < Command
72
+ def run
73
+ opts=Trollop::options do
74
+ banner "parcel install"
75
+ opt :project, "path to Android project", :type=>:string, :short=>'p', :default=>'.'
76
+ opt :replace, "if set and parcel is installed already, remove first", :default=>false
77
+ end
78
+
79
+ Trollop::die "parcel not provided" if ARGV.size==0
80
+
81
+ parcel=ARGV.shift
82
+
83
+ AndParcel::Parcel.install(parcel, opts)
84
+ end
85
+ end
86
+
87
+ class RemoveCommand < Command
88
+ def run
89
+ opts=Trollop::options do
90
+ banner "parcel remove"
91
+ opt :project, "path to Android project", :type=>:string, :short=>'p', :default=>'.'
92
+ end
93
+
94
+ Trollop::die "parcel name not provided" if ARGV.size==0
95
+
96
+ name=ARGV.shift
97
+
98
+ AndParcel::Parcel.remove(name, opts)
99
+ end
100
+ end
101
+
102
+ class CatalogCommand < Command
103
+ def run
104
+ Trollop::die "add/remove not provided" if ARGV.size==0
105
+
106
+ op=ARGV.shift.downcase
107
+
108
+ Trollop::die "invalid operation: #{op}" if !["add", "remove"].include?(op)
109
+ Trollop::die "catalog nickname not provided" if ARGV.size==0
110
+
111
+ nick=ARGV.shift
112
+
113
+ if (op=='add')
114
+ Trollop::die "catalog URL not provided" if ARGV.size==0
115
+
116
+ AndParcel.catalogs.add(nick, ARGV.shift)
117
+ else
118
+ AndParcel.catalogs.remove(nick)
119
+ end
120
+ end
121
+ end
122
+
123
+ class LintCommand < Command
124
+ def run
125
+ opts=Trollop::options do
126
+ banner "parcel lint"
127
+ opt :project, "path to Android project (defaults to parcel.json directory)", :short=>'p'
128
+ opt :repair, "tells parcel to repair problems", :short=>'r', :default=>false
129
+ opt :quiet, "whether it should print output on success", :short=>'q', :default=>false
130
+ end
131
+
132
+ Trollop::die "parcel not provided" if ARGV.size==0
133
+
134
+ pkg_info=ARGV.shift
135
+
136
+ Trollop::die "cannot find #{pkg_info}" if !File.exists?(pkg_info)
137
+
138
+ if !opts[:project]
139
+ opts[:project]=File.dirname(pkg_info)
140
+ pkg_info=File.basename(pkg_info)
141
+ end
142
+
143
+ AndParcel::Parcel.lint(pkg_info, opts)
144
+ end
145
+ end
146
+ end
147
+
148
+ if ARGV.size>0
149
+ name=ARGV.shift
150
+ cls=AndParcel.commands[name]
151
+
152
+ if cls
153
+ cmd=cls.new.run
154
+ else
155
+ $stderr.puts "Could not find subcommand #{name}"
156
+ exit(-1)
157
+ end
158
+ else
159
+ $stderr.puts "Usage: parcel [#{AndParcel.commands.keys.sort.join(',')}] [opts]"
160
+ exit(-1)
161
+ end
@@ -0,0 +1,22 @@
1
+ require "fileutils"
2
+
3
+ module AndParcel
4
+ def self.version
5
+ "0.1"
6
+ end
7
+
8
+ def self.home
9
+ File.join(Dir.chdir {Dir.pwd}, '.andparcel')
10
+ end
11
+
12
+ def self.init
13
+ FileUtils.mkdir_p home
14
+ CatalogSet.new(home).add('andparcel.com', 'http://pub.andparcel.com/andparcel.json')
15
+ end
16
+
17
+ def self.catalogs
18
+ init
19
+
20
+ CatalogSet.new(home)
21
+ end
22
+ end
@@ -0,0 +1,75 @@
1
+ require "fileutils"
2
+ require 'uri'
3
+ require "open-uri"
4
+ require "rubygems"
5
+ require "rio"
6
+
7
+ module AndParcel
8
+ class Catalog
9
+ attr_reader :nick, :path
10
+
11
+ def initialize(path)
12
+ @path=path
13
+ @nick=File.basename(path, '.json')
14
+ end
15
+ end
16
+
17
+ class CatalogSet
18
+ def initialize(root)
19
+ @root=root
20
+ end
21
+
22
+ def size
23
+ roster.size
24
+ end
25
+
26
+ def roster_file
27
+ File.join(@root, 'catalogs.json')
28
+ end
29
+
30
+ def roster
31
+ fn=roster_file
32
+
33
+ if File.exists?(fn)
34
+ return(JSON.parse(open(fn) {|f| f.read}))
35
+ end
36
+
37
+ {}
38
+ end
39
+
40
+ def add(name, url)
41
+ roster_hash=roster
42
+
43
+ roster_hash[name]={'url'=>url}
44
+
45
+ open(roster_file, "w") {|f| f.puts(roster_hash.to_json)}
46
+ end
47
+
48
+ def remove(name)
49
+ roster_hash=roster
50
+
51
+ roster_hash.delete(name)
52
+
53
+ open(roster_file, "w") {|f| f.puts(roster_hash.to_json)}
54
+ end
55
+
56
+ def names
57
+ roster.keys
58
+ end
59
+
60
+ def find(name)
61
+ roster.each_value do |cat|
62
+ packages=JSON.parse(open(cat['url']) {|f| f.read})
63
+ package=packages['parcels'][name]
64
+
65
+ if package
66
+ uri=URI.parse cat['url']
67
+
68
+ return(uri+package['path'])
69
+ end
70
+ end
71
+
72
+ nil
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,21 @@
1
+ module AndParcel
2
+ class FileRef
3
+ attr_reader :local, :relative, :dir
4
+
5
+ def self.[](base)
6
+ files=[]
7
+
8
+ # files += Dir[File.join(base, '*')].collect {|x| FileRef.new(x, base)}
9
+ files += Dir[File.join(base, '**', '*')].collect {|x| FileRef.new(x, base)}
10
+
11
+ files
12
+ end
13
+
14
+ def initialize(name, dir=nil)
15
+ @local=name
16
+ @dir=dir
17
+ @relative=@local[dir.size, 10000] if @local[0, dir.size]==dir
18
+ @relative=@local if !@relative
19
+ end
20
+ end
21
+ end