package main import ( "bytes" "compress/gzip" "encoding/json" "encoding/xml" "fmt" "io" "io/ioutil" "mime/multipart" "net/http" "os" "path/filepath" "strings" ) type EngineClient struct { ProjectName string ServerUrl string } type ResponeResult struct { Code int32 `json:"code"` //描述 Msg string `json:"msg"` //数据 Data []GenerateResult `json:"data"` } type GenerateResult struct { Name string `json:"name"` Content []byte `json:"content"` Type string `json:"type"` } func NewEngineClient(project_name string, server_url string) *EngineClient { return &EngineClient{project_name, server_url} } func (c *EngineClient) InitDefalutFile(project_name string) { c.ProjectName = project_name os.MkdirAll("controllers/gen", os.ModePerm) os.MkdirAll("controllers/partial", os.ModePerm) os.MkdirAll("models", os.ModePerm) os.MkdirAll("routers", os.ModePerm) os.MkdirAll("conf", os.ModePerm) os.MkdirAll("sqlconfig", os.ModePerm) //os.MkdirAll("sqlconfig/gen", os.ModePerm) os.MkdirAll("doc", os.ModePerm) os.MkdirAll("web", os.ModePerm) _, err := os.Stat(project_name + ".xml") if os.IsNotExist(err) { xml := strings.Replace(DefaultProjectXML, "{project_name}", project_name, -1) ioutil.WriteFile(project_name+".xml", []byte(xml), os.ModePerm) } _, err = os.Stat(project_name + ".xsd") if os.IsNotExist(err) { ioutil.WriteFile(project_name+".xsd", []byte(XSD), os.ModePerm) } _, err = os.Stat("Dockerfile") if os.IsNotExist(err) { xml := strings.Replace(DockerFile, "{project_name}", project_name, -1) ioutil.WriteFile("Dockerfile", []byte(xml), os.ModePerm) } _, err = os.Stat("build_docker.sh") if os.IsNotExist(err) { xml := strings.Replace(BuildSH, "{project_name}", project_name, -1) ioutil.WriteFile("build_docker.sh", []byte(xml), os.ModePerm) } _, err = os.Stat("README.md") if os.IsNotExist(err) { xml := strings.Replace(MARK_DOWN, "{project_name}", project_name, -1) xml = strings.Replace(xml, "{!}", "`", -1) ioutil.WriteFile("README.md", []byte(xml), os.ModePerm) } } func (c *EngineClient) GenerateCurrentProject() (app *XmlApplication) { c.InitDefalutFile(c.ProjectName) // 0---0 //path, _ := utils.GetCurrentPath() //c.Generate(path + c.ProjectName + ".xml") projMainXmlFileTemp := "" projMainXmlFileTemp, app = c.MergeXmlToSingle() if projMainXmlFileTemp == "" { fmt.Println("projMainXmlFileTemp is empty") return } c.Generate(projMainXmlFileTemp) path, _ := GetCurrentPath() CopyDir(os.Getenv("GOPATH")+"/src/git.qianqiusoft.com/qianqiusoft/light-apiengine/sqlconfig", path+"vendor/git.qianqiusoft.com/qianqiusoft/light-apiengine/sqlconfig", "./vendor/git.qianqiusoft.com/qianqiusoft/light-apiengine/sqlconfig", "../git.qianqiusoft.com/qianqiusoft/light-apiengine/sqlconfig", path+"sqlconfig") return } func (c *EngineClient) GenerateToPath(xmlfile string, dest_path string) { var result ResponeResult server := "http://qianqiusoft.com:6166" if c.ServerUrl != "" { server = c.ServerUrl } server += "/api/v1/develop/generate" bs := DoRequest(xmlfile, server) if bs != nil { err := json.Unmarshal(bs.Bytes(), &result) if err != nil { fmt.Println(err.Error()) } for i := 0; i < len(result.Data); i++ { var b bytes.Buffer b.Write(result.Data[i].Content) unzip := unzipbytes(&b) result.Data[i].Content = unzip.Bytes() } for i := 0; i < len(result.Data); i++ { path := result.Data[i].Name //fmt.Println(path) path = path[len(c.ProjectName)+1:] path = dest_path + path fmt.Println(path) ft := result.Data[i].Type if result.Data[i].Type == "main" { } else if ft == "config" || ft == "ci" { _, err := os.Stat(path) if err == nil { fmt.Println(path + "已经存在,忽略...") } else { ioutil.WriteFile(path, result.Data[i].Content, os.ModePerm) } } else if ft == "controllers" { os.MkdirAll(filepath.Dir(path), os.ModePerm) if strings.Index(path, "_gen.go") > 0 { ioutil.WriteFile(path, result.Data[i].Content, os.ModePerm) } else { _, err := os.Stat(path) if err == nil { ioutil.WriteFile(path+"_new", result.Data[i].Content, os.ModePerm) } else if os.IsNotExist(err) { ioutil.WriteFile(path, result.Data[i].Content, os.ModePerm) } } } else if ft == "routers" { os.MkdirAll(filepath.Dir(path), os.ModePerm) ioutil.WriteFile(path, result.Data[i].Content, os.ModePerm) } else if ft == "sql" { if strings.Index(path, "_gen.xml") > 0 { os.MkdirAll(filepath.Dir(path), os.ModePerm) ioutil.WriteFile(path, result.Data[i].Content, os.ModePerm) } else { _, err := os.Stat(path) if err == nil { //ioutil.WriteFile(path+"_new", result.Data[i].Content, os.ModePerm) } else if os.IsNotExist(err) { os.MkdirAll(filepath.Dir(path), os.ModePerm) ioutil.WriteFile(path, result.Data[i].Content, os.ModePerm) } } } else { os.MkdirAll(filepath.Dir(path), os.ModePerm) err := ioutil.WriteFile(path, result.Data[i].Content, os.ModePerm) if err != nil { fmt.Println(err.Error()) } } } } } func (c *EngineClient) Generate(xmlfile string) { c.GenerateToPath(xmlfile, "") //c.GenSwagger(xmlfile) } func (c *EngineClient) GenSwagger(xmlfile string) { server := "http://swagger.pusher.i2erp.cn" server += "/api/v1/upload" fmt.Println("===========================================================================>11") request, err := newfileUploadRequest(server, nil, "xmlfile", xmlfile) if err != nil { fmt.Println(err) } client := &http.Client{} resp, err := client.Do(request) if err != nil { fmt.Println("===========================================================================>", err.Error()) } else { defer resp.Body.Close() bytess, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Println("=======================================>ioutil.ReadAll error", err.Error()) } else { fmt.Println("=======================================>", string(bytess)) } } } /** * @brief: merge xml * @param: none * @return: the path of final xml */ func (c *EngineClient) MergeXmlToSingle() (projMainXmlFileTemp string, app *XmlApplication) { path, _ := GetCurrentPath() // e.g.: c:/gopath/src/hanghua_background_proj projDir := fmt.Sprintf("%s%s.proj", path, c.ProjectName) projMainXmlFile := projDir + "/" + c.ProjectName + ".xml" projMainXmlFileTemp = projDir + "/" + c.ProjectName + "_temp.xml" _, err := os.Stat(projMainXmlFileTemp) if os.IsNotExist(err) { fmt.Println("-------------------------->remove project main file temp") os.Remove(projMainXmlFileTemp) // remove } _, err = os.Stat(projMainXmlFile) if os.IsNotExist(err) { fmt.Println("main xml file of " + c.ProjectName + " does not exist") return "", nil } app = &XmlApplication{} bytess, _ := ioutil.ReadFile(projMainXmlFile) err = xml.Unmarshal(bytess, app) if err != nil { fmt.Println("xml.Unmarshal(bytess, &app) error " + err.Error()) return "", nil } controllers, err := scanControllers(projDir + "/controllers") if err != nil { fmt.Println("scanControllers error " + err.Error()) return "", nil } beans, err := scanBeans(projDir + "/beans") if err != nil { fmt.Println("scanBeans error " + err.Error()) return "", nil } tables, err := scanTables(projDir + "/tables") if err != nil { fmt.Println("scanTables error " + err.Error()) return "", nil } if app.Controllers.ControllerList == nil { app.Controllers.ControllerList = []XmlController{} } for i := range controllers { app.Controllers.ControllerList = append(app.Controllers.ControllerList, controllers[i]) } createVueApisFolder(app.Controllers.ControllerList) if app.Beans.BeanList == nil { app.Beans.BeanList = []XmlBean{} } for i := range beans { app.Beans.BeanList = append(app.Beans.BeanList, beans[i]) } if app.Tables.TableList == nil { app.Tables.TableList = []XmlTable{} } for i := range tables { app.Tables.TableList = append(app.Tables.TableList, tables[i]) } bytess, err = xml.Marshal(app) if err != nil { fmt.Println("xml.Marshal(app) error " + err.Error()) return "", nil } err = ioutil.WriteFile(projMainXmlFileTemp, bytess, os.ModePerm) if err != nil { fmt.Println("ioutil.WriteFile(projMainXmlFileTemp, bytess,os.ModePerm) error " + err.Error()) return "", nil } _, err = os.Stat(projMainXmlFileTemp) if os.IsNotExist(err) { fmt.Println("main xml file temp of " + c.ProjectName + " does not exist") return "", nil } else { fmt.Println("main xml file temp of " + c.ProjectName + " exist") } return } func scanControllers(ctrldir string) ([]XmlController, error) { _, err := os.Stat(ctrldir) if os.IsNotExist(err) { fmt.Println("controller dir does not exist", err.Error()) return nil, err } controllers := []XmlController{} filePaths := []string{} filePaths, err = getAllFile(strings.TrimSuffix(ctrldir, "/"), filePaths) if err != nil { fmt.Println("controller getAllFile error", err.Error()) return nil, err } for i := range filePaths { ctrl := XmlController{} ctrlfile := filePaths[i] _, err = os.Stat(ctrlfile) if os.IsNotExist(err) { fmt.Println("controller xml file " + ctrlfile + " does not exist") return controllers, err } ctrlfile = strings.Replace(ctrlfile, "\\", "/", -1) arr := strings.Split(ctrlfile, "/") bytess, _ := ioutil.ReadFile(ctrlfile) err = xml.Unmarshal(bytess, &ctrl) if err != nil { fmt.Println("xml.Unmarshal(bytess, &app) error " + err.Error()) return controllers, err } // get sub dir name if arr[len(arr)-2] != "controllers" { // if sub dir is not controllers, set the dir attr ctrl.Dir = arr[len(arr)-2] } controllers = append(controllers, ctrl) } return controllers, nil //err = filepath.Walk(ctrldir, func(path string, info os.FileInfo, err error) error { // // if err != nil { // return filepath.SkipDir // } // if info.IsDir(){ // return nil // } // // ctrl := XmlController{} // ctrlfile := ctrldir + "/" + info.Name() // _, err = os.Stat(ctrlfile) // if os.IsNotExist(err) { // fmt.Println("controller xml file " + ctrlfile + " does not exist") // return filepath.SkipDir // } // bytess, _ := ioutil.ReadFile(ctrlfile) // err = xml.Unmarshal(bytess, &ctrl) // if err != nil{ // fmt.Println("xml.Unmarshal(bytess, &app) error " + err.Error()) // return filepath.SkipDir // } // controllers = append(controllers, ctrl) // // return nil //}) //return controllers, err } func scanBeans(ctrldir string) ([]XmlBean, error) { _, err := os.Stat(ctrldir) if os.IsNotExist(err) { fmt.Println("controller dir does not exist") return nil, err } beans := []XmlBean{} filePaths := []string{} filePaths, err = getAllFile(strings.TrimSuffix(ctrldir, "/"), filePaths) if err != nil { fmt.Println("controller getAllFile error", err.Error()) return nil, err } for i := range filePaths { ctrl := XmlBean{} ctrlfile := filePaths[i] _, err = os.Stat(ctrlfile) if os.IsNotExist(err) { fmt.Println("controller xml file " + ctrlfile + " does not exist") return beans, err } bytess, _ := ioutil.ReadFile(ctrlfile) err = xml.Unmarshal(bytess, &ctrl) if err != nil { fmt.Println("xml.Unmarshal(bytess, &app) error " + err.Error()) return beans, err } beans = append(beans, ctrl) } return beans, nil //err = filepath.Walk(ctrldir, func(path string, info os.FileInfo, err error) error { // // if err != nil { // return filepath.SkipDir // } // if info.IsDir(){ // return nil // } // // bean := XmlBean{} // beanfile := ctrldir + "/" + info.Name() // _, err = os.Stat(beanfile) // if os.IsNotExist(err) { // fmt.Println("controller xml file " + beanfile + " does not exist") // return filepath.SkipDir // } // bytess, _ := ioutil.ReadFile(beanfile) // err = xml.Unmarshal(bytess, &bean) // if err != nil{ // fmt.Println("xml.Unmarshal(bytess, &app) error " + err.Error()) // return filepath.SkipDir // } // beans = append(beans, bean) // // return nil //}) // //return beans, err } func scanTables(ctrldir string) ([]XmlTable, error) { _, err := os.Stat(ctrldir) if os.IsNotExist(err) { fmt.Println("controller dir does not exist") return nil, err } tables := []XmlTable{} filePaths := []string{} filePaths, err = getAllFile(strings.TrimSuffix(ctrldir, "/"), filePaths) if err != nil { fmt.Println("controller getAllFile error", err.Error()) return nil, err } for i := range filePaths { ctrl := XmlTable{} ctrlfile := filePaths[i] _, err = os.Stat(ctrlfile) if os.IsNotExist(err) { fmt.Println("controller xml file " + ctrlfile + " does not exist") return tables, err } bytess, _ := ioutil.ReadFile(ctrlfile) err = xml.Unmarshal(bytess, &ctrl) if err != nil { fmt.Println("xml.Unmarshal(bytess, &app) error " + err.Error()) return tables, err } tables = append(tables, ctrl) } return tables, nil //err = filepath.Walk(ctrldir, func(path string, info os.FileInfo, err error) error { // // if err != nil { // return filepath.SkipDir // } // if info.IsDir(){ // return nil // } // // table := XmlTable{} // tablefile := ctrldir + "/" + info.Name() // _, err = os.Stat(tablefile) // if os.IsNotExist(err) { // fmt.Println("controller xml file " + tablefile + " does not exist") // return filepath.SkipDir // } // bytess, _ := ioutil.ReadFile(tablefile) // err = xml.Unmarshal(bytess, &table) // if err != nil{ // fmt.Println("xml.Unmarshal(bytess, &app) error " + err.Error()) // return filepath.SkipDir // } // tables = append(tables, table) // // return nil //}) // //return tables, err } func createVueApisFolder(controllers []XmlController) { for i := range controllers { fmt.Println("------------------------------>" + controllers[i].Name) os.MkdirAll("vue/api/modules/"+controllers[i].Name, os.ModePerm) } } func getAllFile(pathname string, s []string) ([]string, error) { rd, err := ioutil.ReadDir(pathname) if err != nil { fmt.Println("read dir fail:", err) return s, err } for _, fi := range rd { if fi.IsDir() { fullDir := pathname + "/" + fi.Name() s, err = getAllFile(fullDir, s) if err != nil { fmt.Println("read dir fail:", err) return s, err } } else { if strings.HasSuffix(strings.ToLower(fi.Name()), ".xml") { fullName := pathname + "/" + fi.Name() s = append(s, fullName) } } } return s, nil } func unzipbytes(bs *bytes.Buffer) bytes.Buffer { r, _ := gzip.NewReader(bs) defer r.Close() var b bytes.Buffer b.ReadFrom(r) //undatas, _ := ioutil.ReadAll(r) //fmt.Println("ungzip size:", len(undatas)) return b } func DoRequest(xmlfile string, server string) *bytes.Buffer { request, err := newfileUploadRequest(server, nil, "xmlfile", xmlfile) if err != nil { fmt.Println(err) } client := &http.Client{} resp, err := client.Do(request) if err != nil { fmt.Println(err) } else { body := &bytes.Buffer{} _, err := body.ReadFrom(resp.Body) if err != nil { fmt.Println(err) } resp.Body.Close() fmt.Println(resp.StatusCode) fmt.Println(resp.Header) //fmt.Println(body) return body } return nil } func newfileUploadRequest(uri string, params map[string]string, paramName, path string) (*http.Request, error) { file, err := os.Open(path) if err != nil { return nil, err } defer file.Close() body := &bytes.Buffer{} writer := multipart.NewWriter(body) part, err := writer.CreateFormFile(paramName, filepath.Base(path)) if err != nil { return nil, err } _, err = io.Copy(part, file) for key, val := range params { _ = writer.WriteField(key, val) } err = writer.Close() if err != nil { return nil, err } request, err := http.NewRequest("POST", uri, body) request.Header.Add("Content-Type", writer.FormDataContentType()) return request, err }