pio 0.3.0 → 0.4.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.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +46 -12
- data/README.md +131 -116
- data/Rakefile +7 -92
- data/examples/arp_new.rb +16 -0
- data/examples/arp_read.rb +4 -0
- data/examples/dhcp_new.rb +30 -0
- data/examples/dhcp_read.rb +4 -0
- data/examples/icmp_new.rb +21 -0
- data/examples/icmp_read.rb +4 -0
- data/examples/lldp_new.rb +4 -0
- data/examples/lldp_read.rb +4 -0
- data/lib/pio.rb +6 -12
- data/lib/pio/arp.rb +7 -19
- data/lib/pio/arp/frame.rb +8 -12
- data/lib/pio/arp/message.rb +12 -25
- data/lib/pio/arp/reply.rb +30 -30
- data/lib/pio/arp/request.rb +30 -29
- data/lib/pio/dhcp.rb +58 -0
- data/lib/pio/dhcp/ack.rb +12 -0
- data/lib/pio/dhcp/boot_reply.rb +16 -0
- data/lib/pio/dhcp/boot_reply_options.rb +75 -0
- data/lib/pio/dhcp/boot_request.rb +16 -0
- data/lib/pio/dhcp/boot_request_options.rb +69 -0
- data/lib/pio/dhcp/common_options.rb +71 -0
- data/lib/pio/dhcp/csum_util.rb +83 -0
- data/lib/pio/dhcp/dhcp_field.rb +48 -0
- data/lib/pio/dhcp/dhcp_tlv_options.rb +84 -0
- data/lib/pio/dhcp/discover.rb +12 -0
- data/lib/pio/dhcp/field_util.rb +102 -0
- data/lib/pio/dhcp/frame.rb +95 -0
- data/lib/pio/dhcp/message.rb +79 -0
- data/lib/pio/dhcp/offer.rb +12 -0
- data/lib/pio/dhcp/optional_tlv.rb +74 -0
- data/lib/pio/dhcp/request.rb +12 -0
- data/lib/pio/dhcp/type/dhcp_client_id.rb +21 -0
- data/lib/pio/dhcp/type/dhcp_param_list.rb +22 -0
- data/lib/pio/dhcp/type/dhcp_string.rb +21 -0
- data/lib/pio/icmp.rb +7 -18
- data/lib/pio/icmp/frame.rb +38 -40
- data/lib/pio/icmp/message.rb +10 -61
- data/lib/pio/icmp/options.rb +25 -0
- data/lib/pio/icmp/reply.rb +34 -7
- data/lib/pio/icmp/request.rb +43 -7
- data/lib/pio/ipv4_address.rb +5 -8
- data/lib/pio/lldp.rb +22 -62
- data/lib/pio/lldp/chassis_id_tlv.rb +7 -13
- data/lib/pio/lldp/end_of_lldpdu_value.rb +3 -9
- data/lib/pio/lldp/frame.rb +6 -12
- data/lib/pio/lldp/management_address_value.rb +4 -10
- data/lib/pio/lldp/optional_tlv.rb +5 -10
- data/lib/pio/lldp/options.rb +37 -0
- data/lib/pio/lldp/organizationally_specific_value.rb +2 -8
- data/lib/pio/lldp/port_description_value.rb +2 -8
- data/lib/pio/lldp/port_id_tlv.rb +6 -12
- data/lib/pio/lldp/system_capabilities_value.rb +2 -8
- data/lib/pio/lldp/system_description_value.rb +2 -8
- data/lib/pio/lldp/system_name_value.rb +2 -8
- data/lib/pio/lldp/ttl_tlv.rb +5 -11
- data/lib/pio/mac.rb +4 -9
- data/lib/pio/message_type_selector.rb +22 -0
- data/lib/pio/options.rb +65 -0
- data/lib/pio/parse_error.rb +6 -0
- data/lib/pio/type/ethernet_header.rb +3 -2
- data/lib/pio/type/ip_address.rb +4 -9
- data/lib/pio/type/ipv4_header.rb +12 -17
- data/lib/pio/type/mac_address.rb +5 -10
- data/lib/pio/type/udp_header.rb +18 -0
- data/lib/pio/version.rb +3 -8
- data/pio.gemspec +12 -10
- data/spec/pio/arp/reply/options_spec.rb +145 -0
- data/spec/pio/arp/reply_spec.rb +77 -113
- data/spec/pio/arp/request/options_spec.rb +115 -0
- data/spec/pio/arp/request_spec.rb +74 -96
- data/spec/pio/arp_spec.rb +71 -105
- data/spec/pio/dhcp/ack_spec.rb +189 -0
- data/spec/pio/dhcp/discover_spec.rb +165 -0
- data/spec/pio/dhcp/offer_spec.rb +189 -0
- data/spec/pio/dhcp/request_spec.rb +173 -0
- data/spec/pio/dhcp_spec.rb +609 -0
- data/spec/pio/icmp/reply_spec.rb +102 -95
- data/spec/pio/icmp/request_spec.rb +86 -78
- data/spec/pio/icmp_spec.rb +153 -146
- data/spec/pio/ipv4_address_spec.rb +2 -7
- data/spec/pio/lldp/options_spec.rb +188 -0
- data/spec/pio/lldp_spec.rb +181 -208
- data/spec/pio/mac_spec.rb +3 -8
- data/spec/spec_helper.rb +4 -10
- metadata +69 -17
- data/.gitignore +0 -20
- data/.rspec +0 -3
- data/.rubocop.yml +0 -1
- data/.travis.yml +0 -13
- data/Gemfile +0 -37
- data/Guardfile +0 -24
- data/lib/pio/message_util.rb +0 -19
- data/lib/pio/type/config.reek +0 -4
- data/lib/pio/util.rb +0 -21
- data/pio.org +0 -668
- data/pio.org_archive +0 -943
- data/rubocop-todo.yml +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46ff2e5ea71119c5c3f334e9714aad64c6394416
|
4
|
+
data.tar.gz: f8d3b344b34473f4ff12992e86ee02db5e97f750
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d12b409112666b903cd16280299613440986d86d199e6cf1eff4d1631ba6580c792bc539fac1f4c19017014a6999b2bdb05e4a501b9b4a10ec9332d0f4759afd
|
7
|
+
data.tar.gz: c44a02181e9b75710884acf48773d1f0a287c07d13e96c9f86a25552a4e22682eced7409f32f061836dc7f0a838e4dffa9e42bf41f0a10e0dfc38d706426418e
|
data/CONTRIBUTING.md
CHANGED
@@ -1,12 +1,46 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
*
|
8
|
-
|
9
|
-
*
|
10
|
-
|
11
|
-
*
|
12
|
-
*
|
1
|
+
## Contributing
|
2
|
+
In the spirit of [free software][free-sw], **everyone** is encouraged to help
|
3
|
+
improve this project.
|
4
|
+
|
5
|
+
[free-sw]: http://www.fsf.org/licensing/essays/free-sw.html
|
6
|
+
|
7
|
+
Here are some ways *you* can contribute:
|
8
|
+
|
9
|
+
* by using alpha, beta, and prerelease versions
|
10
|
+
* by reporting bugs
|
11
|
+
* by suggesting new features
|
12
|
+
* by writing or editing documentation
|
13
|
+
* by writing specifications
|
14
|
+
* by writing code (**no patch is too small**: fix typos, add comments, clean up
|
15
|
+
inconsistent whitespace)
|
16
|
+
* by refactoring code
|
17
|
+
* by fixing [issues][]
|
18
|
+
* by reviewing patches
|
19
|
+
|
20
|
+
[issues]: https://github.com/trema/pio/issues
|
21
|
+
|
22
|
+
## Submitting an Issue
|
23
|
+
We use the [GitHub issue tracker][issues] to track bugs and features. Before
|
24
|
+
submitting a bug report or feature request, check to make sure it hasn't
|
25
|
+
already been submitted. When submitting a bug report, please include a [Gist][]
|
26
|
+
that includes a stack trace and any details that may be necessary to reproduce
|
27
|
+
the bug, including your gem version, Ruby version, and operating system.
|
28
|
+
Ideally, a bug report should include a pull request with failing specs.
|
29
|
+
|
30
|
+
[gist]: https://gist.github.com/
|
31
|
+
|
32
|
+
## Submitting a Pull Request
|
33
|
+
1. [Fork the repository.][fork]
|
34
|
+
2. [Create a topic branch.][branch]
|
35
|
+
3. Add specs for your unimplemented feature or bug fix.
|
36
|
+
4. Run `bundle exec rake spec`. If your specs pass, return to step 3.
|
37
|
+
5. Implement your feature or bug fix.
|
38
|
+
6. Run `bundle exec rake default`. If your specs fail, return to step 5.
|
39
|
+
7. Run `open coverage/index.html`. If your changes are not completely covered
|
40
|
+
by your tests, return to step 3.
|
41
|
+
8. Add, commit, and push your changes.
|
42
|
+
9. [Submit a pull request.][pr]
|
43
|
+
|
44
|
+
[fork]: http://help.github.com/fork-a-repo/
|
45
|
+
[branch]: http://learn.github.com/p/branching.html
|
46
|
+
[pr]: http://help.github.com/send-pull-requests/
|
data/README.md
CHANGED
@@ -1,36 +1,33 @@
|
|
1
|
-
Pio
|
2
|
-
===
|
3
|
-
[](http://badge.fury.io/rb/pio)
|
4
|
-
[](https://travis-ci.org/trema/pio)
|
5
|
-
[](https://codeclimate.com/github/trema/pio)
|
6
|
-
[](https://coveralls.io/r/trema/pio)
|
7
|
-
[](https://gemnasium.com/trema/pio)
|
1
|
+
# Pio
|
8
2
|
|
9
|
-
<a href=
|
10
|
-
|
11
|
-
|
3
|
+
<a href='https://rubygems.org/gems/pio'><img src='http://img.shields.io/gem/v/pio.svg' alt='Gem Version' /></a>
|
4
|
+
<a href='https://travis-ci.org/trema/pio'><img src='http://img.shields.io/travis/trema/pio/develop.svg' alt='Build Status' /></a>
|
5
|
+
<a href='https://codeclimate.com/github/trema/pio'><img src='http://img.shields.io/codeclimate/github/trema/pio.svg' alt='Code Climate' /></a>
|
6
|
+
<a href='https://coveralls.io/r/trema/pio?branch=develop'><img src='http://img.shields.io/coveralls/trema/pio/develop.svg' alt='Coverage Status' /></a>
|
7
|
+
<a href='https://gemnasium.com/trema/pio'><img src='https://gemnasium.com/trema/pio.svg' alt='Dependency Status' /></a>
|
8
|
+
<a href="http://inch-pages.github.io/github/trema/pio"><img src="http://inch-pages.github.io/github/trema/pio.svg" alt="Inline docs"></a>
|
12
9
|
|
13
|
-
|
14
|
-
* ARP
|
15
|
-
* LLDP
|
16
|
-
* (...currently there are just a few formats supported but I'm sure this list will grow)
|
10
|
+
<a href="http://www.flickr.com/photos/mongogushi/4226014070/" title="pio pencil by mongo gushi, on Flickr"><img src="http://farm5.staticflickr.com/4022/4226014070_cdeb7c1e5d_n.jpg" width="320" height="290" alt="pio pencil"></a>
|
17
11
|
|
12
|
+
Pio is a ruby gem to easily parse and generate network packets. It
|
13
|
+
supports the following packet formats:
|
18
14
|
|
19
|
-
|
20
|
-
|
15
|
+
- ICMP
|
16
|
+
- ARP
|
17
|
+
- LLDP
|
18
|
+
- DHCP
|
19
|
+
- (…currently there are just a few formats supported but I'm sure this list will grow)
|
21
20
|
|
22
|
-
|
23
|
-
to parse/generate packets.
|
24
|
-
* Multi-Platform. Runs on major operating systems (recent Windows,
|
25
|
-
Linux, and MacOSX), and supports all major version of Ruby (1.8.7,
|
26
|
-
1.9.3, 2.0.0).
|
27
|
-
* Clean Code. Pio is built on
|
28
|
-
[BinData](https://github.com/dmendel/bindata)'s declarative binary
|
29
|
-
format DSL so that it is easy to read and debug by human beings.
|
21
|
+
## Features Overview
|
30
22
|
|
23
|
+
- Pure Ruby. No additional dependency on other external tools to
|
24
|
+
parse/generate packets.
|
25
|
+
- Multi-Platform. Runs on major operating systems (recent Windows,
|
26
|
+
Linux, and MacOSX).
|
27
|
+
- Clean Code. Pio is built on [BinData](https://github.com/dmendel/bindata)'s declarative binary format DSL
|
28
|
+
so that it is easy to read and debug by human beings.
|
31
29
|
|
32
|
-
Examples
|
33
|
-
--------
|
30
|
+
## Examples
|
34
31
|
|
35
32
|
Its usage is dead simple.
|
36
33
|
|
@@ -39,141 +36,159 @@ Its usage is dead simple.
|
|
39
36
|
To parse an ICMP frame, use the API `Pio::Icmp.read` and you can
|
40
37
|
access each field of the parsed ICMP frame.
|
41
38
|
|
42
|
-
|
43
|
-
|
44
|
-
icmp = Pio::Icmp.read(binary_data)
|
45
|
-
icmp.source_mac.to_s
|
46
|
-
```
|
39
|
+
require 'pio'
|
40
|
+
|
41
|
+
icmp = Pio::Icmp.read(binary_data)
|
42
|
+
icmp.source_mac.to_s # => '00:26:82:eb:ea:d1'
|
47
43
|
|
48
44
|
Also you can use `Pio::Icmp::Request#new` or `Pio::Icmp::Reply#new` to
|
49
45
|
generate an Icmp Request/Reply frame like below:
|
50
46
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
)
|
73
|
-
reply.to_binary #=> ICMP Reply frame in binary format.
|
74
|
-
```
|
47
|
+
require 'pio'
|
48
|
+
|
49
|
+
request = Pio::Icmp::Request.new(
|
50
|
+
source_mac: '00:16:9d:1d:9c:c4',
|
51
|
+
destination_mac: '00:26:82:eb:ea:d1',
|
52
|
+
ip_source_address: '192.168.83.3',
|
53
|
+
ip_destination_address: '192.168.83.254'
|
54
|
+
)
|
55
|
+
request.to_binary # => ICMP Request frame in binary format.
|
56
|
+
|
57
|
+
reply = Pio::Icmp::Reply.new(
|
58
|
+
source_mac: '00:26:82:eb:ea:d1',
|
59
|
+
destination_mac: '00:16:9d:1d:9c:c4',
|
60
|
+
ip_source_address: '192.168.83.254',
|
61
|
+
ip_destination_address: '192.168.83.3',
|
62
|
+
# The ICMP Identifier and the ICMP Sequence number
|
63
|
+
# should be same as those of the request.
|
64
|
+
identifier: request.icmp_identifier,
|
65
|
+
sequence_number: request.icmp_sequence_number
|
66
|
+
)
|
67
|
+
reply.to_binary # => ICMP Reply frame in binary format.
|
75
68
|
|
76
69
|
### ARP
|
77
70
|
|
78
71
|
To parse an ARP frame, use the API `Pio::Arp.read` and you can access
|
79
72
|
each field of the parsed ARP frame.
|
80
73
|
|
81
|
-
|
82
|
-
require 'pio'
|
74
|
+
require 'pio'
|
83
75
|
|
84
|
-
arp = Pio::Arp.read(binary_data)
|
85
|
-
arp.source_mac.to_s
|
86
|
-
```
|
76
|
+
arp = Pio::Arp.read(binary_data)
|
77
|
+
arp.source_mac.to_s # => '00:26:82:eb:ea:d1'
|
87
78
|
|
88
79
|
Also you can use `Pio::Arp::Request#new` or `Pio::Arp::Reply#new` to
|
89
80
|
generate an Arp Request/Reply frame like below:
|
90
81
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
reply.to_binary #=> Arp Reply frame in binary format.
|
108
|
-
```
|
82
|
+
require 'pio'
|
83
|
+
|
84
|
+
request = Pio::Arp::Request.new(
|
85
|
+
source_mac: '00:26:82:eb:ea:d1',
|
86
|
+
sender_protocol_address: '192.168.83.3',
|
87
|
+
target_protocol_address: '192.168.83.254'
|
88
|
+
)
|
89
|
+
request.to_binary # => Arp Request frame in binary format.
|
90
|
+
|
91
|
+
reply = Pio::Arp::Reply.new(
|
92
|
+
source_mac: '00:16:9d:1d:9c:c4',
|
93
|
+
destination_mac: '00:26:82:eb:ea:d1',
|
94
|
+
sender_protocol_address: '192.168.83.254',
|
95
|
+
target_protocol_address: '192.168.83.3'
|
96
|
+
)
|
97
|
+
reply.to_binary # => Arp Reply frame in binary format.
|
109
98
|
|
110
99
|
### LLDP
|
111
100
|
|
112
101
|
To parse an LLDP frame, use the API `Pio::Lldp.read` and you can
|
113
102
|
access each field of the parsed LLDP frame.
|
114
103
|
|
115
|
-
|
116
|
-
require 'pio'
|
104
|
+
require 'pio'
|
117
105
|
|
118
|
-
lldp = Pio::Lldp.read(binary_data)
|
119
|
-
lldp.ttl
|
120
|
-
```
|
106
|
+
lldp = Pio::Lldp.read(binary_data)
|
107
|
+
lldp.ttl # => 120
|
121
108
|
|
122
109
|
Also you can use `Pio::Lldp#new` to generate an LLDP frame like below:
|
123
110
|
|
124
|
-
|
125
|
-
require 'pio'
|
111
|
+
require 'pio'
|
126
112
|
|
127
|
-
lldp = Pio::Lldp.new(dpid: 0x123, port_number: 12)
|
128
|
-
lldp.to_binary
|
129
|
-
```
|
113
|
+
lldp = Pio::Lldp.new(dpid: 0x123, port_number: 12)
|
114
|
+
lldp.to_binary # => LLDP frame in binary format.
|
130
115
|
|
116
|
+
### DHCP
|
131
117
|
|
132
|
-
|
133
|
-
|
118
|
+
To parse a DHCP frame, use the API `Pio::Dhcp.read` and you can access
|
119
|
+
each field of the parsed DHCP frame.
|
134
120
|
|
135
|
-
|
121
|
+
require 'pio'
|
136
122
|
|
137
|
-
|
123
|
+
dhcp = Pio::Dhcp.read(binary_data)
|
124
|
+
dhcp.destination_mac.to_s # => 'ff:ff:ff:ff:ff:ff'
|
138
125
|
|
139
|
-
|
140
|
-
|
141
|
-
|
126
|
+
Also you can use `Pio::Dhcp::Discover#new`,
|
127
|
+
`Pio::Dhcp::Offer#new`, `Pio::Dhcp::Request#new` and
|
128
|
+
`Pio::Dhcp::Ack#new` to generate a DHCP frame like below:
|
142
129
|
|
143
|
-
|
130
|
+
require 'pio'
|
144
131
|
|
145
|
-
|
146
|
-
|
147
|
-
```
|
132
|
+
discover = Pio::Dhcp::Discover.new(source_mac: '24:db:ac:41:e5:5b')
|
133
|
+
discover.to_binary # => DHCP Discover frame in binary format
|
148
134
|
|
135
|
+
offer = Pio::Dhcp::Offer.new(
|
136
|
+
source_mac: '00:26:82:eb:ea:d1',
|
137
|
+
destination_mac: '24:db:ac:41:e5:5b',
|
138
|
+
ip_source_address: '192.168.0.100',
|
139
|
+
ip_destination_address: '192.168.0.1',
|
140
|
+
transaction_id: discover.transaction_id
|
141
|
+
)
|
142
|
+
offer.to_binary # => DHCP Offer frame in binary format
|
149
143
|
|
150
|
-
|
151
|
-
|
144
|
+
request = Pio::Dhcp::Request.new(
|
145
|
+
source_mac: '24:db:ac:41:e5:5b',
|
146
|
+
server_identifier: '192.168.0.100',
|
147
|
+
requested_ip_address: '192.168.0.1',
|
148
|
+
transaction_id: offer.transaction_id
|
149
|
+
)
|
150
|
+
request.to_binary # => DHCP Request frame in binary format
|
152
151
|
|
153
|
-
|
152
|
+
ack = Pio::Dhcp::Ack.new(
|
153
|
+
source_mac: '00:26:82:eb:ea:d1',
|
154
|
+
destination_mac: '24:db:ac:41:e5:5b',
|
155
|
+
ip_source_address: '192.168.0.100',
|
156
|
+
ip_destination_address: '192.168.0.1',
|
157
|
+
transaction_id: request.transaction_id
|
158
|
+
)
|
159
|
+
ack.to_binary # => DHCP Ack frame in binary format
|
154
160
|
|
161
|
+
## Installation
|
155
162
|
|
156
|
-
|
157
|
-
----
|
163
|
+
The simplest way to install Pio is to use [Bundler](http://gembundler.com/).
|
158
164
|
|
159
|
-
|
160
|
-
* [Eishun Kondoh](https://github.com/shun159) ([@Eishun_Kondoh](https://twitter.com/Eishun_Kondoh))
|
165
|
+
Add Pio to your `Gemfile`:
|
161
166
|
|
162
|
-
|
167
|
+
gem 'pio'
|
168
|
+
|
169
|
+
and install it by running Bundler:
|
163
170
|
|
164
|
-
|
171
|
+
prompt> bundle
|
165
172
|
|
173
|
+
## Documents
|
166
174
|
|
167
|
-
|
168
|
-
|
175
|
+
- [API document generated with YARD](http://rubydoc.info/github/trema/pio/frames/file/README.md)
|
176
|
+
|
177
|
+
## Team
|
178
|
+
|
179
|
+
- [Yasuhito Takamiya](https://github.com/yasuhito) ([@yasuhito](https://twitter.com/yasuhito))
|
180
|
+
- [Eishun Kondoh](https://github.com/shun159) ([@Eishun\_Kondoh](https://twitter.com/Eishun_Kondoh))
|
181
|
+
|
182
|
+
### Contributors
|
169
183
|
|
170
|
-
|
171
|
-
* Racket: http://spoofed.org/files/racket/
|
184
|
+
<https://github.com/trema/pio/contributors>
|
172
185
|
|
186
|
+
## Alternatives
|
173
187
|
|
174
|
-
|
175
|
-
|
188
|
+
- PacketFu: <https://github.com/todb/packetfu>
|
189
|
+
- Racket: <http://spoofed.org/files/racket/>
|
176
190
|
|
177
|
-
|
191
|
+
## License
|
178
192
|
|
179
|
-
|
193
|
+
Pio is released under the GNU General Public License version 3.0:
|
194
|
+
- <http://www.gnu.org/licenses/gpl.html>
|
data/Rakefile
CHANGED
@@ -1,101 +1,16 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require 'bundler/gem_tasks'
|
2
|
-
require 'coveralls/rake/task'
|
3
|
-
require 'flay'
|
4
|
-
require 'flay_task'
|
5
|
-
require 'flog'
|
6
|
-
require 'rake/tasklib'
|
7
|
-
require 'reek/rake/task'
|
8
|
-
require 'rspec/core'
|
9
|
-
require 'rspec/core/rake_task'
|
10
|
-
require 'yaml'
|
11
|
-
require 'yard'
|
12
4
|
|
13
|
-
|
5
|
+
# rubocop:disable HashSyntax
|
14
6
|
|
15
7
|
task :default => :travis
|
8
|
+
|
16
9
|
task :travis => [:spec, :quality, 'coveralls:push']
|
17
10
|
|
18
11
|
desc 'Check for code quality'
|
19
|
-
task :quality => [:reek, :flog, :flay]
|
20
|
-
|
21
|
-
Coveralls::RakeTask.new
|
22
|
-
|
23
|
-
RSpec::Core::RakeTask.new
|
24
|
-
|
25
|
-
Reek::Rake::Task.new do |t|
|
26
|
-
t.fail_on_error = false
|
27
|
-
t.verbose = false
|
28
|
-
t.ruby_opts = ['-rubygems']
|
29
|
-
t.reek_opts = '--quiet'
|
30
|
-
t.source_files = ruby_source
|
31
|
-
end
|
32
|
-
|
33
|
-
desc 'Analyze for code complexity'
|
34
|
-
task :flog do
|
35
|
-
flog = Flog.new(:continue => true)
|
36
|
-
flog.flog(*ruby_source)
|
37
|
-
threshold = 28
|
38
|
-
|
39
|
-
bad_methods = flog.totals.select do |name, score|
|
40
|
-
!(/##{flog.no_method}$/ =~ name) && score > threshold
|
41
|
-
end
|
42
|
-
bad_methods.sort { |a, b| a[1] <=> b[1] }.reverse.each do |name, score|
|
43
|
-
printf "%8.1f: %s\n", score, name
|
44
|
-
end
|
45
|
-
unless bad_methods.empty?
|
46
|
-
$stderr.puts "#{bad_methods.size} methods have a complexity > #{threshold}"
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
FlayTask.new do |t|
|
51
|
-
t.dirs = ruby_source.map do |each|
|
52
|
-
each[/[^\/]+/]
|
53
|
-
end.uniq
|
54
|
-
t.threshold = 0
|
55
|
-
t.verbose = true
|
56
|
-
end
|
57
|
-
|
58
|
-
if RUBY_VERSION >= '1.9.0'
|
59
|
-
task :quality => :rubocop
|
60
|
-
require 'rubocop/rake_task'
|
61
|
-
Rubocop::RakeTask.new
|
62
|
-
end
|
63
|
-
|
64
|
-
YARD::Rake::YardocTask.new do |t|
|
65
|
-
t.options = ['--no-private']
|
66
|
-
t.options << '--debug' << '--verbose' if Rake.verbose
|
67
|
-
end
|
68
|
-
|
69
|
-
def travis_yml
|
70
|
-
File.join File.dirname(__FILE__), '.travis.yml'
|
71
|
-
end
|
72
|
-
|
73
|
-
def rubies
|
74
|
-
YAML.load_file(travis_yml)['rvm'].uniq.sort
|
75
|
-
end
|
76
|
-
|
77
|
-
def gemfile_lock
|
78
|
-
File.join File.dirname(__FILE__), 'Gemfile.lock'
|
79
|
-
end
|
80
|
-
|
81
|
-
desc 'Run tests against multiple rubies'
|
82
|
-
task :portability
|
83
|
-
|
84
|
-
rubies.each do |each|
|
85
|
-
portability_task_name = "portability:#{each}"
|
86
|
-
task :portability => portability_task_name
|
12
|
+
task :quality => [:reek, :flog, :flay, :rubocop]
|
87
13
|
|
88
|
-
|
89
|
-
task portability_task_name do
|
90
|
-
rm_f gemfile_lock
|
91
|
-
sh "rvm #{each} exec bundle update"
|
92
|
-
sh "rvm #{each} exec bundle install"
|
93
|
-
sh "rvm #{each} exec bundle exec rake"
|
94
|
-
end
|
95
|
-
end
|
14
|
+
# rubocop:enable HashSyntax
|
96
15
|
|
97
|
-
|
98
|
-
### mode: Ruby
|
99
|
-
### coding: utf-8-unix
|
100
|
-
### indent-tabs-mode: nil
|
101
|
-
### End:
|
16
|
+
Dir.glob('tasks/*.rake').each { |each| import each }
|