diff --git a/README.md b/README.md index 42aa62c83..6b0c40a79 100644 --- a/README.md +++ b/README.md @@ -25,4 +25,8 @@ gpm(Go Package Manager) is a Go package manage tool for search, install, update - Add support for downloading by tag for packages in github.com, bitbucket.org, git.oschina.net, gitcafe.com. - Get author commit time and save in node. - Collect download and installation results and report to users in the end. -- Command `install` add support for downloading code from git.oschina.net, gitcafe.com, *.codeplex.com; \ No newline at end of file +- Command `install` add support for downloading code from git.oschina.net, gitcafe.com, *.codeplex.com; +- Command `check` is for checking and downloading all missing dependencies. +- Command `daemon` is for auto-compile web applications when debug it locally. +- Command `update` is for checking updates. +- Command `remove` is for removing packages. \ No newline at end of file diff --git a/conf/gpm.toml b/conf/gpm.toml index 6cf9be447..2f893c1d8 100644 --- a/conf/gpm.toml +++ b/conf/gpm.toml @@ -1,7 +1,7 @@ # This is a configuration file for gpm with toml format. title = "gpm(Go Package Manager)" -version = "v0.1.0 Build 0521" +version = "v0.1.1 Build 0521" username = "" password = "" user_language = "en-US" \ No newline at end of file diff --git a/doc/struct.go b/doc/struct.go index 5df542dbf..55c5beead 100644 --- a/doc/struct.go +++ b/doc/struct.go @@ -10,13 +10,22 @@ import ( "time" ) -// Node represents a node structure. +// Node represents a node. type Node struct { ImportPath string `json:"import_path"` Commit string Date string } +// Bundle represents a bundle. +type Bundle struct { + Id int64 + UserId int64 `json:"user_id"` + Name string `json:"bundle_name"` + Comment string + Nodes []*Node +} + // source is source code file. type source struct { rawURL string diff --git a/gpm.go b/gpm.go index d96bf368e..45135258e 100644 --- a/gpm.go +++ b/gpm.go @@ -26,9 +26,10 @@ import ( ) var ( - config tomlConfig - appPath string // Application path. - localNodes []*doc.Node + config tomlConfig + appPath string // Application path. + localNodes []*doc.Node + localBundles []*doc.Bundle ) type tomlConfig struct { @@ -164,6 +165,49 @@ func loadLocalNodes() bool { return true } +// loadLocalBundles loads bundles from local file system. +func loadLocalBundles() bool { + // Find all bundles. + dir, err := os.Open(appPath + "repo/bundles/") + if err != nil { + fmt.Println(err) + return false + } + defer dir.Close() + + fis, err := dir.Readdir(0) + if err != nil { + fmt.Println(err) + return false + } + + for _, fi := range fis { + // In case this folder contains unexpected directories. + if !fi.IsDir() { + fr, err := os.Open(appPath + "repo/bundles/" + fi.Name()) + if err != nil { + fmt.Println(err) + return false + } + + bundle := new(doc.Bundle) + err = json.NewDecoder(fr).Decode(bundle) + fr.Close() + if err != nil && err != io.EOF { + fmt.Println(err) + return false + } + + // Make sure bundle name is not empty. + if len(bundle.Name) == 0 { + bundle.Name = fi.Name()[:strings.Index(fi.Name(), ".")] + } + localBundles = append(localBundles, bundle) + } + } + return true +} + // We don't use init() to initialize // bacause we need to get execute path in runtime. func initialize() bool { @@ -187,8 +231,8 @@ func initialize() bool { os.MkdirAll(appPath+"repo/bundles/", os.ModePerm) os.MkdirAll(appPath+"repo/snapshots/", os.ModePerm) - // Initialize local nodes. - if !loadLocalNodes() { + // Initialize local data. + if !loadLocalNodes() || !loadLocalBundles() { return false } diff --git a/install.go b/install.go index 59540efd7..e48f1919e 100644 --- a/install.go +++ b/install.go @@ -143,6 +143,25 @@ func runInstall(cmd *Command, args []string) { fmt.Println("Well done.") } +// checkLocalBundles checks if the bundle is in local file system. +func checkLocalBundles(bundle string) (pkgs, commits []string) { + for _, b := range localBundles { + if bundle == b.Name { + for _, n := range b.Nodes { + pkgs = append(pkgs, n.ImportPath) + // Make sure it will not download all dependencies automatically. + if len(n.Commit) == 0 { + commits = append(commits, "B") + } else { + commits = append(commits, n.Commit) + } + } + return pkgs, commits + } + } + return nil, nil +} + // downloadPackages downloads packages with certain commit, // if the commit is empty string, then it downloads all dependencies, // otherwise, it only downloada package with specific commit only. @@ -152,7 +171,26 @@ func downloadPackages(pkgs, commits []string) { // Check if it is a bundle or snapshot. switch { case p[0] == 'B': - // TODO: api.GetBundleInfo() + // Check local bundles. + bpkgs, bcommits := checkLocalBundles(p[1:]) + if len(bpkgs) > 0 { + // Check with users if continue. + fmt.Printf("Bundle(%s) contains following nodes:\n", p[1:]) + for i := range bpkgs { + fmt.Printf("import path: %s, commit: %s.\n", bpkgs[i], bcommits[i]) + } + fmt.Print("Continue download?(Y/n).") + var option string + fmt.Fscan(os.Stdin, &option) + if strings.ToLower(option) != "y" { + os.Exit(0) + } + downloadPackages(bpkgs, bcommits) + } else { + // Check from server. + // TODO: api.GetBundleInfo() + fmt.Println("Unable to check with server right now.") + } case p[0] == 'S': // TODO: api.GetSnapshotInfo() case utils.IsValidRemotePath(p):