@@ -30,7 +30,7 @@ else | |||||
fi | fi | ||||
echo "running format validation..." | echo "running format validation..." | ||||
./validate_format.rb $FORMAT_FILE | |||||
./validate_format.py $FORMAT_FILE | |||||
if [[ $? != 0 ]]; then | if [[ $? != 0 ]]; then | ||||
echo "format validation failed!" | echo "format validation failed!" | ||||
exit 1 | exit 1 | ||||
@@ -0,0 +1,111 @@ | |||||
#!/usr/bin/env python3 | |||||
import json | |||||
import string | |||||
import sys | |||||
anchor = '###' | |||||
auth_keys = ['apiKey', 'OAuth', 'X-Mashape-Key', 'No'] | |||||
punctuation = ['.', '?', '!'] | |||||
https_keys = ['Yes', 'No'] | |||||
index_title = 0 | |||||
index_desc = 1 | |||||
index_auth = 2 | |||||
index_https = 3 | |||||
index_link = 4 | |||||
errors = [] | |||||
def add_error(line_num, message): | |||||
"""adds an error to the dynamic error list""" | |||||
err = '(L{:03d}) {}'.format(line_num+1, message) | |||||
errors.append(err) | |||||
def check_format(filename): | |||||
""" | |||||
validates that each line is formatted correctly, | |||||
appending to error list as needed | |||||
""" | |||||
with open(filename) as fp: | |||||
lines = list(line.rstrip() for line in fp) | |||||
# START Alphabetical Order | |||||
category = "" | |||||
sections = {} | |||||
section_line_num = {} | |||||
for line_num, line in enumerate(lines): | |||||
if line.startswith(anchor): | |||||
category = line.split(anchor)[1].strip() | |||||
sections[category] = [] | |||||
section_line_num[category] = line_num | |||||
continue | |||||
if not line.startswith('|') or line.startswith('|---'): | |||||
continue | |||||
title = [x.strip() for x in line.split('|')[1:-1]][0].upper() | |||||
sections[category].append(title) | |||||
for category, entries in sections.items(): | |||||
if sorted(entries) != entries: | |||||
add_error(section_line_num[category], '{} section is not in alphabetical order'.format(category)) | |||||
# END Alphabetical Order | |||||
# START Check Entries | |||||
for line_num, line in enumerate(lines): | |||||
if not line.startswith('|') or line.startswith('|---'): | |||||
continue | |||||
segments = line.split('|')[1:-1] | |||||
# START Global | |||||
for segment in segments: | |||||
# every line segment should start and end with exactly 1 space | |||||
if len(segment) - len(segment.lstrip()) != 1 or len(segment) - len(segment.rstrip()) != 1: | |||||
add_error(line_num, "each segment must start and end with exactly 1 space") | |||||
# END Global | |||||
segments = [seg.strip() for seg in segments] | |||||
# START Description | |||||
# first character should be capitalized | |||||
char = segments[index_desc][0] | |||||
if char.upper() != char: | |||||
add_error(line_num, "first char of Description is not capitalized") | |||||
# last character should not punctuation | |||||
char = segments[index_desc][-1] | |||||
if char in punctuation: | |||||
add_error(line_num, "description should not end with {}".format(char)) | |||||
# END Description | |||||
# START Auth | |||||
# values should conform to valid options only | |||||
auth = segments[index_auth].replace('`', '') | |||||
if auth not in auth_keys: | |||||
add_error(line_num, "{} is not a valid Auth option".format(auth)) | |||||
# END Auth | |||||
# START HTTPS | |||||
# values should conform to valid options only | |||||
https = segments[index_https] | |||||
if https not in https_keys: | |||||
add_error(line_num, "{} is not a valid HTTPS option".format(https)) | |||||
# END HTTPS | |||||
# START Link | |||||
# url should be wrapped in '[Go!]()' Markdown syntax | |||||
link = segments[index_link] | |||||
if not link.startswith('[Go!](') or not link.endswith(')'): | |||||
add_error(line_num, 'link format should be "[Go!](LINK)"') | |||||
# END Link | |||||
# END Check Entries | |||||
def main(): | |||||
num_args = len(sys.argv) | |||||
if num_args < 2: | |||||
print("No .md file passed") | |||||
sys.exit(1) | |||||
check_format(sys.argv[1]) | |||||
if len(errors) > 0: | |||||
for err in errors: | |||||
print(err) | |||||
sys.exit(1) | |||||
if __name__ == "__main__": | |||||
main() |
@@ -1,111 +0,0 @@ | |||||
#!/usr/bin/env ruby | |||||
auth_keys = ['apiKey', 'OAuth', 'X-Mashape-Key', 'No'] | |||||
punctuation = ['.', '?', '!'] | |||||
https_keys = ['Yes', 'No'] | |||||
INDEX_TITLE = 1 | |||||
INDEX_DESCRIPTION = 2 | |||||
INDEX_AUTH = 3 | |||||
INDEX_HTTPS = 4 | |||||
INDEX_LINK = 5 | |||||
filename = ARGV[0] | |||||
$errors = [] | |||||
def add_error(line_num, val_index, message) | |||||
case val_index | |||||
when INDEX_TITLE | |||||
segment = "Title" | |||||
when INDEX_DESCRIPTION | |||||
segment = "Description" | |||||
when INDEX_AUTH | |||||
segment = "Auth" | |||||
when INDEX_HTTPS | |||||
segment = "HTTPS" | |||||
when INDEX_LINK | |||||
segment = "Link" | |||||
end | |||||
$errors.push("(L%03d) %-14.14s #{message}" % [line_num, segment]) | |||||
end | |||||
################### CHECK ALPHABETICAL ORDER ################### | |||||
section = '' | |||||
sections = [] | |||||
section_to_line_num = {} | |||||
section_to_entries = Hash.new {|h,k| h[k] = Array.new } | |||||
File.foreach(filename).with_index do | line, line_num | | |||||
if line.start_with?('###') | |||||
section = line.sub('###', '').lstrip.chop | |||||
sections.push(section) | |||||
section_to_line_num[section] = line_num + 1 | |||||
end | |||||
# Skip non-markdown table lines and table schema lines | |||||
if !line.start_with?('|') || line.eql?("|---|---|---|---|---|\n") | |||||
next | |||||
end | |||||
# char to check is the first column | |||||
check_char = line.split("|")[1].strip.upcase | |||||
section_to_entries[section].push(check_char) | |||||
end | |||||
sections.each do | sect | | |||||
if section_to_entries[sect] != section_to_entries[sect].sort | |||||
add_error(section_to_line_num[sect], INDEX_TITLE, "#{sect} section is not in alphabetical order") | |||||
end | |||||
end | |||||
#################### CHECK LINE ENTRIES ######################## | |||||
File.foreach(filename).with_index do | line, line_num | | |||||
line_num += 1 | |||||
# Skip non-markdown table lines and table schema lines | |||||
if !line.start_with?('|') || line.eql?("|---|---|---|---|---|\n") | |||||
next | |||||
end | |||||
values = line.split("|") | |||||
################### GLOBAL ################### | |||||
values.each.with_index do |val, val_index| | |||||
msg = "" | |||||
case val_index | |||||
when INDEX_TITLE..INDEX_LINK | |||||
# every line segment should start and end with exactly 1 space | |||||
if val[/\A */].size != 1 || val[/ *\z/].size != 1 | |||||
add_error(line_num, val_index, "string should start and end with exactly 1 space") | |||||
end | |||||
end | |||||
end | |||||
################# DESCRIPTION ################ | |||||
# First character should be capitalized | |||||
desc_val = values[INDEX_DESCRIPTION].lstrip.chop | |||||
if !/[[:upper:]]/.match(desc_val[0]) | |||||
add_error(line_num, INDEX_DESCRIPTION, "first char not uppercase") | |||||
end | |||||
# value should not be punctuated | |||||
last_char = desc_val[desc_val.length-1] | |||||
if punctuation.include?(last_char) | |||||
add_error(line_num, INDEX_DESCRIPTION, "description should not end with \"#{last_char}\"") | |||||
end | |||||
#################### AUTH #################### | |||||
# Values should conform to valid options only | |||||
auth_val = values[INDEX_AUTH].lstrip.chop.tr('``', '') | |||||
if !auth_keys.include?(auth_val) | |||||
add_error(line_num, INDEX_AUTH, "not a valid option: #{auth_val}") | |||||
end | |||||
#################### HTTPS ################### | |||||
# Values should be either "Yes" or "No" | |||||
https_val = values[INDEX_HTTPS].lstrip.chop | |||||
if !https_keys.include?(https_val) | |||||
add_error(line_num, INDEX_HTTPS, "must use \"Yes\" or \"No\": #{https_val}") | |||||
end | |||||
#################### LINK #################### | |||||
# Url should be wrapped in "[Go!]" view | |||||
link_val = values[INDEX_LINK].lstrip.chop | |||||
if !link_val.start_with?("[Go!](") || !link_val.end_with?(')') | |||||
add_error(line_num, INDEX_LINK, "format should be \"[Go!](<LINK>)\": #{link_val}") | |||||
end | |||||
end | |||||
$errors.each do | e | | |||||
puts e | |||||
end | |||||
exit($errors.length) |