/src/igo/igo.go

https://code.google.com/ · Go · 286 lines · 257 code · 26 blank · 3 comment · 75 complexity · 416c7724db710cf01194971d5826849c MD5 · raw file

  1. package main
  2. import (
  3. "os"
  4. "fmt"
  5. "strings"
  6. "io/ioutil"
  7. "os/exec"
  8. "flag"
  9. "go/build"
  10. "path/filepath"
  11. )
  12. func ChkErr(err error) bool{
  13. if err != nil {
  14. fmt.Println("Error: ", err.Error())
  15. os.Exit(1)
  16. }
  17. return true
  18. }
  19. func igoStrSpaceSplit(str string) []string {
  20. var ret []string
  21. var bStart, bSeparator bool
  22. str = strings.TrimSpace(str)
  23. length := len(str)
  24. bStart = true
  25. for i, j:=0, 0; i<length; i++ {
  26. if (i == 0 && string(str[i]) == "'") {
  27. bSeparator = true
  28. j = 1
  29. }
  30. if !bStart {
  31. if string(str[i]) == " " {
  32. bStart = true
  33. j = i + 1
  34. if string(str[i + 1]) == "'" {
  35. bSeparator = true
  36. i ++
  37. j = i + 1
  38. }
  39. }
  40. } else {
  41. //bStart is true
  42. if bSeparator {
  43. if string(str[i]) == "'" {
  44. if (i + 1 < length && string(str[i + 1]) == " ") || (i + 1 >= length) {
  45. bSeparator = false
  46. bStart = false
  47. s := strings.TrimSpace(str[j:i])
  48. if len(s) > 0 {
  49. ret = append(ret, s)
  50. }
  51. j = i + 1
  52. }
  53. }
  54. } else {
  55. if string(str[i]) == " " {
  56. s := strings.TrimSpace(str[j:i])
  57. if len(s) > 0 {
  58. ret = append(ret, s)
  59. }
  60. j = i + 1
  61. if string(str[i + 1]) == "'" {
  62. bSeparator = true
  63. i ++
  64. j = i + 1
  65. }
  66. } else if i == length - 1 {
  67. s := strings.TrimSpace(str[j:i + 1])
  68. if len(s) > 0 {
  69. ret = append(ret, s)
  70. }
  71. }
  72. }
  73. }
  74. }
  75. return ret
  76. }
  77. func igoListPackages(path string) []string{
  78. var ret []string
  79. s := filepath.Join(path, "src")
  80. fis, err := ioutil.ReadDir(s)
  81. if err != nil {
  82. // fmt.Println("Testing: ", err.Error())
  83. return ret
  84. }
  85. for j:=0; j<len(fis); j++ {
  86. if fis[j].IsDir() {
  87. _, pkgerr := build.ScanDir(filepath.Join(s, fis[j].Name()))
  88. if pkgerr == nil {
  89. ret = append(ret, fis[j].Name())
  90. }
  91. }
  92. }
  93. return ret
  94. }
  95. const (
  96. CCONFIGFILE = "gopath.cfg"
  97. )
  98. type TGopath struct {
  99. curDir string
  100. cfgFile string
  101. gopath []string
  102. pkgs map[string][]string
  103. }
  104. func (me *TGopath) Create() {
  105. var err error
  106. me.curDir, err = os.Getwd()
  107. me.pkgs = make(map[string][]string)
  108. me.cfgFile, _ = filepath.Abs(CCONFIGFILE)
  109. ChkErr(err)
  110. }
  111. func (me *TGopath) Pwd() string {
  112. return me.curDir
  113. }
  114. func (me *TGopath) GetGopath() []string {
  115. return me.gopath
  116. }
  117. func (me *TGopath) AddPath(newPath string) {
  118. if len(newPath) == 0 {
  119. return
  120. }
  121. switch string(newPath[0]) {
  122. case "/":
  123. me.gopath = append(me.gopath, newPath)
  124. case "~":
  125. home := os.Getenv("HOME")
  126. me.gopath = append(me.gopath, filepath.Join(home, strings.TrimLeft(newPath, "~")))
  127. default:
  128. me.gopath = append(me.gopath, strings.TrimRight(me.curDir, "/") + "/" + newPath)
  129. }
  130. }
  131. func (me *TGopath) ReadGopathFromConfigFile() bool {
  132. byteFileContent, err := ioutil.ReadFile(me.cfgFile)
  133. if err != nil {
  134. return false
  135. }
  136. strFileContent := string(byteFileContent)
  137. gp := strings.Split(strFileContent, "\n")
  138. for i:=0; i<len(gp); i++ {
  139. s := strings.TrimRight(gp[i], "\r")
  140. if len(s) > 0 {
  141. me.AddPath(s)
  142. }
  143. }
  144. return true
  145. }
  146. func (me *TGopath) BuildPackageList() {
  147. for i:=0; i<len(me.gopath); i++ {
  148. me.pkgs[me.gopath[i]] = igoListPackages(me.gopath[i])
  149. }
  150. }
  151. func (me *TGopath) GetPackageListFromPath(path string) []string{
  152. return me.pkgs[path]
  153. }
  154. func (me *TGopath) AutoBuildPath() {
  155. fis, err := ioutil.ReadDir(me.curDir)
  156. ChkErr(err)
  157. for i:=0; i<len(fis); i++ {
  158. if fis[i].IsDir() {
  159. me.gopath = append(me.gopath, filepath.Join(me.curDir, fis[i].Name()))
  160. }
  161. }
  162. }
  163. type TIgo struct {
  164. gopath TGopath
  165. originGopath string
  166. bManualPath, bManualPkg bool
  167. mPkgs []string
  168. // cmd exec.Cmd
  169. Gotool string
  170. Args []string
  171. }
  172. func (me *TIgo) Create() {
  173. me.gopath.Create()
  174. me.Gotool = os.Getenv("GOBIN")
  175. if len(me.Gotool) == 0 {
  176. me.Gotool = os.Getenv("GOROOT")
  177. if len(me.Gotool) == 0 {
  178. os.Exit(2)
  179. }
  180. me.Gotool = strings.TrimRight(me.Gotool, "/") + "/bin/go"
  181. } else {
  182. me.Gotool = strings.TrimRight(me.Gotool, "/") + "/go"
  183. }
  184. me.originGopath = os.Getenv("GOPATH")
  185. }
  186. func (me *TIgo) HandleArgs() {
  187. var manualGoPath, manualPkgs string
  188. var workDir, cfgFile string
  189. flag.StringVar(&manualGoPath, "p", "", "assign gopath manually")
  190. flag.StringVar(&manualPkgs, "m", "", "point out which package or which path to be build")
  191. flag.StringVar(&workDir, "d", "", "set working dir")
  192. flag.StringVar(&cfgFile, "f", "", "set gopath config file")
  193. flag.Parse()
  194. if flag.NArg() == 0 {
  195. me.Args = append(me.Args, "install")
  196. } else {
  197. me.Args = append(me.Args, flag.Args()...)
  198. }
  199. if len(cfgFile) > 0 {
  200. abs, err := filepath.Abs(cfgFile)
  201. if err == nil {
  202. me.gopath.cfgFile = abs
  203. me.gopath.curDir = filepath.Dir(abs)
  204. }
  205. } else if len(workDir) >0 {
  206. abs, err := filepath.Abs(workDir)
  207. if err == nil {
  208. me.gopath.curDir = abs
  209. }
  210. }
  211. var slManualGoPath, slManualPkgs []string
  212. if len(manualGoPath) > 0 {
  213. me.bManualPath = true
  214. slManualGoPath = igoStrSpaceSplit(manualGoPath)
  215. for i:=0; i<len(slManualGoPath); i++ {
  216. me.gopath.AddPath(slManualGoPath[i])
  217. }
  218. } else if !me.gopath.ReadGopathFromConfigFile() {
  219. me.gopath.AutoBuildPath()
  220. }
  221. me.gopath.BuildPackageList()
  222. if len(manualPkgs) > 0 {
  223. me.bManualPkg = true
  224. slManualPkgs = igoStrSpaceSplit(manualPkgs)
  225. for i:=0; i<len(slManualPkgs); i++ {
  226. givenPath := strings.TrimRight(me.gopath.Pwd(), "/") + "/" + slManualPkgs[i]
  227. pkgs := me.gopath.GetPackageListFromPath(givenPath)
  228. me.mPkgs = append(me.mPkgs, pkgs...)
  229. }
  230. for _, v := range me.gopath.pkgs {
  231. for i:=0; i<len(v); i++ {
  232. for j:=0; j<len(slManualPkgs); j++ {
  233. if v[i] == slManualPkgs[j] {
  234. me.mPkgs = append(me.mPkgs, v[i])
  235. }
  236. }
  237. }
  238. }
  239. } else {
  240. me.mPkgs = []string{"all"}
  241. }
  242. me.Args = append(me.Args, me.mPkgs...)
  243. gpl := me.gopath.GetGopath()
  244. for _, s := range gpl {
  245. me.originGopath = me.originGopath + ":" + s
  246. }
  247. me.originGopath = strings.TrimLeft(me.originGopath, ":")
  248. os.Setenv("GOPATH", me.originGopath)
  249. }
  250. func main(){
  251. var igo TIgo
  252. igo.Create()
  253. igo.HandleArgs()
  254. fmt.Println("GOPATH is :\n\t", os.Getenv("GOPATH"))
  255. cmd := exec.Command(igo.Gotool, igo.Args[:]...)
  256. cmd.Stdout = os.Stdout
  257. cmd.Stderr = os.Stderr
  258. err := cmd.Run()
  259. ChkErr(err)
  260. }