NMEAPlus uses a very standard GitHub workflow.
- Fork the repository on github
- Generate the parser files with
rake -f parser/Rakefile
- Make your desired changes
- Push to your personal fork
- Open a pull request
Pull requests will trigger a Travis CI job. The following two commands will be expected to pass (so you may want to run them locally before opening the pull request):
rubocop -D
- code style testsrspec
- functional tests
Be prepared to write tests to accompany any code you would like to see merged.
A very trivial parser extracts the message type and checksum information, passing them directly to a message factory class. The factory classes read the data type and instantiate the appropriate object through reflection.
The classes are by default named after the message types they support. However, NMEA supports so-called "Standard Sentences" -- talker-independent commands -- which need to be attempted if a given message class does not exist. These can be configured in the self.alternate_data_type
method of a message factory subclass.
Message classes are given the message prefix (e.g. "$"), payload (string of comma-separated fields), and checksum string (without the *
). They are also given the "interpreted data type" -- the possible alternate data type produced above. Messages immediately split the payload on the commas, and any subclasses of messages should expose those fields as proper data types with proper names.
A similar pattern applies to the parsing of AIS message payloads.
Let's say we've defined a new NMEA message called MYMSG and want our parser to properly parse it.
- Edit
lib/nmea_plus/message/nmea/mymsg.rb
- Stub it out as follows:
require 'nmea_plus/message/nmea/base_nmea'
module NMEAPlus
module Message
module NMEA
class MYMSG < NMEAPlus::Message::NMEA::NMEAMessage
end
end
end
end
- Add
require 'nmea_plus/message/nmea/mymsg'
tolib/nmea_plus/nmea_message_factory.rb
- Add tests in
spec/parser_spec.rb
- Add accessor methods in NMEAPlus::Message::NMEA::MYMSG, and appropriate tests.
The following metaprogramming feature has been added to facilitate this:
field_reader :my_field, 2, :_integer
# this is equivalent to the following:
def my_field
_integer(@fields[2])
end
Let's say we've defined a new AIS VDM message type 28 and want our decoder to properly decode it.
- Edit
lib/nmea_plus/message/ais/vdm_payload/vdm_msg28.rb
- Stub it out as follows:
require 'nmea_plus/message/ais/vdm_payload/vdm_msg'
module NMEAPlus
module Message
module AIS
module VDMPayload
class VDMMsg28 < NMEAPlus::Message::AIS::VDMPayload::VDMMsg
end
end
end
end
end
- Add
require 'nmea_plus/message/ais/vdm_payload/vdm_msg28'
tolib/nmea_plus/message/ais/vdm.rb
- Add tests in
spec/ais_spec.rb
The following metaprogramming feature has been added to facilitate this:
payload_reader :my_field, 11, 22, :_I, 33, 44
# this is equivalent to the following:
def my_field
# let v = the 22 bits starting from field 11
# format v using _I() with arguments 33 and 44
# based on our convention, this means that if 44 == _I(args), return nil
end
Let's say we've defined a new binary payload type for AIS VDM message type 6 and want our decoder to properly decode it. This message type uses DAC 333 and FID 444
- Edit
lib/nmea_plus/message/ais/vdm_payload/vdm_msg6d333f444.rb
- Stub it out as follows:
require 'nmea_plus/message/ais/vdm_payload/vdm_msg6_dynamic_payload' # or msg8 as appropriate
module NMEAPlus
module Message
module AIS
module VDMPayload
class VDMMsg6d333f444 < NMEAPlus::Message::AIS::VDMPayload::VDMMsg6DynamicPayload
end
end
end
end
end
- Add
require 'nmea_plus/message/ais/vdm_payload/vdm_msg6d235f10'
tolib/nmea_plus/message/ais/vdm_msg6.rb
- Add tests in
spec/ais_spec.rb
The same metaprogramming feature (payload_reader
) is available, and the bit offsets still work from the beginning of the message.
- Merge pull request with new features and changelog entries (in "Unreleased")
git stash save
(at least before the gem build step, but easiest here).git pull --rebase
rake -f parser/Rakefile
- Bump the version in
lib/nmea_plus/version.rb
and change it inREADME.md
(since rubydoc.info doesn't always redirect to the latest version). - Create a new
CHANGELOG.md
section for the release and restore the "Unreleased" section at the top to be blank. Don't forget the version comparison links at the bottom. git add README.md CHANGELOG.md lib/nmea_plus/version.rb
git commit -m "vVERSION bump"
git tag -a vVERSION -m "Released version VERSION"
gem build nmea_plus.gemspec
git stash pop
gem push nmea_plus-VERSION.gem
git push upstream
git push upstream --tags
- Visit http://www.rubydoc.info/gems/nmea_plus/VERSION to initiate the doc generation process