diff --git a/README.md b/README.md index e0b3d50..e7b0a41 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ See `kitchen_sink.sh` examples. # Current Status - - [ ] Change message templates to render headers in this order: `author`, `prev`, `lipmaa`, `depth`, `kind`. + - [ ] Enforce canonical header ordering: `author`, `prev`, `lipmaa`, `depth`, `kind`. - [ ] Change `@`, `%`, `&` to `feed.`, `mesg.`, `blob.`, respectively. Better readability, easier onboarding, URL friendly. - [ ] Update Dev docs in protocol spec to reflect changes to `lipmaa` header. - [ ] Update spec document CLI usage examples to reflect API changes in 2020. diff --git a/lib/pigeon.rb b/lib/pigeon.rb index 45cab7a..418418f 100644 --- a/lib/pigeon.rb +++ b/lib/pigeon.rb @@ -13,7 +13,13 @@ module Pigeon DEFAULT_BLOB_DIR = File.join(Dir.home, "pigeon_sha256") MESSAGE_FILE = "messages.pgn" # MESSAGE TEMPLATE CONSTANTS: - HEADER_TPL = "author <%= author %>\nkind <%= kind %>\nprev <%= prev %>\ndepth <%= depth %>\nlipmaa <%= lipmaa %>\n\n" + HEADER_TPL = [ + "author <%= author %>", + "depth <%= depth %>", + "kind <%= kind %>", + "lipmaa <%= lipmaa %>\n\n", + "prev <%= prev %>", + ].join("\n") BODY_TPL = "<% body.to_a.each do |k, v| %><%= k %>:<%= v %><%= \"\\n\" %><% end %>\n" FOOTER_TPL = "signature <%= signature %>" COMPLETE_TPL = [HEADER_TPL, BODY_TPL, FOOTER_TPL].join("") diff --git a/lib/pigeon/lexer.rb b/lib/pigeon/lexer.rb index b6f3096..688707f 100644 --- a/lib/pigeon/lexer.rb +++ b/lib/pigeon/lexer.rb @@ -94,7 +94,6 @@ module Pigeon raise LexError, msg end - # This might be a mistake or uneccessary. NN 20 MAR 2020 def maybe_end_message! if tokens.last.last != :MESSAGE_DELIM @tokens << [:MESSAGE_DELIM, scanner.pos] @@ -102,46 +101,66 @@ module Pigeon end end + CANONICAL_ORDERING = { + # Current Key => Allowed previous keys + AUTHOR: [:FOOTER_SEPERATOR, :START], + DEPTH: [:AUTHOR], + KIND: [:DEPTH], + LIPMAA: [:KIND], + PREV: [:LIPMAA], + HEADER_SEPERATOR: [:PREV], + } + + def check_header_order(current) + expected = CANONICAL_ORDERING.fetch(current) + if expected.include?(@last_good) + @last_good = current + else + msg = "BAD HEADER ORDERING. Expected: #{expected.join(" OR ")}. Got: #{current}" + raise msg + end + end + def do_header if scanner.scan(AUTHOR) author = scanner.matched.chomp.gsub("author ", "") @tokens << [:AUTHOR, author, scanner.pos] - @last_good = :AUTHOR + check_header_order(:AUTHOR) return end if scanner.scan(DEPTH) depth = scanner.matched.chomp.gsub("depth ", "").to_i @tokens << [:DEPTH, depth, scanner.pos] - @last_good = :DEPTH + check_header_order(:DEPTH) return end if scanner.scan(LIPMAA) depth = scanner.matched.chomp.gsub("lipmaa ", "") @tokens << [:LIPMAA, depth, scanner.pos] - @last_good = :LIPMAA + check_header_order(:LIPMAA) return end if scanner.scan(PREV) prev = scanner.matched.chomp.gsub("prev ", "") @tokens << [:PREV, prev, scanner.pos] - @last_good = :PREV + check_header_order(:PREV) return end if scanner.scan(KIND) kind = scanner.matched.chomp.gsub("kind ", "") @tokens << [:KIND, kind, scanner.pos] - @last_good = :KIND + check_header_order(:KIND) return end if scanner.scan(SEPERATOR) @state = BODY @tokens << [:HEADER_END, scanner.pos] - @last_good = :HEADER_SEPERATOR + check_header_order(:HEADER_SEPERATOR) return end diff --git a/spec/pigeon/bundle_spec.rb b/spec/pigeon/bundle_spec.rb index b0d382a..45e684e 100644 --- a/spec/pigeon/bundle_spec.rb +++ b/spec/pigeon/bundle_spec.rb @@ -2,7 +2,6 @@ require "spec_helper" RSpec.describe Pigeon::Message do before(:each) do - puts "WARNING: This test deletes the blob dir! Fix ASAP" `rm -rf #{Pigeon::DEFAULT_BLOB_DIR}` p = Pigeon::DEFAULT_BUNDLE_PATH File.delete(p) if File.file?(p)