()
| 87 | } |
| 88 | |
| 89 | func (s *Session) handleRequests() error { |
| 90 | done := make(chan struct{}) |
| 91 | defer close(done) |
| 92 | requests := s.requestReader(done) |
| 93 | planned := false |
| 94 | for req := range requests { |
| 95 | if req.GetCancel() != nil { |
| 96 | s.Logger.Warn(s.Context(), "ignoring cancel before request or after complete") |
| 97 | continue |
| 98 | } |
| 99 | resp := &proto.Response{} |
| 100 | if parse := req.GetParse(); parse != nil { |
| 101 | if !s.initialized { |
| 102 | // Files must be initialized before parsing. |
| 103 | return xerrors.New("cannot parse before successful init") |
| 104 | } |
| 105 | r := &request[*proto.ParseRequest, *proto.ParseComplete]{ |
| 106 | req: parse, |
| 107 | session: s, |
| 108 | serverFn: s.server.Parse, |
| 109 | cancels: requests, |
| 110 | } |
| 111 | complete, err := r.do() |
| 112 | if err != nil { |
| 113 | return err |
| 114 | } |
| 115 | // Handle README centrally, so that individual provisioners don't need to mess with it. |
| 116 | readme, err := os.ReadFile(s.Files.ReadmeFilePath()) |
| 117 | if err == nil { |
| 118 | complete.Readme = readme |
| 119 | } else { |
| 120 | s.Logger.Debug(s.Context(), "failed to parse readme (missing ok)", slog.Error(err)) |
| 121 | } |
| 122 | resp.Type = &proto.Response_Parse{Parse: complete} |
| 123 | } |
| 124 | if init := req.GetInit(); init != nil { |
| 125 | if s.initialized { |
| 126 | return xerrors.New("cannot init more than once per session") |
| 127 | } |
| 128 | |
| 129 | initResp, err := s.handleInitRequest(init, requests) |
| 130 | if err != nil { |
| 131 | return err |
| 132 | } |
| 133 | resp.Type = &proto.Response_Init{Init: initResp} |
| 134 | } |
| 135 | if plan := req.GetPlan(); plan != nil { |
| 136 | if !s.initialized { |
| 137 | return xerrors.New("cannot plan before successful init") |
| 138 | } |
| 139 | planResp, err := s.handlePlanRequest(plan, requests) |
| 140 | if err != nil { |
| 141 | return err |
| 142 | } |
| 143 | if planResp.Error == "" { |
| 144 | planned = true |
| 145 | } |
| 146 | resp.Type = &proto.Response_Plan{Plan: planResp} |
no test coverage detected