linguistics 1.0.8

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/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2003-2008, Michael Granger
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ * Neither the name of the author/s, nor the names of the project's
15
+ contributors may be used to endorse or promote products derived from this
16
+ software without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README ADDED
@@ -0,0 +1,166 @@
1
+
2
+ = Linguistics
3
+
4
+ == Authors
5
+
6
+ * Michael Granger <ged@FaerieMUD.org>
7
+ * Martin Chase <stillflame@FaerieMUD.org>
8
+
9
+
10
+ == Requirements
11
+
12
+ * Ruby >= 1.8.6
13
+
14
+
15
+ == Optional
16
+
17
+ * Ruby-WordNet (>= 0.0.5) - adds integration for the Ruby binding for the
18
+ WordNet� lexical refrence system.
19
+
20
+ URL: http://deveiate.org/projects/Ruby-WordNet
21
+
22
+ * LinkParser (>= 1.0.5)
23
+
24
+ URL: http://deveiate.org/projects/Ruby-LinkParser
25
+
26
+
27
+ == General Information
28
+
29
+ Linguistics is a framework for building linguistic utilities for Ruby objects
30
+ in any language. It includes a generic language-independant front end, a
31
+ module for mapping language codes into language names, and a module which
32
+ contains various English-language utilities.
33
+
34
+
35
+ === Method Interface
36
+
37
+ The Linguistics module comes with a language-independant mechanism for
38
+ extending core Ruby classes with linguistic methods.
39
+
40
+ It consists of three parts: a core linguistics module which contains the
41
+ class-extension framework for languages, a generic inflector class that serves
42
+ as a delegator for linguistic methods on Ruby objects, and one or more
43
+ language-specific modules which contain the actual linguistic functions.
44
+
45
+ The module works by adding a single instance method for each language named
46
+ after the language's two-letter code (or three-letter code, if no two-letter
47
+ code is defined by ISO639) to various Ruby classes. This allows many
48
+ language-specific methods to be added to objects without cluttering up the
49
+ interface or risking collision between them, albeit at the cost of three or four
50
+ more characters per method invocation.
51
+
52
+ If you don't like extending core Ruby classes, the language modules should
53
+ also allow you to use them as a function library as well.
54
+
55
+ For example, the English-language module contains a #plural function which can
56
+ be accessed via a method on a core class:
57
+
58
+ Linguistics::use( :en )
59
+ "goose".en.plural
60
+ # => "geese"
61
+
62
+ or via the Linguistics::EN::plural function directly:
63
+
64
+ include Linguistics::EN
65
+ plural( "goose" )
66
+ # => "geese"
67
+
68
+ The class-extension mechanism actually uses the functional interface behind
69
+ the scenes.
70
+
71
+ A new feature with the 0.02 release: You can now omit the language-code method
72
+ for unambiguous methods by calling Linguistics::use with the +:installProxy+
73
+ configuration key, with the language code of the language module whose methods
74
+ you wish to be available. For example, instead of having to call:
75
+
76
+ "goose".en.plural
77
+
78
+ from the example above, you can now do this:
79
+
80
+ Lingusitics::use( :en, :installProxy => :en )
81
+ "goose".plural
82
+ # => "geese"
83
+
84
+ More about how this works in the documentation for Linguistics::use.
85
+
86
+
87
+ ==== Adding Language Modules
88
+
89
+ To add a new language to the framework, create a file named the same as the
90
+ ISO639 2- or 3-letter language code for the language you're adding. It must be
91
+ placed under lib/linguistics/ to be recognized by the linguistics module, but
92
+ you can also just require it yourself prior to calling Linguistics::use().
93
+ This file should define a module under Linguistics that is an all-caps version
94
+ of the code used in the filename. Any methods you wish to be exposed to users
95
+ should be declared as module functions (ie., using Module#module_function).
96
+
97
+ You may also wish to add your module to the list of default languages by
98
+ adding the appropriate symbol to the Linguistics::DefaultLanguages array.
99
+
100
+ For example, to create a Portuguese-language module, create a file called
101
+ 'lib/linguistics/pt.rb' which contains the following:
102
+
103
+ module Linguistics
104
+ module PT
105
+ Linguistics::DefaultLanguages << :pt
106
+
107
+ module_function
108
+ <language methods here>
109
+ end
110
+ end
111
+
112
+ See the English language module (lib/linguistics/en.rb) for an example.
113
+
114
+
115
+ === English Language Module
116
+
117
+ See the README.english file for a synopsis.
118
+
119
+ The English-language module currently contains linguistic functions ported
120
+ from a few excellent Perl modules:
121
+
122
+ Lingua::EN::Inflect
123
+ Lingua::Conjunction
124
+ Lingua::EN::Infinitive
125
+
126
+ See the lib/linguistics/en.rb file for specific attributions.
127
+
128
+ New with version 0.02: integration with the Ruby WordNet� and LinkParser
129
+ modules (which must be installed separately).
130
+
131
+
132
+ == To Do
133
+
134
+ * I am planning on improving the results from the infinitive functions, which
135
+ currently return useful results only part of the time. Investigations into
136
+ additional stemming functions and some other strategies are ongoing.
137
+
138
+ * Martin Chase <stillflame at FaerieMUD dot org> is working on an integration
139
+ module for his excellent work on a Ruby interface to the CMU Link Grammar
140
+ (an english-sentence parser). This will make writing fairly accurate natural
141
+ language parsers in Ruby much easier.
142
+
143
+ * Suggestions (and patches) for any of these items or additional features are
144
+ welcomed.
145
+
146
+
147
+
148
+ == Legal
149
+
150
+ This module is Open Source Software which is Copyright (c) 2003 by The
151
+ FaerieMUD Consortium. All rights reserved.
152
+
153
+ You may use, modify, and/or redistribute this software under the terms of the
154
+ Perl Artistic License, a copy of which should have been included in this
155
+ distribution (See the file Artistic). If it was not, a copy of it may be
156
+ obtained from http://language.perl.com/misc/Artistic.html or
157
+ http://www.faeriemud.org/artistic.html).
158
+
159
+ THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
160
+ WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
161
+ MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
162
+
163
+
164
+ $Id$
165
+
166
+
data/README.english ADDED
@@ -0,0 +1,245 @@
1
+
2
+ = English Ruby Linguistics Module - Synopsis
3
+
4
+ This is an overview of the functionality currently in the English functions of
5
+ the Ruby Linguistics module as of version 0.02:
6
+
7
+
8
+ == Pluralization
9
+
10
+ require 'linguistics'
11
+ Linguistics::use( :en ) # extends Array, String, and Numeric
12
+
13
+ "box".en.plural
14
+ # => "boxes"
15
+
16
+ "mouse".en.plural
17
+ # => "mice"
18
+
19
+ "ruby".en.plural
20
+ # => "rubies"
21
+
22
+
23
+ == Indefinite Articles
24
+
25
+ "book".en.a
26
+ # => "a book"
27
+
28
+ "article".en.a
29
+ # => "an article"
30
+
31
+
32
+ == Present Participles
33
+
34
+ "runs".en.present_participle
35
+ # => "running"
36
+
37
+ "eats".en.present_participle
38
+ # => "eating"
39
+
40
+ "spies".en.present_participle
41
+ # => "spying"
42
+
43
+
44
+ == Ordinal Numbers
45
+
46
+ 5.en.ordinal
47
+ # => "5th"
48
+
49
+ 2004.en.ordinal
50
+ # => "2004th"
51
+
52
+
53
+ == Numbers to Words
54
+
55
+ 5.en.numwords
56
+ # => "five"
57
+
58
+ 2004.en.numwords
59
+ # => "two thousand and four"
60
+
61
+ 2385762345876.en.numwords
62
+ # => "two trillion, three hundred and eighty-five billion,
63
+ seven hundred and sixty-two million, three hundred and
64
+ forty-five thousand, eight hundred and seventy-six"
65
+
66
+
67
+ == Quantification
68
+
69
+ "cow".en.quantify( 5 )
70
+ # => "several cows"
71
+
72
+ "cow".en.quantify( 1005 )
73
+ # => "thousands of cows"
74
+
75
+ "cow".en.quantify( 20_432_123_000_000 )
76
+ # => "tens of trillions of cows"
77
+
78
+
79
+ == Conjunctions
80
+
81
+ animals = %w{dog cow ox chicken goose goat cow dog rooster llama
82
+ pig goat dog cat cat dog cow goat goose goose ox alpaca}
83
+ puts "The farm has: " + animals.en.conjunction
84
+
85
+ # => The farm has: four dogs, three cows, three geese, three goats,
86
+ two oxen, two cats, a chicken, a rooster, a llama, a pig,
87
+ and an alpaca
88
+
89
+ Note that 'goose' and 'ox' are both correctly pluralized, and the correct
90
+ indefinite article 'an' has been used for 'alpaca'.
91
+
92
+ You can also use the generalization function of the #quantify method to give
93
+ general descriptions of object lists instead of literal counts:
94
+
95
+ allobjs = []
96
+ ObjectSpace::each_object {|obj| allobjs << obj.class.name}
97
+
98
+ puts "The current Ruby objectspace contains: " +
99
+ allobjs.en.conjunction( :generalize => true )
100
+
101
+ which will print something like:
102
+
103
+ The current Ruby objectspace contains: thousands of Strings,
104
+ thousands of Arrays, hundreds of Hashes, hundreds of
105
+ Classes, many Regexps, a number of Ranges, a number of
106
+ Modules, several Floats, several Procs, several MatchDatas,
107
+ several Objects, several IOS, several Files, a Binding, a
108
+ NoMemoryError, a SystemStackError, a fatal, a ThreadGroup,
109
+ and a Thread
110
+
111
+
112
+ == Infinitives
113
+
114
+ New in version 0.02:
115
+
116
+ "leaving".en.infinitive
117
+ # => "leave"
118
+
119
+ "left".en.infinitive
120
+ # => "leave"
121
+
122
+ "leaving".en.infinitive.suffix
123
+ # => "ing"
124
+
125
+
126
+ == WordNet� Integration
127
+
128
+ Also new in version 0.02, if you have the Ruby-WordNet module installed, you can
129
+ look up WordNet synsets using the Linguistics interface:
130
+
131
+ # Test to be sure the WordNet module loaded okay.
132
+ Linguistics::EN.has_wordnet?
133
+ # => true
134
+
135
+ # Fetch the default synset for the word "balance"
136
+ "balance".synset
137
+ # => #<WordNet::Synset:0x40376844 balance (noun): "a state of equilibrium"
138
+ (derivations: 3, antonyms: 1, hypernyms: 1, hyponyms: 3)>
139
+
140
+ # Fetch the synset for the first verb sense of "balance"
141
+ "balance".en.synset( :verb )
142
+ # => #<WordNet::Synset:0x4033f448 balance, equilibrate, equilibrize, equilibrise
143
+ (verb): "bring into balance or equilibrium; "She has to balance work and her
144
+ domestic duties"; "balance the two weights"" (derivations: 7, antonyms: 1,
145
+ verbGroups: 2, hypernyms: 1, hyponyms: 5)>
146
+
147
+ # Fetch the second noun sense
148
+ "balance".en.synset( 2, :noun )
149
+ # => #<WordNet::Synset:0x404ebb24 balance (noun): "a scale for weighing; depends
150
+ on pull of gravity" (hypernyms: 1, hyponyms: 5)>
151
+
152
+ # Fetch the second noun sense's hypernyms (more-general words, like a superclass)
153
+ "balance".en.synset( 2, :noun ).hypernyms
154
+ # => [#<WordNet::Synset:0x404e5620 scale, weighing machine (noun): "a measuring
155
+ instrument for weighing; shows amount of mass" (derivations: 2, hypernyms: 1,
156
+ hyponyms: 2)>]
157
+
158
+ # A simpler way of doing the same thing:
159
+ "balance".en.hypernyms( 2, :noun )
160
+ # => [#<WordNet::Synset:0x404e5620 scale, weighing machine (noun): "a measuring
161
+ instrument for weighing; shows amount of mass" (derivations: 2, hypernyms: 1,
162
+ hyponyms: 2)>]
163
+
164
+ # Fetch the first hypernym's hypernyms
165
+ "balance".en.synset( 2, :noun ).hypernyms.first.hypernyms
166
+ # => [#<WordNet::Synset:0x404c60b8 measuring instrument, measuring system,
167
+ measuring device (noun): "instrument that shows the extent or amount or quantity
168
+ or degree of something" (hypernyms: 1, hyponyms: 83)>]
169
+
170
+ # Find the synset to which both the second noun sense of "balance" and the
171
+ # default sense of "shovel" belong.
172
+ ("balance".en.synset( 2, :noun ) | "shovel".en.synset)
173
+ # => #<WordNet::Synset:0x40473da4 instrumentality, instrumentation (noun): "an
174
+ artifact (or system of artifacts) that is instrumental in accomplishing some
175
+ end" (derivations: 1, hypernyms: 1, hyponyms: 13)>
176
+
177
+ # Fetch just the words for the other kinds of "instruments"
178
+ "instrument".en.hyponyms.collect {|synset| synset.words}.flatten
179
+ # => ["analyzer", "analyser", "cautery", "cauterant", "drafting instrument",
180
+ "extractor", "instrument of execution", "instrument of punishment", "measuring
181
+ instrument", "measuring system", "measuring device", "medical instrument",
182
+ "navigational instrument", "optical instrument", "plotter", "scientific
183
+ instrument", "sonograph", "surveying instrument", "surveyor's instrument",
184
+ "tracer", "weapon", "arm", "weapon system", "whip"]
185
+
186
+ There are many more WordNet methods supported � too many to list here. See the
187
+ documentation for the complete list.
188
+
189
+
190
+ == LinkParser Integration
191
+
192
+ Another new feature in version 0.02 is integration with the Ruby version of the
193
+ CMU Link Grammar Parser by Martin Chase. If you have the LinkParser module
194
+ installed, you can create linkages from English sentences that let you query for
195
+ parts of speech:
196
+
197
+ # Test to see whether or not the link parser is loaded.
198
+ Linguistics::EN.has_link_parser?
199
+ # => true
200
+
201
+ # Diagram the first linkage for a test sentence
202
+ puts "he is a big dog".sentence.linkages.first.to_s
203
+ +---O*---+
204
+ | +--Ds--+
205
+ +Ss+ | +-A-+
206
+ | | | | |
207
+ he is a big dog
208
+
209
+ # Find the verb in the sentence
210
+ "he is a big dog".en.sentence.verb.to_s
211
+ # => "is"
212
+
213
+ # Combined infinitive + LinkParser: Find the infinitive form of the verb of the
214
+ given sentence.
215
+ "he is a big dog".en.sentence.verb.infinitive
216
+ # => "be"
217
+
218
+ # Find the direct object of the sentence
219
+ "he is a big dog".en.sentence.object.to_s
220
+ # => "dog"
221
+
222
+ # Look at the raw LinkParser::Word for the direct object of the sentence.
223
+ "he is a big dog".en.sentence.object
224
+ # => #<LinkParser::Word:0x403da0a0 @definition=[[{@A-}, Ds-, {@M+}, J-], [{@A-},
225
+ Ds-, {@M+}, Os-], [{@A-}, Ds-, {@M+}, Ss+, {@CO-}, {C-}], [{@A-}, Ds-, {@M+},
226
+ Ss+, R-], [{@A-}, Ds-, {@M+}, SIs-], [{@A-}, Ds-, {R+}, {Bs+}, J-], [{@A-}, Ds-,
227
+ {R+}, {Bs+}, Os-], [{@A-}, Ds-, {R+}, {Bs+}, Ss+, {@CO-}, {C-}], [{@A-}, Ds-,
228
+ {R+}, {Bs+}, Ss+, R-], [{@A-}, Ds-, {R+}, {Bs+}, SIs-]], @right=[], @suffix="",
229
+ @left=[#<LinkParser::Connection:0x403da028 @rword=#<LinkParser::Word:0x403da0a0
230
+ ...>, @lword=#<LinkParser::Word:0x403da0b4 @definition=[[Ss-, O+, {@MV+}], [Ss-,
231
+ B-, {@MV+}], [Ss-, P+], [Ss-, AF-], [RS-, Bs-, O+, {@MV+}], [RS-, Bs-, B-,
232
+ {@MV+}], [RS-, Bs-, P+], [RS-, Bs-, AF-], [{Q-}, SIs+, O+, {@MV+}], [{Q-}, SIs+,
233
+ B-, {@MV+}], [{Q-}, SIs+, P+], [{Q-}, SIs+, AF-]],
234
+ @right=[#<LinkParser::Connection:0x403da028 ...>], @suffix="", @left=[],
235
+ @name="is", @position=1>, @subName="*", @name="O", @length=3>], @name="dog",
236
+ @position=4>
237
+
238
+ # Combine WordNet + LinkParser to find the definition of the direct object of
239
+ # the sentence
240
+ "he is a big dog".en.sentence.object.gloss
241
+ # => "a member of the genus Canis (probably descended from the common wolf) that
242
+ has been domesticated by man since prehistoric times; occurs in many breeds;
243
+ \"the dog barked all night\""
244
+
245
+
data/Rakefile ADDED
@@ -0,0 +1,338 @@
1
+ #!rake
2
+ #
3
+ # Linguistics rakefile
4
+ #
5
+ # Based on various other Rakefiles, especially one by Ben Bleything
6
+ #
7
+ # Copyright (c) 2007-2009 The FaerieMUD Consortium
8
+ #
9
+ # Authors:
10
+ # * Michael Granger <ged@FaerieMUD.org>
11
+ #
12
+
13
+ BEGIN {
14
+ require 'pathname'
15
+ basedir = Pathname.new( __FILE__ ).dirname
16
+
17
+ libdir = basedir + "lib"
18
+ extdir = basedir + "ext"
19
+
20
+ $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
21
+ $LOAD_PATH.unshift( extdir.to_s ) unless $LOAD_PATH.include?( extdir.to_s )
22
+ }
23
+
24
+ begin
25
+ require 'readline'
26
+ include Readline
27
+ rescue LoadError
28
+ # Fall back to a plain prompt
29
+ def readline( text )
30
+ $stderr.print( text.chomp )
31
+ return $stdin.gets
32
+ end
33
+ end
34
+
35
+ require 'rbconfig'
36
+ require 'rake'
37
+ require 'rake/testtask'
38
+ require 'rake/packagetask'
39
+ require 'rake/clean'
40
+ # require 'rake/191_compat.rb'
41
+
42
+ $dryrun = false
43
+
44
+ ### Config constants
45
+ BASEDIR = Pathname.new( __FILE__ ).dirname.relative_path_from( Pathname.getwd )
46
+ BINDIR = BASEDIR + 'bin'
47
+ LIBDIR = BASEDIR + 'lib'
48
+ EXTDIR = BASEDIR + 'ext'
49
+ DOCSDIR = BASEDIR + 'docs'
50
+ PKGDIR = BASEDIR + 'pkg'
51
+ DATADIR = BASEDIR + 'data'
52
+
53
+ MANUALDIR = DOCSDIR + 'manual'
54
+
55
+ PROJECT_NAME = 'Linguistics'
56
+ PKG_NAME = PROJECT_NAME.downcase
57
+ PKG_SUMMARY = 'a framework for building linguistic utilities for Ruby objects'
58
+
59
+ # Cruisecontrol stuff
60
+ CC_BUILD_LABEL = ENV['CC_BUILD_LABEL']
61
+ CC_BUILD_ARTIFACTS = ENV['CC_BUILD_ARTIFACTS'] || 'artifacts'
62
+
63
+ VERSION_FILE = LIBDIR + 'linguistics.rb'
64
+ if VERSION_FILE.exist? && buildrev = ENV['CC_BUILD_LABEL']
65
+ PKG_VERSION = VERSION_FILE.read[ /VERSION\s*=\s*['"](\d+\.\d+\.\d+)['"]/, 1 ] + '.' + buildrev
66
+ elsif VERSION_FILE.exist?
67
+ PKG_VERSION = VERSION_FILE.read[ /VERSION\s*=\s*['"](\d+\.\d+\.\d+)['"]/, 1 ]
68
+ else
69
+ PKG_VERSION = '0.0.0'
70
+ end
71
+
72
+ PKG_FILE_NAME = "#{PKG_NAME.downcase}-#{PKG_VERSION}"
73
+ GEM_FILE_NAME = "#{PKG_FILE_NAME}.gem"
74
+
75
+ # Universal VCS constants
76
+ DEFAULT_EDITOR = 'vi'
77
+ COMMIT_MSG_FILE = 'commit-msg.txt'
78
+ FILE_INDENT = " " * 12
79
+ LOG_INDENT = " " * 3
80
+
81
+ EXTCONF = EXTDIR + 'extconf.rb'
82
+
83
+ ARTIFACTS_DIR = Pathname.new( CC_BUILD_ARTIFACTS )
84
+
85
+ TEXT_FILES = Rake::FileList.new( %w[Rakefile ChangeLog README LICENSE] )
86
+ BIN_FILES = Rake::FileList.new( "#{BINDIR}/*" )
87
+ LIB_FILES = Rake::FileList.new( "#{LIBDIR}/**/*.rb" )
88
+ EXT_FILES = Rake::FileList.new( "#{EXTDIR}/**/*.{c,h,rb}" )
89
+ DATA_FILES = Rake::FileList.new( "#{DATADIR}/**/*" )
90
+
91
+ SPECDIR = BASEDIR + 'spec'
92
+ SPECLIBDIR = SPECDIR + 'lib'
93
+ SPEC_FILES = Rake::FileList.new( "#{SPECDIR}/**/*_spec.rb", "#{SPECLIBDIR}/**/*.rb" )
94
+
95
+ TESTDIR = BASEDIR + 'tests'
96
+ TEST_FILES = Rake::FileList.new( "#{TESTDIR}/**/*.tests.rb" )
97
+
98
+ RAKE_TASKDIR = BASEDIR + 'rake'
99
+ RAKE_TASKLIBS = Rake::FileList.new( "#{RAKE_TASKDIR}/*.rb" )
100
+ PKG_TASKLIBS = Rake::FileList.new( "#{RAKE_TASKDIR}/{191_compat,helpers,packaging,rdoc,testing}.rb" )
101
+ PKG_TASKLIBS.include( "#{RAKE_TASKDIR}/manual.rb" ) if MANUALDIR.exist?
102
+
103
+ RAKE_TASKLIBS_URL = 'http://repo.deveiate.org/rake-tasklibs'
104
+
105
+ LOCAL_RAKEFILE = BASEDIR + 'Rakefile.local'
106
+
107
+ EXTRA_PKGFILES = Rake::FileList.new
108
+ EXTRA_PKGFILES.include( "#{BASEDIR}/examples/*.rb" )
109
+ EXTRA_PKGFILES.include( "#{BASEDIR}/README.english" )
110
+
111
+ RELEASE_FILES = TEXT_FILES +
112
+ SPEC_FILES +
113
+ TEST_FILES +
114
+ BIN_FILES +
115
+ LIB_FILES +
116
+ EXT_FILES +
117
+ DATA_FILES +
118
+ RAKE_TASKLIBS +
119
+ EXTRA_PKGFILES
120
+
121
+
122
+ RELEASE_FILES << LOCAL_RAKEFILE.to_s if LOCAL_RAKEFILE.exist?
123
+
124
+ COVERAGE_MINIMUM = ENV['COVERAGE_MINIMUM'] ? Float( ENV['COVERAGE_MINIMUM'] ) : 85.0
125
+ RCOV_EXCLUDES = 'spec,tests,/Library/Ruby,/var/lib,/usr/local/lib'
126
+ RCOV_OPTS = [
127
+ '--exclude', RCOV_EXCLUDES,
128
+ '--xrefs',
129
+ '--save',
130
+ '--callsites',
131
+ #'--aggregate', 'coverage.data' # <- doesn't work as of 0.8.1.2.0
132
+ ]
133
+
134
+
135
+ ### Load some task libraries that need to be loaded early
136
+ if !RAKE_TASKDIR.exist?
137
+ $stderr.puts "It seems you don't have the build task directory. Shall I fetch it "
138
+ ans = readline( "for you? [y]" )
139
+ ans = 'y' if !ans.nil? && ans.empty?
140
+
141
+ if ans =~ /^y/i
142
+ $stderr.puts "Okay, fetching #{RAKE_TASKLIBS_URL} into #{RAKE_TASKDIR}..."
143
+ system 'hg', 'clone', RAKE_TASKLIBS_URL, RAKE_TASKDIR
144
+ if ! $?.success?
145
+ fail "Damn. That didn't work. Giving up; maybe try manually fetching?"
146
+ end
147
+ else
148
+ $stderr.puts "Then I'm afraid I can't continue. Best of luck."
149
+ fail "Rake tasklibs not present."
150
+ end
151
+
152
+ RAKE_TASKLIBS.include( "#{RAKE_TASKDIR}/*.rb" )
153
+ end
154
+
155
+ require RAKE_TASKDIR + 'helpers.rb'
156
+
157
+ # Define some constants that depend on the 'svn' tasklib
158
+ if hg = which( 'hg' )
159
+ id = IO.read('|-') or exec hg.to_s, 'id', '-n'
160
+ PKG_BUILD = id.chomp[ /^[[:xdigit:]]+/ ]
161
+ else
162
+ PKG_BUILD = 0
163
+ end
164
+ SNAPSHOT_PKG_NAME = "#{PKG_FILE_NAME}.#{PKG_BUILD}"
165
+ SNAPSHOT_GEM_NAME = "#{SNAPSHOT_PKG_NAME}.gem"
166
+
167
+ # Documentation constants
168
+ RDOCDIR = DOCSDIR + 'api'
169
+ RDOC_OPTIONS = [
170
+ '-w', '4',
171
+ '-HN',
172
+ '-i', '.',
173
+ '-m', 'README',
174
+ '-t', PKG_NAME,
175
+ '-W', 'http://deveiate.org/projects/Linguistics/browser/'
176
+ ]
177
+
178
+ # Release constants
179
+ SMTP_HOST = 'mail.faeriemud.org'
180
+ SMTP_PORT = 465 # SMTP + SSL
181
+
182
+ # Project constants
183
+ PROJECT_HOST = 'deveiate'
184
+ PROJECT_PUBDIR = '/usr/local/www/public/code'
185
+ PROJECT_DOCDIR = "#{PROJECT_PUBDIR}/#{PKG_NAME}"
186
+ PROJECT_SCPPUBURL = "#{PROJECT_HOST}:#{PROJECT_PUBDIR}"
187
+ PROJECT_SCPDOCURL = "#{PROJECT_HOST}:#{PROJECT_DOCDIR}"
188
+
189
+ # Rubyforge stuff
190
+ RUBYFORGE_GROUP = 'deveiate'
191
+ RUBYFORGE_PROJECT = 'linguistics'
192
+
193
+ # Gem dependencies: gemname => version
194
+ DEPENDENCIES = {
195
+ }
196
+
197
+ # Developer Gem dependencies: gemname => version
198
+ DEVELOPMENT_DEPENDENCIES = {
199
+ 'rake' => '>= 0.8.7',
200
+ 'rcodetools' => '>= 0.7.0.0',
201
+ 'rcov' => '>= 0.8.1.2.0',
202
+ 'rdoc' => '>= 2.4.3',
203
+ 'RedCloth' => '>= 4.0.3',
204
+ 'rspec' => '>= 1.2.6',
205
+ 'rubyforge' => '>= 0',
206
+ 'termios' => '>= 0',
207
+ 'text-format' => '>= 1.0.0',
208
+ 'tmail' => '>= 1.2.3.1',
209
+ 'diff-lcs' => '>= 1.1.2',
210
+ 'wordnet' => '>=0.0.5',
211
+ 'linkparser' => '>=1.0.3',
212
+ }
213
+
214
+ # Non-gem requirements: packagename => version
215
+ REQUIREMENTS = {
216
+ }
217
+
218
+ # RubyGem specification
219
+ GEMSPEC = Gem::Specification.new do |gem|
220
+ gem.name = PKG_NAME.downcase
221
+ gem.version = PKG_VERSION
222
+
223
+ gem.summary = PKG_SUMMARY
224
+ gem.description = [
225
+ "in any language. It includes a generic language-independant front end, a",
226
+ "module for mapping language codes into language names, and a module which",
227
+ "contains various English-language utilities.",
228
+ ].join( "\n" )
229
+
230
+ gem.authors = "Michael Granger"
231
+ gem.email = ["ged@FaerieMUD.org"]
232
+ gem.homepage = 'http://deveiate.org/projects/Linguistics/'
233
+
234
+ # Apparently this isn't actually the 'project'?
235
+ gem.rubyforge_project = RUBYFORGE_GROUP
236
+
237
+ gem.has_rdoc = true
238
+ gem.rdoc_options = RDOC_OPTIONS
239
+ gem.extra_rdoc_files = %w[ChangeLog README LICENSE]
240
+
241
+ gem.bindir = BINDIR.relative_path_from(BASEDIR).to_s
242
+ gem.executables = BIN_FILES.select {|pn| File.executable?(pn) }.
243
+ collect {|pn| File.basename(pn) }
244
+ gem.require_paths << EXTDIR.relative_path_from( BASEDIR ).to_s if EXTDIR.exist?
245
+
246
+ if EXTCONF.exist?
247
+ gem.extensions << EXTCONF.relative_path_from( BASEDIR ).to_s
248
+ end
249
+
250
+ gem.files = RELEASE_FILES
251
+ gem.test_files = SPEC_FILES
252
+
253
+ DEPENDENCIES.each do |name, version|
254
+ version = '>= 0' if version.length.zero?
255
+ gem.add_runtime_dependency( name, version )
256
+ end
257
+
258
+ REQUIREMENTS.each do |name, version|
259
+ gem.requirements << [ name, version ].compact.join(' ')
260
+ end
261
+ end
262
+
263
+ $trace = Rake.application.options.trace ? true : false
264
+ $dryrun = Rake.application.options.dryrun ? true : false
265
+ $include_dev_dependencies = false
266
+
267
+ # Load any remaining task libraries
268
+ RAKE_TASKLIBS.each do |tasklib|
269
+ next if tasklib.to_s =~ %r{/helpers\.rb$}
270
+ begin
271
+ trace " loading tasklib %s" % [ tasklib ]
272
+ import tasklib
273
+ rescue ScriptError => err
274
+ fail "Task library '%s' failed to load: %s: %s" %
275
+ [ tasklib, err.class.name, err.message ]
276
+ trace "Backtrace: \n " + err.backtrace.join( "\n " )
277
+ rescue => err
278
+ log "Task library '%s' failed to load: %s: %s. Some tasks may not be available." %
279
+ [ tasklib, err.class.name, err.message ]
280
+ trace "Backtrace: \n " + err.backtrace.join( "\n " )
281
+ end
282
+ end
283
+
284
+ # Load any project-specific rules defined in 'Rakefile.local' if it exists
285
+ import LOCAL_RAKEFILE if LOCAL_RAKEFILE.exist?
286
+
287
+
288
+ #####################################################################
289
+ ### T A S K S
290
+ #####################################################################
291
+
292
+ ### Default task
293
+ task :default => [:clean, :local, :spec, :rdoc, :package]
294
+
295
+ ### Task the local Rakefile can append to -- no-op by default
296
+ task :local
297
+
298
+ ### Task: clean
299
+ CLEAN.include 'coverage'
300
+ CLOBBER.include 'artifacts', 'coverage.info', PKGDIR
301
+
302
+ ### Task: changelog
303
+ file 'ChangeLog' do |task|
304
+ log "Updating #{task.name}"
305
+
306
+ changelog = make_changelog()
307
+ File.open( task.name, 'w' ) do |fh|
308
+ fh.print( changelog )
309
+ end
310
+ end
311
+
312
+
313
+ ### Task: cruise (Cruisecontrol task)
314
+ desc "Cruisecontrol build"
315
+ task :cruise => [:clean, 'spec:quiet', :package] do |task|
316
+ raise "Artifacts dir not set." if ARTIFACTS_DIR.to_s.empty?
317
+ artifact_dir = ARTIFACTS_DIR.cleanpath + (CC_BUILD_LABEL || Time.now.strftime('%Y%m%d-%T'))
318
+ artifact_dir.mkpath
319
+
320
+ coverage = BASEDIR + 'coverage'
321
+ if coverage.exist? && coverage.directory?
322
+ $stderr.puts "Copying coverage stats..."
323
+ FileUtils.cp_r( 'coverage', artifact_dir )
324
+ end
325
+
326
+ $stderr.puts "Copying packages..."
327
+ FileUtils.cp_r( FileList['pkg/*'].to_a, artifact_dir )
328
+ end
329
+
330
+
331
+ desc "Update the build system to the latest version"
332
+ task :update_build do
333
+ log "Updating the build system"
334
+ run 'hg', '-R', RAKE_TASKDIR, 'pull', '-u'
335
+ log "Updating the Rakefile"
336
+ sh 'rake', '-f', RAKE_TASKDIR + 'Metarakefile'
337
+ end
338
+