github.com/googlecloudplatform/kubernetes-workshops@v0.0.0-20180501174420-d8199445b2c3/test/parser.go (about) 1 // Copyright 2016 Google, Inc 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package main 15 16 import ( 17 "bufio" 18 "errors" 19 "io" 20 "strings" 21 ) 22 23 // An Action is one instance of a START/END tag pair. ActionType is 24 // the word following START. Lines are the lines between the tags. 25 type Action struct { 26 ActionType string 27 Lines []string 28 closed bool 29 } 30 31 type stateFn func(string, *[]Action) (stateFn, error) 32 33 func neutralState(line string, actions *[]Action) (stateFn, error) { 34 words := strings.Fields(line) 35 for index, word := range words { 36 if word == "END" { 37 return nil, errors.New("Unexpected END tag outside action") 38 } 39 if word == "START" { 40 action := words[index+1] 41 newAction(action, actions) 42 return insideActionState, nil 43 } 44 } 45 return neutralState, nil 46 } 47 48 func insideActionState(line string, actions *[]Action) (stateFn, error) { 49 words := strings.Fields(line) 50 if strings.HasPrefix(line, "```") || words[0] == "```" { 51 // Ignore line. 52 return insideActionState, nil 53 } 54 for _, word := range words { 55 if word == "END" { 56 closeAction(*actions) 57 return neutralState, nil 58 } 59 if word == "START" { 60 return nil, errors.New("Unexpected START tag inside action") 61 } 62 } 63 actionLine(line, *actions) 64 return insideActionState, nil 65 } 66 67 func newAction(aType string, actions *[]Action) { 68 aa := Action{ 69 ActionType: aType, 70 Lines: make([]string, 0), 71 closed: false, 72 } 73 *actions = append(*actions, aa) 74 } 75 76 func actionLine(line string, actions []Action) { 77 actions[len(actions)-1].Lines = 78 append(actions[len(actions)-1].Lines, line) 79 } 80 81 func closeAction(actions []Action) { 82 actions[len(actions)-1].closed = true 83 } 84 85 // GetActions parses the input for START/END tags and compiles a list 86 // of actions, comprising of the lines between the lines with 87 // START/END. Lines that begin with ``` are ignored. The word 88 // immediately after START is saved as the action type. 89 func GetActions(reader io.Reader) ([]Action, error) { 90 scanner := bufio.NewScanner(reader) 91 actions := make([]Action, 0) 92 93 for state := neutralState; scanner.Scan(); { 94 var err error 95 state, err = state(scanner.Text(), &actions) 96 if err != nil { 97 return nil, err 98 } 99 } 100 if err := scanner.Err(); err != nil { 101 return nil, err 102 } 103 104 return actions, nil 105 }