// ResolveJar get jar from 1. jar directory, 2. local repository, 3. maven repository // then set jar into jar directory and return jar path func (r *JarResolver) ResolveJar(artifact *Artifact) (string, error) { utils.Log("info", fmt.Sprintf("Resolve jar: %+v", artifact)) // jar directory jarPath, jarDirErr := r.JarDir.FindJarArtifact(artifact) if jarDirErr == nil { return jarPath, nil } utils.Log("debug", fmt.Sprintf("Could not find jar in jar directory: %+v", r.JarDir)) // local repository path, localRepoErr := r.LocalRepo.FindJarArtifact(artifact) if localRepoErr == nil { // copy from local repo to jar directory if jarPath, err := r.JarDir.CopyFile(path, artifact.JarFileName()); err == nil { return jarPath, nil } } utils.Log("debug", fmt.Sprintf("Could not find jar in local repository: %+v", r.LocalRepo)) // maven repository content, mavenRepoErr := r.MavenRepo.DownloadJarArtifact(artifact) if mavenRepoErr == nil { return r.JarDir.WriteFile(content, artifact.JarFileName()) } utils.Log("debug", fmt.Sprintf("Could not find jar in maven repository: %+v", r.MavenRepo)) return "", fmt.Errorf("Failed to resolve jar : [%v,%v,%v]", jarDirErr, localRepoErr, mavenRepoErr) }
// FindJarArtifact get artifact file path in local storage func (d *JarDirectory) FindJarArtifact(artifact *Artifact) (string, error) { utils.Log("info", fmt.Sprintf("Try to find jar in jar directory: %+v", artifact)) path := fmt.Sprintf("%s/%s", d.Dir, artifact.JarFileName()) _, err := os.Stat(path) if os.IsNotExist(err) { return "", fmt.Errorf("Could not find jar in jar directory") } utils.Log("info", fmt.Sprintf("Found jar in jar directory: %s", path)) return path, nil }
// FindJarArtifact get artifact file path in local storage func (r *LocalRepository) FindJarArtifact(artifact *Artifact) (string, error) { path := fmt.Sprintf("%s/%s/%s/%s/%s", r.Dir, artifact.GroupIDPath(), artifact.Name, artifact.Version, artifact.JarFileName()) utils.Log("info", fmt.Sprintf("Try to find jar in local repository: %s", path)) _, err := os.Stat(path) if os.IsNotExist(err) { return "", fmt.Errorf("Could not find local jar") } utils.Log("info", fmt.Sprintf("Found jar in local repository: %s", path)) return path, nil }
// CopyFile copy path file to jar directory file func (d *JarDirectory) CopyFile(path, filename string) (string, error) { utils.Log("info", fmt.Sprintf("Copy file in jar directory: from %s", path)) data, err := ioutil.ReadFile(path) if err != nil { return "", err } return d.WriteFile(data, filename) }
// WriteFile write data in jar directory file func (d *JarDirectory) WriteFile(data []byte, filename string) (string, error) { path := fmt.Sprintf("%s/%s", d.Dir, filename) utils.Log("info", fmt.Sprintf("Write file in jar directory: %s", path)) if err := ioutil.WriteFile(path, data, 0644); err != nil { return "", err } return path, nil }
// LatestVersion find latest version of the artifact func (r *MavenRepository) LatestVersion(artifact *Artifact) (version string, err error) { metadataURL := fmt.Sprintf("%s/maven-metadata.xml", r.artifactURLBase(artifact)) utils.Log("info", fmt.Sprintf("Search latest version to %s: %+v", metadataURL, artifact)) content, err := ValidateDownload(metadataURL) if err != nil { return "", err } xmlPath := xmlpath.MustCompile(`/metadata/versioning/latest`) root, err := xmlpath.Parse(bytes.NewReader(content)) if err != nil { return "", err } if latestVersion, ok := xmlPath.String(root); ok { utils.Log("info", fmt.Sprintf("Found latest version: %s", latestVersion)) return latestVersion, nil } return "", fmt.Errorf("Could not find latest version in %s", metadataURL) }
func download(url string) ([]byte, error) { utils.Log("debug", fmt.Sprintf("Try to download file: %s", url)) resp, err := http.Get(url) if err != nil { return []byte{}, err } defer resp.Body.Close() return ioutil.ReadAll(resp.Body) }
// ValidateDownload try to download file and validate checksum func ValidateDownload(url string) ([]byte, error) { utils.Log("info", fmt.Sprintf("Validate checksum: %s", url)) contents, err := download(url) if err != nil { return []byte{}, err } md5URL := url + ".md5" if md5Response, err := download(md5URL); err == nil { md5Checksum := md5.Sum(contents) if hex.EncodeToString(md5Checksum[:]) == string(md5Response) { return contents, nil } utils.Log("debug", fmt.Sprintf("Failed to validate md5 checksum: actual=%s, expected=%s", hex.EncodeToString(md5Checksum[:]), string(md5Response))) } sha1URL := url + ".sha1" if sha1Response, err := download(sha1URL); err == nil { sha1Checksum := sha1.Sum(contents) if hex.EncodeToString(sha1Checksum[:]) == string(sha1Response) { return contents, nil } utils.Log("debug", fmt.Sprintf("Failed to validate sha1 checksum: actual=%s, expected=%s", hex.EncodeToString(sha1Checksum[:]), string(sha1Response))) } return []byte{}, fmt.Errorf("Checksum validation failed for %s", url) }
// DownloadJarArtifact try to download jar artifact into outputDir func (r *MavenRepository) DownloadJarArtifact(artifact *Artifact) ([]byte, error) { url := fmt.Sprintf("%s/%s/%s", r.artifactURLBase(artifact), artifact.Version, artifact.JarFileName()) utils.Log("info", fmt.Sprintf("Try to download jar: %s", url)) return ValidateDownload(url) }
// Run generates a new cli project. It returns exit code func (c *JarCommand) Run(args []string) int { // options var ( groupID string artifactName string version string option string argument string jarDirectory string ) uflag := flag.NewFlagSet("jar", flag.ContinueOnError) uflag.Usage = func() { c.UI.Error(c.Help()) } uflag.StringVar(&groupID, "groupId", "", "groupId") uflag.StringVar(&groupID, "g", "", "groupId (short)") uflag.StringVar(&artifactName, "artifact", "", "artifact") uflag.StringVar(&artifactName, "a", "", "artifact (short)") uflag.StringVar(&version, "version", "", "version") uflag.StringVar(&version, "V", "", "version (short)") uflag.StringVar(&option, "option", "", "option") uflag.StringVar(&option, "o", "", "option (short)") uflag.StringVar(&argument, "argument", "", "argument") uflag.StringVar(&argument, "A", "", "argument (short)") uflag.StringVar(&jarDirectory, "jarDir", "", "jarDir") uflag.StringVar(&jarDirectory, "O", "", "jarDir (short)") errR, errW := io.Pipe() errScanner := bufio.NewScanner(errR) uflag.SetOutput(errW) go func() { for errScanner.Scan() { c.UI.Error(errScanner.Text()) } }() if err := uflag.Parse(args); err != nil { c.UI.Error("Failed to parse arguments") return ExitCodeFailed } parsedArgs := uflag.Args() if len(parsedArgs) != 0 { c.UI.Error(fmt.Sprintf("Invalid arguments: %s", strings.Join(parsedArgs, " "))) c.UI.Error(c.Help()) return ExitCodeFailed } if groupID == "" { c.UI.Error("Invalid arguments: -groupId is required") c.UI.Error(c.Help()) return ExitCodeFailed } if artifactName == "" { c.UI.Error("Invalid arguments: -artifact is required") c.UI.Error(c.Help()) return ExitCodeFailed } if jarDirectory == "" { if workDir, err := os.Getwd(); err == nil { jarDirectory = workDir } else { c.UI.Error(err.Error()) return ExitCodeFailed } } jarDir := &repository.JarDirectory{ Dir: jarDirectory, } mavenRepo := repository.NewMavenRepository() localRepo, err := repository.NewLocalRepository() if err != nil { c.UI.Error(err.Error()) return ExitCodeFailed } artifact := &repository.Artifact{ GroupID: groupID, Name: artifactName, Version: version, } if artifact.Version == "" { latestVersion, err := mavenRepo.LatestVersion(artifact) if err != nil { c.UI.Error(err.Error()) return ExitCodeFailed } artifact.Version = latestVersion } utils.Log("info", fmt.Sprintf("jarDir = %s", jarDir)) jarResolver := &repository.JarResolver{ JarDir: *jarDir, LocalRepo: *localRepo, MavenRepo: *mavenRepo, } jarPath, err := jarResolver.ResolveJar(artifact) if err != nil { c.UI.Error(err.Error()) return ExitCodeFailed } // run jar // cmd := exec.Command("java", option, "-jar", jarPath, argument) // Error: Could not find or load main class ??? command := fmt.Sprintf("java %s -jar %s %s", option, jarPath, argument) cmd := exec.Command("sh", "-c", command) utils.Log("info", fmt.Sprintf("Exec jar: sh -c %s", cmd.Args)) stdoutPipe, err := cmd.StdoutPipe() if err != nil { c.UI.Error(err.Error()) return ExitCodeFailed } defer stdoutPipe.Close() stderrPipe, err := cmd.StderrPipe() if err != nil { c.UI.Error(err.Error()) return ExitCodeFailed } defer stderrPipe.Close() go io.Copy(os.Stdout, stdoutPipe) go io.Copy(os.Stderr, stderrPipe) cmd.Run() return ExitCodeOK }