package golang import ( // stdlib "bytes" "io" "log" "net/http" "strings" // local "go.dev.pztrn.name/glp/configuration" "go.dev.pztrn.name/glp/httpclient" "go.dev.pztrn.name/glp/structs" ) // Gets go-import and go-source data and fill it in dependency. func getGoData(dependency *structs.Dependency) { // Dependencies are imported using URL which can be called with // "?go-get=1" parameter to obtain required VCS data. req, _ := http.NewRequest("GET", "http://"+dependency.Name, nil) q := req.URL.Query() q.Add("go-get", "1") req.URL.RawQuery = q.Encode() respBody := httpclient.GET(req) if respBody == nil { return } // HTML is hard to parse properly statically, so we will go // line-by-line for
parsing. resp := bytes.NewBuffer(respBody) var ( // This flag shows that we're currently parsing from HTML. headCurrentlyParsing bool ) for { line, err := resp.ReadString('\n') if err != nil && err != io.EOF { log.Fatalln("Failed to read HTML response line-by-line:", err.Error()) } else if err != nil && err == io.EOF { break } if headCurrentlyParsing { // Check for go-import data. if strings.Contains(line, ` 5 { log.Println("Got line: '" + line + "', but it cannot be parsed. Probably badly formed - line where meta tag is located appears to be too long. Skipping") continue } // Import line contains data like VCS name and VCS URL. // They're delimited with whitespace. importDataSplitted := strings.Split(lineSplitted[3], " ") // Import line should contain at least 3 elements. if len(importDataSplitted) < 3 { log.Println("Got line: '" + line + "', but it cannot be parsed. Probably badly formed - import data is too small. Skipping") continue } // Fill dependency data with this data. // First element is a module name and we do not actually // need it, because it is already filled previously. dependency.VCS.VCS = importDataSplitted[1] dependency.VCS.VCSPath = importDataSplitted[2] } // Check for go-source data. if strings.Contains(line, ` 5 { log.Println("Got line: '" + line + "', but it cannot be parsed. Probably badly formed - line where meta tag is located appears to be too long. Skipping") continue } // Source line contains data like VCS paths templates. // They're delimited with whitespace. sourceDataSplitted := strings.Split(lineSplitted[3], " ") // Source data line should contain at least 3 elements. if len(sourceDataSplitted) < 4 { log.Println("Got line: '" + line + "', but it cannot be parsed. Probably badly formed - source data is too small. Skipping") continue } // Fill dependency data. dependency.VCS.SourceURLDirTemplate = sourceDataSplitted[2] dependency.VCS.SourceURLFileTemplate = sourceDataSplitted[3] } } if strings.Contains(strings.ToLower(line), "") { headCurrentlyParsing = true } if strings.Contains(strings.ToLower(line), "") { headCurrentlyParsing = false } } if configuration.Cfg.Log.Debug { log.Printf("go-import and go-source data parsed: %+v\n", dependency.VCS) } }