dm-cutie 0.3.16
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +0 -0
- data/LICENSE +19 -0
- data/README.markdown +352 -0
- data/Rakefile +103 -0
- data/lib/dm-cutie.rb +29 -0
- data/lib/dm-cutie/cutie.rb +283 -0
- data/lib/dm-cutie/models/executed_query.rb +49 -0
- data/lib/dm-cutie/models/generalized_query.rb +108 -0
- data/lib/dm-cutie/models/query_storage_link.rb +15 -0
- data/lib/dm-cutie/models/repository_storage.rb +67 -0
- data/lib/dm-cutie/tracker/data_objects.rb +16 -0
- data/lib/dm-cutie/tracker/data_objects/helper.rb +85 -0
- data/lib/dm-cutie/tracker/data_objects/overrides.rb +161 -0
- data/lib/dm-cutie/tracker/hook/abstract.rb +57 -0
- data/lib/dm-cutie/version.rb +5 -0
- metadata +100 -0
data/History.txt
ADDED
File without changes
|
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (C) 2009, Cory ODaniel
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
4
|
+
copy of this software and associated documentation files (the "Software"),
|
5
|
+
to deal in the Software without restriction, including without limitation
|
6
|
+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
7
|
+
and/or sell copies of the Software, and to permit persons to whom the
|
8
|
+
Software is furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
16
|
+
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
18
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
19
|
+
DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,352 @@
|
|
1
|
+
Project Description
|
2
|
+
===================
|
3
|
+
dm-cutie - The 'cutie' stands for Query Tracking. She is super thorough and easy as hell, just the way you like it.
|
4
|
+
|
5
|
+
Tracks queries that are executed by DataMapper. Models can be optionally excluded from tracking. Cutie currently only supports DataObjects Adapters.
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
Quickstart- The whole caboodle.
|
10
|
+
===============================
|
11
|
+
There are two major pieces to the Cutie Project.
|
12
|
+
|
13
|
+
* dm-cutie - the query tracking portion - this gets installed 'in your app'
|
14
|
+
* dm-cutie-ui - A sinatra app that can connect to your dm-cutie repo and provide statisics.
|
15
|
+
|
16
|
+
Installing the query tracker (dm-cutie)
|
17
|
+
$ gem sources -a http://gemcutter.org # Add gem cutter to your gem sources
|
18
|
+
$ gem install dm-cutie
|
19
|
+
$ gem install dm-cutie-extras # This is a plugin pack for dm-cutie
|
20
|
+
$ gem install dm-cutie-ui # this is the front-end to dm-cutie
|
21
|
+
|
22
|
+
|
23
|
+
Adding it to your projects
|
24
|
+
# Somewhere after your DataMapper repositories are setup
|
25
|
+
require 'dm-cutie'
|
26
|
+
DataMapper::Cutie.enable_adapter :data_objects
|
27
|
+
|
28
|
+
# If you want some extras, sorry its Mysql centric, its what Im primarily familiar with
|
29
|
+
# require 'dm-cutie-extras'
|
30
|
+
#
|
31
|
+
# # Query Plan for Sqlite3
|
32
|
+
# DataMapper::Cutie::Extras.load :sqlite3_execution_step
|
33
|
+
#
|
34
|
+
# # Query Plan for Mysql
|
35
|
+
# DataMapper::Cutie::Extras.load :mysql_execution_step
|
36
|
+
#
|
37
|
+
# # Mysql Index information
|
38
|
+
# DataMapper::Cutie::Extras.load :mysql_index
|
39
|
+
#
|
40
|
+
# # Mysql warnings & errors
|
41
|
+
# DataMapper::Cutie::Extras.load :mysql_warning
|
42
|
+
#
|
43
|
+
|
44
|
+
DataMapper::Cutie.setup do |c|
|
45
|
+
# The name of the datamapper repository to store dm cutie tracked data in.
|
46
|
+
# If you are using something like mysql make sure that you created the schema
|
47
|
+
#
|
48
|
+
c[:repo_name] = :dm_cutie
|
49
|
+
|
50
|
+
# List of any models in YOUR application that you want dm-cutie to ignore
|
51
|
+
c[:exclude_models] = false #[:person, :car]
|
52
|
+
|
53
|
+
# List of models you want dm-cutie to specifically track
|
54
|
+
c[:only_models] = false #[:article, :address]
|
55
|
+
|
56
|
+
# What you consider a slow query
|
57
|
+
c[:slow_query_length] = 2
|
58
|
+
end
|
59
|
+
|
60
|
+
# passing true will tell dm-cutie to force a migration of all of HER models.
|
61
|
+
# she will always do a migration if she can't find her tables. In a development
|
62
|
+
# environment it is recommended to pass 'true' as your DataMapper models are probably
|
63
|
+
# changing often and there for should be re-profiled.
|
64
|
+
DataMapper::Cutie.start(true)
|
65
|
+
|
66
|
+
# If you are doing long term tracking in a production environment you will want to pass
|
67
|
+
# 'false' DM cutie will still migrate her tables the first time to make sure everything
|
68
|
+
# is set up correctly. PS, dm-cutie causes TONS of queries to be executed to adequatly track
|
69
|
+
# what is going on in your application. It would be recommended to only use her in development
|
70
|
+
# and staging environments.
|
71
|
+
# DataMapper::Cutie.start(false)
|
72
|
+
|
73
|
+
Starting the dm-cutie-ui sinatra app
|
74
|
+
# A bin file should have been included with the gem
|
75
|
+
#
|
76
|
+
# Want to see options?
|
77
|
+
# dm-cutie-ui --help
|
78
|
+
#
|
79
|
+
# The default port is 4567
|
80
|
+
$ dm-cutie-ui
|
81
|
+
|
82
|
+
Log into dm-cutie-ui
|
83
|
+
|
84
|
+
* Go to http://localhost:4567 #or whatever port you used
|
85
|
+
* Enter the path to your dm-cutie repo # mysql://root@localhost/dm-cutie
|
86
|
+
* Click 'connect' or enter a password if the account you are connecting with needs a password
|
87
|
+
* Learn?
|
88
|
+
|
89
|
+
|
90
|
+
How It Works
|
91
|
+
============
|
92
|
+
DM Cutie overrides DataObjectsAdapters and puts in some hooks to track queries. Cutie uses four models to store information about queries
|
93
|
+
|
94
|
+
* GeneralizedQuery - This is a query without variables bound to it
|
95
|
+
* Example: Person.first(:email => "user@example.com") would be stored as "SELECT * FROM `people` WHERE `email` = ?"
|
96
|
+
* This query will be unique to this table.
|
97
|
+
* Useful for determine how many generic queries are being generated by your application
|
98
|
+
* ExecutedQuery - This is a query WITH variables bound to it
|
99
|
+
* Example: Person.first(:email => "user@example.com") would be stored as "SELECT * FROM `people` WHERE `email` = 'user@example.com'"
|
100
|
+
* EVERY executed statement is stored in this table, executed statements do not have a unique constraint.
|
101
|
+
* This table has a foreign Key to GeneralizedQuery, so you can determine which ExecutedQuery objects are related
|
102
|
+
* Example: Person.first(:email => "user@example.com") and Person.first(:email => "person@example.com")
|
103
|
+
* Both ExecutedQuery objects would relate back to the GeneralizedQuery, Person.first(:email => ?) ("SELECT * FROM `people` WHERE `email` = ?")
|
104
|
+
* This also stores the line number and file name of the caller.
|
105
|
+
* RepositoryStorage - This keeps track of all storages (tables) across repositories.
|
106
|
+
* UnboundQueries 'belong' to RepositoryStorages through QueryStorageLink
|
107
|
+
* Example:
|
108
|
+
* if you have a Person model that is stored in a YAML repository that would be one RepositoryStorage
|
109
|
+
* if you have a Person model that is stored in a MySQL repostiroy that would be an additional RepositoryStorage
|
110
|
+
* UnboundQueries directed at MySQL for the Person model would be related to the MySQL Person RepositoryStorage object
|
111
|
+
* QueryStorageLink - ties a RepositoryStorage
|
112
|
+
* Denotes whether a RepositoryStorage was the 'primary storage' for a query
|
113
|
+
* The primary storage is determine by the Repository#name and Repository#adapter of the query object
|
114
|
+
* Other QueryStorageLinks on an GeneralizedQuery are a result of relationships that are stored in the Query#links
|
115
|
+
|
116
|
+
|
117
|
+
Important
|
118
|
+
=========
|
119
|
+
DM Cutie generates a ton of queries itself to track what is going on in DataMapper. It would be wise to use it to only to track your queries in a Staging or Development environment or temporarily in production.
|
120
|
+
|
121
|
+
DM Cutie essentially records a 'snapshot' of everything that happened in your applications repository.
|
122
|
+
|
123
|
+
|
124
|
+
Usage
|
125
|
+
=======
|
126
|
+
require 'dm-cutie'
|
127
|
+
|
128
|
+
# Load the hook for the adapter you want to track
|
129
|
+
DataMapper::Cutie.enable_adapter :data_objects
|
130
|
+
|
131
|
+
#note, these haven't been written yet
|
132
|
+
# DataMapper::Cutie.enable_adapter :yaml
|
133
|
+
# DataMapper::Cutie.enable_adapter :in_memory
|
134
|
+
|
135
|
+
# Optional
|
136
|
+
DataMapper::Cutie.setup do |c|
|
137
|
+
# The repo to use to store Cutie's data in
|
138
|
+
c[:repo_name] = :dm_cutie
|
139
|
+
|
140
|
+
# Models to always exclude from tracking
|
141
|
+
c[:exclude_models] = false #[:person, :car]
|
142
|
+
|
143
|
+
# Models to only tracker
|
144
|
+
c[:only_models] = false #[:article, :address]
|
145
|
+
|
146
|
+
# Time in seconds you consider a query to be slow
|
147
|
+
c[:slow_query_length] = 2
|
148
|
+
end
|
149
|
+
|
150
|
+
DataMapper::Cutie.start
|
151
|
+
|
152
|
+
|
153
|
+
Adapter Trackers vs Tracker Hooks
|
154
|
+
====================================
|
155
|
+
|
156
|
+
* Adapter Trackers are the basic trackers for a specific adapter (DataObjectsAdapter, MySQLAdapter, etc)
|
157
|
+
* Provide the basic functionality to 'capture' a query in progress and the basic storage of details in ExecutedQuery, GeneralizedQuery, RepositoryStorage, and QueryStorageLink
|
158
|
+
* Currently this is NOT DRY and is a bit hostile, as it literally reimplements the CRUD layer methods in DO
|
159
|
+
* Tracker Hooks allow you to create additional storages for details that are outside the basic 4 models included in Cutie
|
160
|
+
* Example: All SQL queries have a RepositoryStorage (the tables in the FROM statement), but only a MySQL query would have a MySQL execution plan, so you can have a Tracker Hook that will only store MySQL Execution plans if its the mysql adapter
|
161
|
+
* Allow you to perform logic on an 'executed query'
|
162
|
+
|
163
|
+
|
164
|
+
Enabling Tracker Hooks
|
165
|
+
=========================
|
166
|
+
|
167
|
+
A project of tracker hooks exists called dm-cutie-extras.
|
168
|
+
|
169
|
+
require 'dm-cutie'
|
170
|
+
DataMapper::Cutie.enable_adapter :data_objects
|
171
|
+
|
172
|
+
# Simply require the additional trackers
|
173
|
+
require 'dm-cutie-extras'
|
174
|
+
DataMapper::Cutie::Extras.load :mysql_execution_step
|
175
|
+
DataMapper::Cutie::Extras.load :sqlite3_execution_step
|
176
|
+
|
177
|
+
DataMapper::Cutie.start(true)
|
178
|
+
|
179
|
+
|
180
|
+
Currently included are:
|
181
|
+
|
182
|
+
* MySQL Execution Step - Runs a query plan for MySQL queries
|
183
|
+
* Sqlite3 Execution Step - Runs a query plan for Sqlite3 queries
|
184
|
+
|
185
|
+
|
186
|
+
Writing Tracker Hooks
|
187
|
+
=========================
|
188
|
+
To write a tracker simply include DataMapper::Cutie::Tracker::Hook::Abstract into a class and define a few methods
|
189
|
+
class MyTrackerHook
|
190
|
+
include DataMapper::Cutie::Tracker::Hook::Abstract
|
191
|
+
|
192
|
+
# The name of your hook
|
193
|
+
def self.hook_name
|
194
|
+
"Really cool hook"
|
195
|
+
end
|
196
|
+
|
197
|
+
# the statements this tracker applies to
|
198
|
+
def self.supported_statements
|
199
|
+
[:select]
|
200
|
+
end
|
201
|
+
|
202
|
+
# The adapters this tracker applies to
|
203
|
+
def self.suppored_adapters
|
204
|
+
[:mysql]
|
205
|
+
end
|
206
|
+
|
207
|
+
# This is a factory method that will run your tracking logic
|
208
|
+
# this method will receive the current ExecutedQuery
|
209
|
+
#
|
210
|
+
def self.track( executed_query )
|
211
|
+
# Your tracking logic goes here
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
Then let Cutie know she has a new hook to work with
|
216
|
+
DataMapper::Cutie.add_tracker_hook :my_tracker_hook #Symbol representation of your class name
|
217
|
+
|
218
|
+
Example "Hi Mom! Tracker Hook" - Sends mom an email telling her what SELECT statements where ran
|
219
|
+
|
220
|
+
class HiMomTrackerHook
|
221
|
+
include DataMapper::Cutie::Tracker::Hook::Abstract
|
222
|
+
|
223
|
+
# The name of your hook
|
224
|
+
def self.hook_name
|
225
|
+
"Hi Mom! Tracker hook"
|
226
|
+
end
|
227
|
+
|
228
|
+
# the statements this tracker applies to
|
229
|
+
def self.supported_statements
|
230
|
+
[:select]
|
231
|
+
end
|
232
|
+
|
233
|
+
# The adapters this tracker applies to
|
234
|
+
def self.suppored_adapters
|
235
|
+
[:mysql]
|
236
|
+
end
|
237
|
+
|
238
|
+
def self.track( executed_query )
|
239
|
+
# This is an absolutely awesome tracker, because my mom can optimize the heck out of a query.
|
240
|
+
|
241
|
+
my_cool_mail_method(
|
242
|
+
:to => "mom@example.com",
|
243
|
+
:from => "yourlovingchild@example.com",
|
244
|
+
:subject => "my friends are reading my data",
|
245
|
+
:body => "My friend just executed this query: #{executed_query.generalized_query.statement}"
|
246
|
+
)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
# Of course tell cutie she has a new hook
|
251
|
+
DataMapper::Cutie.add_tracker_hook :hi_mom_tracker_hook
|
252
|
+
|
253
|
+
|
254
|
+
Example "Which Server Executed What" - Keeps track of what Application server sent the query
|
255
|
+
# Create a model to store server names in
|
256
|
+
class QueryingServer
|
257
|
+
require 'socket'
|
258
|
+
include DataMapper::Cutie::Tracker::Hook::Abstract
|
259
|
+
|
260
|
+
include DataMapper::Resource
|
261
|
+
has n, :executed_queries
|
262
|
+
|
263
|
+
property :id, Serial
|
264
|
+
property :name, String, :unique_index => true
|
265
|
+
|
266
|
+
def self.hook_name
|
267
|
+
"Which Server Executed A Query Hook"
|
268
|
+
end
|
269
|
+
|
270
|
+
def self.supported_statements
|
271
|
+
[:select, :insert, :update, :delete]
|
272
|
+
end
|
273
|
+
|
274
|
+
def self.suppored_adapters
|
275
|
+
[:mysql]
|
276
|
+
end
|
277
|
+
|
278
|
+
def self.track( executed_query )
|
279
|
+
DataMapper::Cutie.repo do #get access to the Cutie's repo (you can store this wherever, probably makes sense here though)
|
280
|
+
|
281
|
+
trans = DataMapper::Transaction.new #start a transaction (optional)
|
282
|
+
|
283
|
+
trans.link do
|
284
|
+
querying_server = QueryingServer.first_or_create(:name => Socket.gethostname)
|
285
|
+
querying_server.executed_queries << executed_query
|
286
|
+
querying_server.save
|
287
|
+
end
|
288
|
+
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
end
|
293
|
+
|
294
|
+
# Let ExecutedQuery know its getting a new column :P
|
295
|
+
ExecutedQuery.send :belongs_to, :querying_server
|
296
|
+
|
297
|
+
# Of course let cutie know she has a new hook
|
298
|
+
DataMapper::Cutie.add_tracker_hook :querying_server
|
299
|
+
|
300
|
+
# Here we have one other concern, we've created a new model: QueryingServer. We want Cutie to treat this model as an internal model, so she doesn't track it (which would cause an infinite loop)
|
301
|
+
DataMapper::Cutie.add_internal_model :querying_server
|
302
|
+
|
303
|
+
|
304
|
+
Tracker hooks don't have to be a model, but they can be.
|
305
|
+
|
306
|
+
The #track method receives a ExecutedQuery object. Here are some methods available on that object
|
307
|
+
|
308
|
+
executed_query.generalized_query #The GeneralizedQuery object
|
309
|
+
executed_query.statement #The bound SQL Statement
|
310
|
+
executed_query.generalized_query.statement #The generalized SQL Statement
|
311
|
+
executed_query.bind_values #The bind values for the SQL Statement
|
312
|
+
# etc... Everything that is available on a DataMapper::Query object
|
313
|
+
|
314
|
+
|
315
|
+
Writing an Adapter Tracker
|
316
|
+
==================
|
317
|
+
|
318
|
+
Trackers should 'hook' around the method that is to be tracked. In the DataObjectsTracker example
|
319
|
+
the methods being tracked are
|
320
|
+
|
321
|
+
* select_statement
|
322
|
+
* insert_statement
|
323
|
+
* update_statement
|
324
|
+
* delete_statement
|
325
|
+
|
326
|
+
A model that is performing a crud action will only be tracked if the adapter of the repository that the action
|
327
|
+
is happening in is based on the DO Adapter.
|
328
|
+
|
329
|
+
|
330
|
+
TODOS
|
331
|
+
=====
|
332
|
+
* Model.all => Doesnt track -> Probably need to add an override to Collection class
|
333
|
+
* Rspecs, convert test_script.rb to specs
|
334
|
+
|
335
|
+
* Format documentation for rdoc/yard whatever.
|
336
|
+
* is there an easier way to 'hi jack' something at the DO Adapter level other than making the code unDRY in /tracker/data_objects/overrides
|
337
|
+
* Tried using extlib hooks, but needed access to local variables in the DO CRUD methods
|
338
|
+
|
339
|
+
* Namespace the Models so they dont interfere with anyones code if they have the same model names.
|
340
|
+
* Tracker hooks trackers should automatically be stored in DataMapper::Cutie.repo instead of having to explicitly call it
|
341
|
+
* Spot Tracking => Cutie.track{...statements...} #So you can track a specific area, rather than the whole system
|
342
|
+
|
343
|
+
CONSIDERATIONS
|
344
|
+
===============
|
345
|
+
|
346
|
+
* Should this be pushed back to the DO level?
|
347
|
+
* I like using DM to access data... also the potential to track DM Sphinx, etc
|
348
|
+
* Its highly geared toward SQL, can it be abstracted
|
349
|
+
* use CRUD operations instead of :select, :insert, :update, :delete
|
350
|
+
* Get self.default_respository_name to work so all CUTIE queries dont have to be done in Cutie.repo block
|
351
|
+
* class_eval def self.default_repository_name; #{THE_NAME}; end;
|
352
|
+
* Add ability to exclude/include repositories. You might have 3 MySQL repos, and are tracking the DO adapter, but are only interested in a particular database
|
data/Rakefile
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'rubygems/specification'
|
4
|
+
require 'date'
|
5
|
+
require "extlib"
|
6
|
+
|
7
|
+
require 'rake'
|
8
|
+
require 'rake/clean'
|
9
|
+
require 'spec/rake/spectask'
|
10
|
+
require "spec"
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
require 'rake/gempackagetask'
|
13
|
+
|
14
|
+
ROOT = Pathname(__FILE__).dirname.expand_path
|
15
|
+
require ROOT + 'lib/dm-cutie/version'
|
16
|
+
|
17
|
+
@spec = Gem::Specification.new do |s|
|
18
|
+
s.name = %q{dm-cutie}
|
19
|
+
s.version = DataMapper::Cutie::VERSION
|
20
|
+
|
21
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
22
|
+
s.authors = ["Cory ODaniel"]
|
23
|
+
s.date = %q{2009-10-15}
|
24
|
+
s.summary = %q{DataMapper's Original Query Tracker'}
|
25
|
+
s.description = %q{DataMapper's Query Tracker; She is super thorough and easy as hell, just the way you like it.}
|
26
|
+
|
27
|
+
s.email = %q{cutie@coryodaniel.com}
|
28
|
+
|
29
|
+
s.extra_rdoc_files = ["README.markdown", "LICENSE", "History.txt"]
|
30
|
+
s.files = ["LICENSE", "README.markdown", "Rakefile",
|
31
|
+
"lib/dm-cutie.rb",
|
32
|
+
"lib/dm-cutie/cutie.rb",
|
33
|
+
"lib/dm-cutie/version.rb",
|
34
|
+
|
35
|
+
"lib/dm-cutie/models/executed_query.rb",
|
36
|
+
"lib/dm-cutie/models/query_storage_link.rb",
|
37
|
+
"lib/dm-cutie/models/repository_storage.rb",
|
38
|
+
"lib/dm-cutie/models/generalized_query.rb",
|
39
|
+
|
40
|
+
"lib/dm-cutie/tracker/data_objects.rb",
|
41
|
+
"lib/dm-cutie/tracker/data_objects/helper.rb",
|
42
|
+
"lib/dm-cutie/tracker/data_objects/overrides.rb",
|
43
|
+
|
44
|
+
"lib/dm-cutie/tracker/hook/abstract.rb"
|
45
|
+
|
46
|
+
]
|
47
|
+
s.add_dependency "extlib",">=0.9.12"
|
48
|
+
s.add_dependency "dm-core", '>=0.10.0'
|
49
|
+
s.add_dependency "dm-types", '>=0.10.0'
|
50
|
+
s.has_rdoc = true
|
51
|
+
s.homepage = "http://github.com/coryodaniel/dm-cutie"
|
52
|
+
s.require_paths = ["lib"]
|
53
|
+
s.rubygems_version = %q{1.2.0}
|
54
|
+
end
|
55
|
+
|
56
|
+
[ ROOT, ROOT.parent ].each do |dir|
|
57
|
+
Pathname.glob(dir.join('tasks/**/*.rb').to_s).each { |f| require f }
|
58
|
+
end
|
59
|
+
|
60
|
+
NAME = @spec.name
|
61
|
+
GEM_VERSION = DataMapper::Cutie::VERSION
|
62
|
+
|
63
|
+
Rake::GemPackageTask.new(@spec) do |pkg|
|
64
|
+
pkg.gem_spec = @spec
|
65
|
+
end
|
66
|
+
|
67
|
+
desc "install the plugin locally"
|
68
|
+
task :install => [:package] do
|
69
|
+
sh %{sudo gem install #{install_home} pkg/#{NAME}-#{GEM_VERSION} --no-update-sources}
|
70
|
+
end
|
71
|
+
|
72
|
+
desc "create a gemspec file"
|
73
|
+
task :make_spec do
|
74
|
+
File.open("#{NAME}.gemspec", "w") do |file|
|
75
|
+
file.puts @spec.to_ruby
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
Rake::RDocTask.new do |rdoc|
|
80
|
+
files = ["README.markdown", "History.txt", "LICENSE", "lib/**/*.rb"]
|
81
|
+
rdoc.rdoc_files.add(files)
|
82
|
+
rdoc.main = "README.markdown"
|
83
|
+
rdoc.title = "DM Cutie"
|
84
|
+
|
85
|
+
rdoc.rdoc_dir = "doc/rdoc"
|
86
|
+
rdoc.options << "--line-numbers" << "--inline-source"
|
87
|
+
end
|
88
|
+
|
89
|
+
Spec::Rake::SpecTask.new do |t|
|
90
|
+
t.spec_files = Dir["./spec/**/*_spec.rb"]
|
91
|
+
t.spec_files.unshift './spec/spec_helper.rb'
|
92
|
+
|
93
|
+
t.libs = ['lib']
|
94
|
+
t.spec_opts << "--color" << "--format" << "specdoc" #"progress"
|
95
|
+
|
96
|
+
if ENV['RCOV']
|
97
|
+
t.rcov = true
|
98
|
+
t.rcov_opts << '--exclude' << 'pkg,spec,interactive.rb,install_test_suite.rb,lib/gems,' + Gem.path.join(',')
|
99
|
+
t.rcov_opts << '--text-summary'
|
100
|
+
t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
|
101
|
+
t.rcov_opts << '--only-uncovered'
|
102
|
+
end
|
103
|
+
end
|