package handler import ( "encoding/json" "fmt" "gosimplenpm/serviceidos" "gosimplenpm/storage" "net/http" "net/url" "path" "strings" "github.com/gorilla/mux" ) type NPMClientPutRequest struct { Request serviceidos.IndexJson } func Publish(w http.ResponseWriter, r *http.Request) { // (1) Parse Json Body // (2) Check if package exists in the folder. // (a) if it does, ckeck if it is the same version. If it is, return error. Else modify index.json from (2) // (b) If it does not, add the latest tag to the new index.json escapedName := mux.Vars(r)["name"] packageName, _ := url.PathUnescape(escapedName) fmt.Printf("Package name => %s\n", packageName) var cr NPMClientPutRequest // Parse json body err := json.NewDecoder(r.Body).Decode(&cr.Request) if err != nil { fmt.Printf("Error unmarshaling put request: %+v\n", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } // Extract relevant data from index.json index := 0 var tag string var version string var versionData serviceidos.IndexJsonVersions // TODO: Fix this as the order is not guaranteed for key, value := range cr.Request.DistTags { if index == 0 { tag = key version = value break } index++ } versionData = cr.Request.Versions[version] fmt.Printf("For version(%s) with tag(%s), versionData => %+v\n", version, tag, versionData) // Rewrite the tarball path tarballFileName := strings.Split(versionData.Dist.Tarball, "/-/")[1] fmt.Printf("TarballName => %s\n", tarballFileName) // versionData.Dist.Tarball = fmt.Sprintf("file://%s", packageFilePath) versionData.Dist.Tarball = fmt.Sprintf("http://%s/%s/-/%s", r.Host, url.PathEscape(packageName), url.PathEscape(tarballFileName)) fmt.Printf("versionData.Dist.Tarball => %s\n", versionData.Dist.Tarball) registryPath, _ := storage.GetRegistryPath() tarBallFile := strings.Split(tarballFileName, "/")[1] packageFilePath := path.Join(registryPath, packageName, tarBallFile) // Try to get the index.json from the store fileToServe, found, err := storage.GetIndexJsonFromStore(packageName) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } var jsonFile serviceidos.IndexJson if !found { // new package jsonFile = cr.Request jsonFile.DistTags["latest"] = version } else { // old package err = storage.ReadIndexJson(fileToServe, &jsonFile) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Checking that you are not publishing over a pervious published version if jsonFile.Versions[version].Version == version { fmt.Printf("Version %s of package %s already exists!!\n", version, packageName) http.Error(w, err.Error(), http.StatusBadRequest) return } // Rewrite attachments jsonFile.DistTags[tag] = version nAttachments := make(map[string]serviceidos.IndexJsonAttachments) nAttachments[fmt.Sprintf("%s-%s.tgz", packageName, version)] = cr.Request.Attachments[fmt.Sprintf("%s-%s.tgz", packageName, version)] jsonFile.Attachments = nAttachments // Merge in the new version data jsonFile.Versions[version] = versionData } fmt.Println("FiletoServe ==> ", fileToServe) // Write index.json err = storage.WriteIndexJson(fileToServe, &jsonFile) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } fmt.Println("Package path => ", packageFilePath) // Write bundled package packageData := jsonFile.Attachments[fmt.Sprintf("%s-%s.tgz", packageName, version)].Data err = storage.WritePackageToStore(packageFilePath, packageData) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } }