diff --git a/.travis.yml b/.travis.yml index 5f7c288c..043ebf0a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,13 @@ language: go go: - 1.9 + - 1.10 - master before_install: - cd $HOME - git clone https://github.com/Azareal/Gosora - cd Gosora + - mv config_default.noparse config.go - chmod 755 ./update-deps-linux - chmod 755 ./run-linux-tests - ./update-deps-linux diff --git a/README.md b/README.md index df740496..6cad7054 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ It's entirely possible that your host might already have MySQL, so you might be cd to the directory / folder the code is in. In other words, type cd followed by the location of the code and it should jump there. -Run ./install-gosora-linux +Run ./install-linux Follow the instructions shown on the screen. @@ -65,7 +65,7 @@ Follow the instructions shown on the screen. *Linux* -In the same directory you installed it, you simply have to type: ./run-gosora-linux +In the same directory you installed it, you simply have to type: ./run-linux *Windows* @@ -73,13 +73,13 @@ Run run.bat *Updating Dependencies* -You can update the dependencies which Gosora relies on by running update-deps.bat on Windows or ./update-deps-linux on Linux. These dependencies do not include Go or MySQL. +You can update the dependencies which Gosora relies on by running update-deps.bat on Windows or ./update-deps-linux on Linux. These dependencies do not include Go or MySQL, those have to be updated separately. We're also looking into ways to distribute ready made executables for Windows. While this is not a complicated endeavour, the configuration settings currently get built with the rest of the program for speed, and we will likely have to change this. With the introduction of the new settings system, we will begin moving some of the less critical settings out of the configuration file, and will likely have a config.xml or config.ini in the future to store the critical settings in. -You might have to run run.bat or ./run-gosora-linux twice after changing a template to make sure the templates are compiled properly. We'll be resolving this issue while rolling out the new compiled templates system to the rest of the routes. +You'll need to restart the server every-time you change a template, e.g. with `run.bat` or `./run-linux` Several important features for saving memory in the templates system may have to be implemented before the new compiled template system is rolled out to every route. These features are coming fairly soon, but not before the higher priority items. @@ -90,6 +90,8 @@ An example of running the commands directly on Windows. We're looking into reduc Linux is similar, however you might need to use cd and mv a bit more like in the shell files due to the differences in go build across platforms. Additionally, Linux doesn't require `StackExchange/wmi` or ``/x/sys/windows` +You also need to substitute the `gosora.exe` bits for `./Gosora` on Linux. For more info, you might want to take a gander inside the `./run-linux` and `./install-linux` shell files to see how they're implemented. + ```bash git clone https://github.com/Azareal/Gosora @@ -113,6 +115,8 @@ go get -u github.com/denisenkom/go-mssqldb go get -u github.com/fsnotify/fsnotify +go get -u gopkg.in/src-d/go-git.v4/... + go generate @@ -130,6 +134,8 @@ go build ./install install.exe +gosora.exe -build-templates + gosora.exe ``` diff --git a/build_templates.bat b/build_templates.bat new file mode 100644 index 00000000..68d74b24 --- /dev/null +++ b/build_templates.bat @@ -0,0 +1,2 @@ +gosora.exe -build-templates +pause \ No newline at end of file diff --git a/common/no_websockets.go b/common/no_websockets.go index 28bb37fa..dd1b9efd 100644 --- a/common/no_websockets.go +++ b/common/no_websockets.go @@ -11,20 +11,13 @@ var EnableWebsockets = false // Put this in caps for consistency with the other var wsHub WSHub var errWsNouser = errors.New("This user isn't connected via WebSockets") -type WSHub struct { -} +type WSHub struct{} -func (_ *WSHub) guestCount() int { - return 0 -} +func (_ *WSHub) guestCount() int { return 0 } -func (_ *WSHub) userCount() int { - return 0 -} +func (_ *WSHub) userCount() int { return 0 } -func (hub *WSHub) broadcastMessage(_ string) error { - return nil -} +func (hub *WSHub) broadcastMessage(_ string) error { return nil } func (hub *WSHub) pushMessage(_ int, _ string) error { return errWsNouser @@ -38,5 +31,4 @@ func (hub *WSHub) pushAlerts(_ []int, _ int, _ string, _ string, _ int, _ int, _ return errWsNouser } -func RouteWebsockets(_ http.ResponseWriter, _ *http.Request, _ User) { -} +func RouteWebsockets(_ http.ResponseWriter, _ *http.Request, _ User) {} diff --git a/common/routes_common.go b/common/routes_common.go index 50a300cb..4521a455 100644 --- a/common/routes_common.go +++ b/common/routes_common.go @@ -224,6 +224,9 @@ func userCheck(w http.ResponseWriter, r *http.Request, user *User) (headerVars * if len(theme.Resources) > 0 { rlist := theme.Resources for _, resource := range rlist { + if resource.Loggedin && !user.Loggedin { + continue + } if resource.Location == "global" || resource.Location == "frontend" { extarr := strings.Split(resource.Name, ".") ext := extarr[len(extarr)-1] diff --git a/common/template_init.go b/common/template_init.go index e2e59dfa..f5c20736 100644 --- a/common/template_init.go +++ b/common/template_init.go @@ -4,7 +4,10 @@ import ( "html/template" "log" "net/http" + "path/filepath" "strconv" + "strings" + "sync" "time" "./templates" @@ -119,7 +122,7 @@ var Template_ip_search_handle = func(pi IPSearchPage, w http.ResponseWriter) err } // ? - Add template hooks? -func compileTemplates() error { +func CompileTemplates() error { var config tmpl.CTemplateConfig config.Minify = Config.MinifyTemplates config.SuperDebug = Dev.TemplateDebug @@ -235,6 +238,23 @@ func compileTemplates() error { return err } + var wg sync.WaitGroup + var writeTemplate = func(name string, content string) { + log.Print("Writing template '" + name + "'") + if content == "" { + log.Fatal("No content body") + } + + wg.Add(1) + go func() { + err := writeFile("./template_"+name+".go", content) + if err != nil { + log.Fatal(err) + } + wg.Done() + }() + } + // Let plugins register their own templates DebugLog("Registering the templates for the plugins") config = c.GetConfig() @@ -247,20 +267,22 @@ func compileTemplates() error { if err != nil { return err } - go writeTemplate(tmplItem.Name, compiledTmpl) + writeTemplate(tmplItem.Name, compiledTmpl) } log.Print("Writing the templates") - go writeTemplate("topic", topicIDTmpl) - go writeTemplate("topic_alt", topicIDAltTmpl) - go writeTemplate("profile", profileTmpl) - go writeTemplate("forums", forumsTmpl) - go writeTemplate("topics", topicsTmpl) - go writeTemplate("forum", forumTmpl) - go writeTemplate("login", loginTmpl) - go writeTemplate("register", registerTmpl) - go writeTemplate("ip_search", ipSearchTmpl) - go writeTemplate("error", errorTmpl) + writeTemplate("topic", topicIDTmpl) + writeTemplate("topic_alt", topicIDAltTmpl) + writeTemplate("profile", profileTmpl) + writeTemplate("forums", forumsTmpl) + writeTemplate("topics", topicsTmpl) + writeTemplate("forum", forumTmpl) + writeTemplate("login", loginTmpl) + writeTemplate("register", registerTmpl) + writeTemplate("ip_search", ipSearchTmpl) + writeTemplate("error", errorTmpl) + + wg.Add(1) go func() { out := "package main\n\n" for templateName, count := range c.TemplateFragmentCount { @@ -271,26 +293,15 @@ func compileTemplates() error { if err != nil { log.Fatal(err) } + wg.Done() }() + wg.Wait() return nil } -func writeTemplate(name string, content string) { - err := writeFile("./template_"+name+".go", content) - if err != nil { - log.Fatal(err) - } -} - func InitTemplates() error { - if Dev.DebugMode { - log.Print("Initialising the template system") - } - err := compileTemplates() - if err != nil { - return err - } + DebugLog("Initialising the template system") // TODO: Add support for 64-bit integers // TODO: Add support for floats @@ -365,7 +376,34 @@ func InitTemplates() error { // The interpreted templates... DebugLog("Loading the template files...") Templates.Funcs(fmap) - template.Must(Templates.ParseGlob("templates/*")) + templateFiles, err := filepath.Glob("templates/*.html") + if err != nil { + return err + } + + var templateFileMap = make(map[string]int) + for index, path := range templateFiles { + path = strings.Replace(path, "\\", "/", -1) + log.Print("templateFile: ", path) + templateFileMap[path] = index + } + + overrideFiles, err := filepath.Glob("templates/overrides/*.html") + if err != nil { + return err + } + for _, path := range overrideFiles { + path = strings.Replace(path, "\\", "/", -1) + log.Print("overrideFile: ", path) + index, ok := templateFileMap["templates/"+strings.TrimPrefix(path, "templates/overrides/")] + if !ok { + log.Print("not ok: templates/" + strings.TrimPrefix(path, "templates/overrides/")) + templateFiles = append(templateFiles, path) + continue + } + templateFiles[index] = path + } + template.Must(Templates.ParseFiles(templateFiles...)) template.Must(Templates.ParseGlob("pages/*")) return nil diff --git a/common/templates/templates.go b/common/templates/templates.go index 529b3150..25cc8465 100644 --- a/common/templates/templates.go +++ b/common/templates/templates.go @@ -109,9 +109,14 @@ func (c *CTemplateSet) Compile(name string, fileDir string, expects string, expe c.expectsInt = expectsInt holdreflect := reflect.ValueOf(expectsInt) - res, err := ioutil.ReadFile(fileDir + name) + res, err := ioutil.ReadFile(fileDir + "overrides/" + name) if err != nil { - return "", err + c.detail("override path: ", fileDir+"overrides/"+name) + c.detail("override err: ", err) + res, err = ioutil.ReadFile(fileDir + name) + if err != nil { + return "", err + } } content := string(res) @@ -125,14 +130,14 @@ func (c *CTemplateSet) Compile(name string, fileDir string, expects string, expe if err != nil { return "", err } - c.log(name) + c.detail(name) out = "" fname := strings.TrimSuffix(name, filepath.Ext(name)) c.templateList = map[string]*parse.Tree{fname: tree} varholder := "tmpl_" + fname + "_vars" - c.log(c.templateList) + c.detail(c.templateList) c.localVars = make(map[string]map[string]VarItemReflect) c.localVars[fname] = make(map[string]VarItemReflect) c.localVars[fname]["."] = VarItemReflect{".", varholder, holdreflect} @@ -203,16 +208,16 @@ w.Write([]byte(`, " + ", -1) } fmt.Println(" ") } - c.log("Output!") - c.log(fout) + c.detail("Output!") + c.detail(fout) return fout, nil } func (c *CTemplateSet) rootIterate(tree *parse.Tree, varholder string, holdreflect reflect.Value, fname string) (out string) { - c.log(tree.Root) + c.detail(tree.Root) treeLength := len(tree.Root.Nodes) for index, node := range tree.Root.Nodes { - c.log("Node:", node.String()) + c.detail("Node:", node.String()) c.previousNode = c.currentNode c.currentNode = node.Type() if treeLength != (index + 1) { @@ -224,10 +229,10 @@ func (c *CTemplateSet) rootIterate(tree *parse.Tree, varholder string, holdrefle } func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value, templateName string, node parse.Node) (out string) { - c.log("in compileSwitch") + c.detail("in compileSwitch") switch node := node.(type) { case *parse.ActionNode: - c.log("Action Node") + c.detail("Action Node") if node.Pipe == nil { break } @@ -235,30 +240,30 @@ func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value out += c.compileSubswitch(varholder, holdreflect, templateName, cmd) } case *parse.IfNode: - c.log("If Node:") - c.log("node.Pipe", node.Pipe) + c.detail("If Node:") + c.detail("node.Pipe", node.Pipe) var expr string for _, cmd := range node.Pipe.Cmds { - c.log("If Node Bit:", cmd) - c.log("Bit Type:", reflect.ValueOf(cmd).Type().Name()) + c.detail("If Node Bit:", cmd) + c.detail("Bit Type:", reflect.ValueOf(cmd).Type().Name()) expr += c.compileVarswitch(varholder, holdreflect, templateName, cmd) - c.log("Expression Step:", c.compileVarswitch(varholder, holdreflect, templateName, cmd)) + c.detail("Expression Step:", c.compileVarswitch(varholder, holdreflect, templateName, cmd)) } - c.log("Expression:", expr) + c.detail("Expression:", expr) c.previousNode = c.currentNode c.currentNode = parse.NodeList c.nextNode = -1 out = "if " + expr + " {\n" + c.compileSwitch(varholder, holdreflect, templateName, node.List) + "}" if node.ElseList == nil { - c.log("Selected Branch 1") + c.detail("Selected Branch 1") return out + "\n" } - c.log("Selected Branch 2") + c.detail("Selected Branch 2") return out + " else {\n" + c.compileSwitch(varholder, holdreflect, templateName, node.ElseList) + "}\n" case *parse.ListNode: - c.log("List Node") + c.detail("List Node") for _, subnode := range node.Nodes { out += c.compileSwitch(varholder, holdreflect, templateName, subnode) } @@ -291,15 +296,15 @@ func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value } func (c *CTemplateSet) compileRangeNode(varholder string, holdreflect reflect.Value, templateName string, node *parse.RangeNode) (out string) { - c.log("Range Node!") - c.log(node.Pipe) + c.detail("Range Node!") + c.detail(node.Pipe) var outVal reflect.Value for _, cmd := range node.Pipe.Cmds { - c.log("Range Bit:", cmd) + c.detail("Range Bit:", cmd) out, outVal = c.compileReflectSwitch(varholder, holdreflect, templateName, cmd) } - c.log("Returned:", out) - c.log("Range Kind Switch!") + c.detail("Returned:", out) + c.detail("Range Kind Switch!") switch outVal.Kind() { case reflect.Map: @@ -308,7 +313,7 @@ func (c *CTemplateSet) compileRangeNode(varholder string, holdreflect reflect.Va item = outVal.MapIndex(key) } - c.log("Range item:", item) + c.detail("Range item:", item) if !item.IsValid() { panic("item" + "^\n" + "Invalid map. Maybe, it doesn't have any entries for the template engine to analyse?") } @@ -334,11 +339,11 @@ func (c *CTemplateSet) compileRangeNode(varholder string, holdreflect reflect.Va } func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string) { - c.log("in compileSubswitch") + c.detail("in compileSubswitch") firstWord := node.Args[0] switch n := firstWord.(type) { case *parse.FieldNode: - c.log("Field Node:", n.Ident) + c.detail("Field Node:", n.Ident) /* Use reflect to determine if the field is for a method, otherwise assume it's a variable. Variable declarations are coming soon! */ cur := holdreflect @@ -351,12 +356,12 @@ func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Va // ! Might not work so well for non-struct pointers skipPointers := func(cur reflect.Value, id string) reflect.Value { if cur.Kind() == reflect.Ptr { - c.log("Looping over pointer") + c.detail("Looping over pointer") for cur.Kind() == reflect.Ptr { cur = cur.Elem() } - c.log("Data Kind:", cur.Kind().String()) - c.log("Field Bit:", id) + c.detail("Data Kind:", cur.Kind().String()) + c.detail("Field Bit:", id) } return cur } @@ -364,8 +369,8 @@ func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Va var assLines string var multiline = false for _, id := range n.Ident { - c.log("Data Kind:", cur.Kind().String()) - c.log("Field Bit:", id) + c.detail("Data Kind:", cur.Kind().String()) + c.detail("Field Bit:", id) cur = skipPointers(cur, id) if !cur.IsValid() { @@ -382,7 +387,7 @@ func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Va panic(varbit + "^\n" + "Invalid value. Maybe, it doesn't exist?") } - c.log("in-loop varbit: " + varbit) + c.detail("in-loop varbit: " + varbit) if cur.Kind() == reflect.Map { cur = cur.MapIndex(reflect.ValueOf(id)) varbit += "[\"" + id + "\"]" @@ -427,7 +432,7 @@ func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Va } varbit += cur.Type().Name() + ")" } - c.log("End Cycle: ", varbit) + c.detail("End Cycle: ", varbit) } if multiline { @@ -446,20 +451,20 @@ func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Va } return out case *parse.DotNode: - c.log("Dot Node:", node.String()) + c.detail("Dot Node:", node.String()) return c.compileVarsub(varholder, holdreflect, "") case *parse.NilNode: panic("Nil is not a command x.x") case *parse.VariableNode: - c.log("Variable Node:", n.String()) - c.log(n.Ident) + c.detail("Variable Node:", n.String()) + c.detail(n.Ident) varname, reflectVal := c.compileIfVarsub(n.String(), varholder, templateName, holdreflect) return c.compileVarsub(varname, reflectVal, "") case *parse.StringNode: return n.Quoted case *parse.IdentifierNode: - c.log("Identifier Node:", node) - c.log("Identifier Node Args:", node.Args) + c.detail("Identifier Node:", node) + c.detail("Identifier Node Args:", node.Args) out, outval, lit := c.compileIdentSwitch(varholder, holdreflect, templateName, node) if lit { return out @@ -471,7 +476,7 @@ func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Va } func (c *CTemplateSet) compileVarswitch(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string) { - c.log("in compileVarswitch") + c.detail("in compileVarswitch") firstWord := node.Args[0] switch n := firstWord.(type) { case *parse.FieldNode: @@ -485,26 +490,26 @@ func (c *CTemplateSet) compileVarswitch(varholder string, holdreflect reflect.Va /* Use reflect to determine if the field is for a method, otherwise assume it's a variable. Coming Soon. */ return c.compileBoolsub(n.String(), varholder, templateName, holdreflect) case *parse.ChainNode: - c.log("Chain Node:", n.Node) - c.log("Node Args:", node.Args) + c.detail("Chain Node:", n.Node) + c.detail("Node Args:", node.Args) case *parse.IdentifierNode: - c.log("Identifier Node:", node) - c.log("Node Args:", node.Args) + c.detail("Identifier Node:", node) + c.detail("Node Args:", node.Args) return c.compileIdentSwitchN(varholder, holdreflect, templateName, node) case *parse.DotNode: return varholder case *parse.VariableNode: - c.log("Variable Node:", n.String()) - c.log("Node Identifier:", n.Ident) + c.detail("Variable Node:", n.String()) + c.detail("Node Identifier:", n.Ident) out, _ = c.compileIfVarsub(n.String(), varholder, templateName, holdreflect) case *parse.NilNode: panic("Nil is not a command x.x") case *parse.PipeNode: - c.log("Pipe Node!") - c.log(n) - c.log("Node Args:", node.Args) + c.detail("Pipe Node!") + c.detail(n) + c.detail("Node Args:", node.Args) out += c.compileIdentSwitchN(varholder, holdreflect, templateName, node) - c.log("Out:", out) + c.detail("Out:", out) default: return c.unknownNode(firstWord) } @@ -518,15 +523,15 @@ func (c *CTemplateSet) unknownNode(node parse.Node) (out string) { } func (c *CTemplateSet) compileIdentSwitchN(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string) { - c.log("in compileIdentSwitchN") + c.detail("in compileIdentSwitchN") out, _, _ = c.compileIdentSwitch(varholder, holdreflect, templateName, node) return out } func (c *CTemplateSet) dumpSymbol(pos int, node *parse.CommandNode, symbol string) { - c.log("symbol: ", symbol) - c.log("node.Args[pos + 1]", node.Args[pos+1]) - c.log("node.Args[pos + 2]", node.Args[pos+2]) + c.detail("symbol: ", symbol) + c.detail("node.Args[pos + 1]", node.Args[pos+1]) + c.detail("node.Args[pos + 2]", node.Args[pos+2]) } func (c *CTemplateSet) compareFunc(varholder string, holdreflect reflect.Value, templateName string, pos int, node *parse.CommandNode, compare string) (out string) { @@ -552,7 +557,7 @@ func (c *CTemplateSet) simpleMath(varholder string, holdreflect reflect.Value, t } func (c *CTemplateSet) compareJoin(varholder string, holdreflect reflect.Value, templateName string, pos int, node *parse.CommandNode, symbol string) (pos2 int, out string) { - c.logf("Building %s function", symbol) + c.detailf("Building %s function", symbol) if pos == 0 { fmt.Println("pos:", pos) panic(symbol + " is missing a left operand") @@ -572,24 +577,24 @@ func (c *CTemplateSet) compareJoin(varholder string, holdreflect reflect.Value, } out = left + " " + symbol + " " + right - c.log("Left operand:", node.Args[pos-1]) - c.log("Right operand:", node.Args[pos+1]) + c.detail("Left operand:", node.Args[pos-1]) + c.detail("Right operand:", node.Args[pos+1]) if !funcExists { pos++ } - c.log("pos:", pos) - c.log("len(node.Args):", len(node.Args)) + c.detail("pos:", pos) + c.detail("len(node.Args):", len(node.Args)) return pos, out } func (c *CTemplateSet) compileIdentSwitch(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string, val reflect.Value, literal bool) { - c.log("in compileIdentSwitch") + c.detail("in compileIdentSwitch") ArgLoop: for pos := 0; pos < len(node.Args); pos++ { id := node.Args[pos] - c.log("pos:", pos) - c.log("ID:", id) + c.detail("pos:", pos) + c.detail("ID:", id) switch id.String() { case "not": out += "!" @@ -683,7 +688,7 @@ ArgLoop: literal = true break ArgLoop default: - c.log("Variable!") + c.detail("Variable!") if len(node.Args) > (pos + 1) { nextNode := node.Args[pos+1].String() if nextNode == "or" || nextNode == "and" { @@ -697,7 +702,7 @@ ArgLoop: } func (c *CTemplateSet) compileReflectSwitch(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string, outVal reflect.Value) { - c.log("in compileReflectSwitch") + c.detail("in compileReflectSwitch") firstWord := node.Args[0] switch n := firstWord.(type) { case *parse.FieldNode: @@ -710,8 +715,8 @@ func (c *CTemplateSet) compileReflectSwitch(varholder string, holdreflect reflec /* Use reflect to determine if the field is for a method, otherwise assume it's a variable. Coming Soon. */ return c.compileIfVarsub(n.String(), varholder, templateName, holdreflect) case *parse.ChainNode: - c.log("Chain Node:", n.Node) - c.log("node.Args:", node.Args) + c.detail("Chain Node:", n.Node) + c.detail("node.Args:", node.Args) case *parse.DotNode: return varholder, holdreflect case *parse.NilNode: @@ -723,13 +728,13 @@ func (c *CTemplateSet) compileReflectSwitch(varholder string, holdreflect reflec } func (c *CTemplateSet) compileIfVarsubN(varname string, varholder string, templateName string, cur reflect.Value) (out string) { - c.log("in compileIfVarsubN") + c.detail("in compileIfVarsubN") out, _ = c.compileIfVarsub(varname, varholder, templateName, cur) return out } func (c *CTemplateSet) compileIfVarsub(varname string, varholder string, templateName string, cur reflect.Value) (out string, val reflect.Value) { - c.log("in compileIfVarsub") + c.detail("in compileIfVarsub") if varname[0] != '.' && varname[0] != '$' { return varname, cur } @@ -757,22 +762,22 @@ func (c *CTemplateSet) compileIfVarsub(varname string, varholder string, templat } bits[0] = strings.TrimPrefix(bits[0], "$") - c.log("Cur Kind:", cur.Kind()) - c.log("Cur Type:", cur.Type().Name()) + c.detail("Cur Kind:", cur.Kind()) + c.detail("Cur Type:", cur.Type().Name()) for _, bit := range bits { - c.log("Variable Field:", bit) + c.detail("Variable Field:", bit) if bit == "" { continue } // TODO: Fix this up so that it works for regular pointers and not just struct pointers. Ditto for the other cur.Kind() == reflect.Ptr we have in this file if cur.Kind() == reflect.Ptr { - c.log("Looping over pointer") + c.detail("Looping over pointer") for cur.Kind() == reflect.Ptr { cur = cur.Elem() } - c.log("Data Kind:", cur.Kind().String()) - c.log("Field Bit:", bit) + c.detail("Data Kind:", cur.Kind().String()) + c.detail("Field Bit:", bit) } cur = cur.FieldByName(bit) @@ -784,13 +789,13 @@ func (c *CTemplateSet) compileIfVarsub(varname string, varholder string, templat if !cur.IsValid() { panic(out + "^\n" + "Invalid value. Maybe, it doesn't exist?") } - c.log("Data Kind:", cur.Kind()) - c.log("Data Type:", cur.Type().Name()) + c.detail("Data Kind:", cur.Kind()) + c.detail("Data Type:", cur.Type().Name()) } - c.log("Out Value:", out) - c.log("Out Kind:", cur.Kind()) - c.log("Out Type:", cur.Type().Name()) + c.detail("Out Value:", out) + c.detail("Out Kind:", cur.Kind()) + c.detail("Out Type:", cur.Type().Name()) for _, varItem := range c.varList { if strings.HasPrefix(out, varItem.Destination) { @@ -798,9 +803,9 @@ func (c *CTemplateSet) compileIfVarsub(varname string, varholder string, templat } } - c.log("Out Value:", out) - c.log("Out Kind:", cur.Kind()) - c.log("Out Type:", cur.Type().Name()) + c.detail("Out Value:", out) + c.detail("Out Kind:", cur.Kind()) + c.detail("Out Type:", cur.Type().Name()) _, ok := c.stats[out] if ok { @@ -813,7 +818,7 @@ func (c *CTemplateSet) compileIfVarsub(varname string, varholder string, templat } func (c *CTemplateSet) compileBoolsub(varname string, varholder string, templateName string, val reflect.Value) string { - c.log("in compileBoolsub") + c.detail("in compileBoolsub") out, val := c.compileIfVarsub(varname, varholder, templateName, val) // TODO: What if it's a pointer or an interface? I *think* we've got pointers handled somewhere, but not interfaces which we don't know the types of at compile time switch val.Kind() { @@ -834,7 +839,7 @@ func (c *CTemplateSet) compileBoolsub(varname string, varholder string, template } func (c *CTemplateSet) compileVarsub(varname string, val reflect.Value, assLines string) (out string) { - c.log("in compileVarsub") + c.detail("in compileVarsub") // Is this a literal string? if len(varname) != 0 && varname[0] == '"' { @@ -858,8 +863,8 @@ func (c *CTemplateSet) compileVarsub(varname string, val reflect.Value, assLines val = val.Elem() } - c.log("varname: ", varname) - c.log("assLines: ", assLines) + c.detail("varname: ", varname) + c.detail("assLines: ", assLines) switch val.Kind() { case reflect.Int: c.importMap["strconv"] = "strconv" @@ -883,13 +888,13 @@ func (c *CTemplateSet) compileVarsub(varname string, val reflect.Value, assLines fmt.Println("Unknown Type:", val.Type().Name()) panic("-- I don't know what this variable's type is o.o\n") } - c.log("out: ", out) + c.detail("out: ", out) return assLines + out } func (c *CTemplateSet) compileSubtemplate(pvarholder string, pholdreflect reflect.Value, node *parse.TemplateNode) (out string) { - c.log("in compileSubtemplate") - c.log("Template Node: ", node.Name) + c.detail("in compileSubtemplate") + c.detail("Template Node: ", node.Name) fname := strings.TrimSuffix(node.Name, filepath.Ext(node.Name)) varholder := "tmpl_" + fname + "_vars" @@ -904,16 +909,21 @@ func (c *CTemplateSet) compileSubtemplate(pvarholder string, pholdreflect reflec case *parse.NilNode: panic("Nil is not a command x.x") default: - c.log("Unknown Node: ", firstWord) + c.detail("Unknown Node: ", firstWord) panic("") } } } // TODO: Cascade errors back up the tree to the caller? - res, err := ioutil.ReadFile(c.fileDir + node.Name) + res, err := ioutil.ReadFile(c.fileDir + "overrides/" + node.Name) if err != nil { - log.Fatal(err) + c.detail("override path: ", c.fileDir+"overrides/"+node.Name) + c.detail("override err: ", err) + res, err = ioutil.ReadFile(c.fileDir + node.Name) + if err != nil { + log.Fatal(err) + } } content := string(res) @@ -930,7 +940,7 @@ func (c *CTemplateSet) compileSubtemplate(pvarholder string, pholdreflect reflec c.templateList[fname] = tree subtree := c.templateList[fname] - c.log("subtree.Root", subtree.Root) + c.detail("subtree.Root", subtree.Root) c.localVars[fname] = make(map[string]VarItemReflect) c.localVars[fname]["."] = VarItemReflect{".", varholder, holdreflect} @@ -943,13 +953,13 @@ func (c *CTemplateSet) compileSubtemplate(pvarholder string, pholdreflect reflec // TODO: Should we rethink the way the log methods work or their names? -func (c *CTemplateSet) log(args ...interface{}) { +func (c *CTemplateSet) detail(args ...interface{}) { if c.config.SuperDebug { fmt.Println(args...) } } -func (c *CTemplateSet) logf(left string, args ...interface{}) { +func (c *CTemplateSet) detailf(left string, args ...interface{}) { if c.config.SuperDebug { fmt.Printf(left, args...) } diff --git a/common/themes.go b/common/themes.go index dfb715a1..ae3d4563 100644 --- a/common/themes.go +++ b/common/themes.go @@ -71,6 +71,7 @@ type TemplateMapping struct { type ThemeResource struct { Name string Location string + Loggedin bool // Only serve this resource to logged in users } type ThemeStmts struct { diff --git a/config.go b/config_default.noparse similarity index 100% rename from config.go rename to config_default.noparse diff --git a/extend/adventure/lib/adventure.go b/extend/adventure/lib/adventure.go new file mode 100644 index 00000000..1a284f28 --- /dev/null +++ b/extend/adventure/lib/adventure.go @@ -0,0 +1,15 @@ +package adventure + +// We're experimenting with struct tags here atm +type Adventure struct { + ID int `schema:"name=aid;primary;auto"` + Name string `schema:"name=name;type=short_text"` + Desc string `schema:"name=desc;type=text"` + CreatedBy int `schema:"name=createdBy"` + //CreatedBy int `schema:"name=createdBy;relatesTo=users.uid"` +} + +// TODO: Should we add a table interface? +func (adventure *Adventure) GetTable() string { + return "adventure" +} diff --git a/extend/adventure/lib/adventure_store.go b/extend/adventure/lib/adventure_store.go new file mode 100644 index 00000000..42a62d9f --- /dev/null +++ b/extend/adventure/lib/adventure_store.go @@ -0,0 +1,8 @@ +package adventure + +type AdventureStore interface { + Create() (int, error) +} + +type DefaultAdventureStore struct { +} diff --git a/extend/adventure/plugin.json b/extend/adventure/plugin.json new file mode 100644 index 00000000..383999e6 --- /dev/null +++ b/extend/adventure/plugin.json @@ -0,0 +1,7 @@ +{ + "UName":"adventure", + "Name":"Adventure", + "Author":"Azareal", + "URL":"https://github.com/Azareal/Gosora", + "Skip":true +} \ No newline at end of file diff --git a/extend/adventure/prebuild/filler.txt b/extend/adventure/prebuild/filler.txt new file mode 100644 index 00000000..20e14b1e --- /dev/null +++ b/extend/adventure/prebuild/filler.txt @@ -0,0 +1 @@ +This file is here so that Git will include this folder in the repository. \ No newline at end of file diff --git a/extend/guilds/prebuild/filler.txt b/extend/guilds/prebuild/filler.txt new file mode 100644 index 00000000..20e14b1e --- /dev/null +++ b/extend/guilds/prebuild/filler.txt @@ -0,0 +1 @@ +This file is here so that Git will include this folder in the repository. \ No newline at end of file diff --git a/install-linux b/install-linux index 451908d2..caee966f 100644 --- a/install-linux +++ b/install-linux @@ -28,6 +28,9 @@ go get -u github.com/bamiaux/rez echo "Installing fsnotify" go get -u github.com/fsnotify/fsnotify +echo "Installing Go Git" +go get -u gopkg.in/src-d/go-git.v4/... + echo "Building the installer" cd ./install diff --git a/install.bat b/install.bat index 34c22631..2f4bebc5 100644 --- a/install.bat +++ b/install.bat @@ -85,6 +85,13 @@ if %errorlevel% neq 0 ( exit /b %errorlevel% ) +echo Installing Go Git +go get -u gopkg.in/src-d/go-git.v4/... +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) + echo Building the installer go generate diff --git a/install/install.go b/install/install.go index abe78bee..98bd795f 100644 --- a/install/install.go +++ b/install/install.go @@ -198,7 +198,8 @@ func handleDatabaseDetails() (adap install.InstallAdapter, ok bool) { var dbUsername string var dbPassword string var dbName string - var dbPort string + // TODO: Let the admin set the database port? + //var dbPort string for { fmt.Println("Which database adapter do you wish to use? mysql, mssql, or mysql? Default: mysql") diff --git a/langs/english.json b/langs/english.json index 500a15f9..20dad4af 100644 --- a/langs/english.json +++ b/langs/english.json @@ -231,7 +231,18 @@ "NoticePhrases": { "account_banned":"Your account has been suspended. Some of your permissions may have been revoked.", - "account_inactive":"Your account hasn't been activated yet. Some features may remain unavailable until it is." + "account_inactive":"Your account hasn't been activated yet. Some features may remain unavailable until it is.", + "account_password_updated":"Your password was successfully updated", + "account_avatar_updated":"Your avatar was successfully updated", + "account_username_updated":"Your username was successfully updated", + "account_mail_disabled":"The mail system is currently disabled.", + "account_mail_verify_success":"Your email was successfully verified", + + "panel_forum_created":"The forum was successfully created", + "panel_forum_deleted":"The forum was successfully deleted", + "panel_forum_updated":"The forum was successfully updated", + "panel_forum_perms_updated":"The forum permissions were successfully updated", + "panel_user_updated":"The user was successfully updated" }, "TmplPhrases": { diff --git a/main.go b/main.go index 5b036ba8..7a888a2d 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,7 @@ package main import ( + "flag" "fmt" "io" "log" @@ -217,6 +218,16 @@ func main() { } defer db.Close() + buildTemplates := flag.Bool("build-templates", false, "build the templates") + flag.Parse() + if *buildTemplates { + err = common.CompileTemplates() + if err != nil { + log.Fatal(err) + } + return + } + err = afterDBInit() if err != nil { log.Fatal(err) diff --git a/member_routes.go b/member_routes.go index d7a4160c..c85f1746 100644 --- a/member_routes.go +++ b/member_routes.go @@ -129,12 +129,12 @@ func routeProfileReplyCreateSubmit(w http.ResponseWriter, r *http.Request, user if err != nil { return common.LocalError("Invalid UID", w, r, user) } - + profileOwner, err := common.Users.Get(uid) if err == ErrNoRows { return common.LocalError("The profile you're trying to post on doesn't exist.", w, r, user) } else if err != nil { - return common.InternalError(err,w,r) + return common.InternalError(err, w, r) } content := common.PreparseMessage(r.PostFormValue("reply-content")) @@ -278,7 +278,7 @@ func routeAccountEditCriticalSubmit(w http.ResponseWriter, r *http.Request, user // Log the user out as a safety precaution common.Auth.ForceLogout(user.ID) - headerVars.NoticeList = append(headerVars.NoticeList, "Your password was successfully updated") + headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("account_password_updated")) pi := common.Page{"Edit Password", user, headerVars, tList, nil} if common.RunPreRenderHook("pre_render_account_own_edit_critical", w, r, &user, &pi) { return nil @@ -367,7 +367,7 @@ func routeAccountEditAvatarSubmit(w http.ResponseWriter, r *http.Request, user c return common.InternalError(err, w, r) } user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + "." + ext - headerVars.NoticeList = append(headerVars.NoticeList, "Your avatar was successfully updated") + headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("account_avatar_updated")) pi := common.Page{"Edit Avatar", user, headerVars, tList, nil} if common.RunPreRenderHook("pre_render_account_own_edit_avatar", w, r, &user, &pi) { @@ -410,7 +410,7 @@ func routeAccountEditUsernameSubmit(w http.ResponseWriter, r *http.Request, user } user.Name = newUsername - headerVars.NoticeList = append(headerVars.NoticeList, "Your username was successfully updated") + headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("account_username_updated")) pi := common.Page{"Edit Username", user, headerVars, tList, nil} if common.RunPreRenderHook("pre_render_account_own_edit_username", w, r, &user, &pi) { return nil @@ -461,7 +461,7 @@ func routeAccountEditEmail(w http.ResponseWriter, r *http.Request, user common.U emailList = append(emailList, email) } if !common.Site.EnableEmails { - headerVars.NoticeList = append(headerVars.NoticeList, "The mail system is currently disabled.") + headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("account_mail_disabled")) } pi := common.Page{"Email Manager", user, headerVars, emailList, nil} @@ -531,9 +531,9 @@ func routeAccountEditEmailTokenSubmit(w http.ResponseWriter, r *http.Request, us } if !common.Site.EnableEmails { - headerVars.NoticeList = append(headerVars.NoticeList, "The mail system is currently disabled.") + headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("account_mail_disabled")) } - headerVars.NoticeList = append(headerVars.NoticeList, "Your email was successfully verified") + headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("account_mail_verify_success")) pi := common.Page{"Email Manager", user, headerVars, emailList, nil} if common.RunPreRenderHook("pre_render_account_own_edit_email", w, r, &user, &pi) { return nil diff --git a/panel_routes.go b/panel_routes.go index ebba603b..3bab236e 100644 --- a/panel_routes.go +++ b/panel_routes.go @@ -198,11 +198,11 @@ func routePanelForums(w http.ResponseWriter, r *http.Request, user common.User) } if r.FormValue("created") == "1" { - headerVars.NoticeList = append(headerVars.NoticeList, "The forum was successfully created") + headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("panel_forum_created")) } else if r.FormValue("deleted") == "1" { - headerVars.NoticeList = append(headerVars.NoticeList, "The forum was successfully deleted") + headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("panel_forum_deleted")) } else if r.FormValue("updated") == "1" { - headerVars.NoticeList = append(headerVars.NoticeList, "The forum was successfully updated") + headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("panel_forum_updated")) } pi := common.PanelPage{common.GetTitlePhrase("panel_forums"), user, headerVars, stats, "forums", forumList, nil} @@ -335,7 +335,7 @@ func routePanelForumsEdit(w http.ResponseWriter, r *http.Request, user common.Us } if r.FormValue("updated") == "1" { - headerVars.NoticeList = append(headerVars.NoticeList, "The forum was successfully updated") + headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("panel_forum_updated")) } pi := common.PanelEditForumPage{common.GetTitlePhrase("panel_edit_forum"), user, headerVars, stats, "forums", forum.ID, forum.Name, forum.Desc, forum.Active, forum.Preset, gplist} @@ -501,7 +501,7 @@ func routePanelForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, us addNameLangToggle("MoveTopic", forumPerms.MoveTopic) if r.FormValue("updated") == "1" { - headerVars.NoticeList = append(headerVars.NoticeList, "The forum permissions were successfully updated") + headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("panel_forums_perms_updated")) } pi := common.PanelEditForumGroupPage{common.GetTitlePhrase("panel_edit_forum"), user, headerVars, stats, "forums", forum.ID, gid, forum.Name, forum.Desc, forum.Active, forum.Preset, formattedPermList} @@ -1794,7 +1794,7 @@ func routePanelUsersEdit(w http.ResponseWriter, r *http.Request, user common.Use } if r.FormValue("updated") == "1" { - headerVars.NoticeList = append(headerVars.NoticeList, "The user was successfully updated") + headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("panel_user_updated")) } pi := common.PanelPage{common.GetTitlePhrase("panel_edit_user"), user, headerVars, stats, "users", groupList, targetUser} diff --git a/plugin_adventure.go b/plugin_adventure.go new file mode 100644 index 00000000..3f07dbe0 --- /dev/null +++ b/plugin_adventure.go @@ -0,0 +1,20 @@ +// WIP - Experimental adventure plugin, this might find a new home soon, but it's here to stress test Gosora's extensibility for now +package main + +import "./common" + +func init() { + common.Plugins["adventure"] = common.NewPlugin("adventure", "WIP", "Azareal", "http://github.com/Azareal", "", "", "", initAdventure, nil, deactivateAdventure, installAdventure, nil) +} + +func initAdventure() error { + return nil +} + +// TODO: Change the signature to return an error? +func deactivateAdventure() { +} + +func installAdventure() error { + return nil +} diff --git a/run-linux b/run-linux index aa81c8ba..fa1e7cfd 100644 --- a/run-linux +++ b/run-linux @@ -2,5 +2,7 @@ echo "Generating the dynamic code" go generate echo "Building Gosora" go build -o Gosora +echo "Building the templates" +./Gosora -build-templates echo "Running Gosora" ./Gosora \ No newline at end of file diff --git a/run-linux-nowebsockets b/run-linux-nowebsockets index 0360c35d..32f35fd1 100644 --- a/run-linux-nowebsockets +++ b/run-linux-nowebsockets @@ -2,5 +2,7 @@ echo "Generating the dynamic code" go generate echo "Building Gosora" go build -o Gosora -tags no_ws +echo "Building the templates" +./Gosora -build-templates echo "Running Gosora" ./Gosora diff --git a/run-nowebsockets.bat b/run-nowebsockets.bat index ccc7db35..25ffe69f 100644 --- a/run-nowebsockets.bat +++ b/run-nowebsockets.bat @@ -14,6 +14,10 @@ if %errorlevel% neq 0 ( ) echo Running the router generator router_gen.exe +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) echo Building the query generator go build ./query_gen @@ -23,6 +27,10 @@ if %errorlevel% neq 0 ( ) echo Running the query generator query_gen.exe +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) echo Building the executable go build -o gosora.exe -tags no_ws @@ -31,6 +39,13 @@ if %errorlevel% neq 0 ( exit /b %errorlevel% ) +echo Building the templates +gosora.exe -build-templates +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) + echo Running Gosora gosora.exe pause \ No newline at end of file diff --git a/run.bat b/run.bat index 85f1b775..0e14741a 100644 --- a/run.bat +++ b/run.bat @@ -14,6 +14,10 @@ if %errorlevel% neq 0 ( ) echo Running the router generator router_gen.exe +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) echo Building the query generator go build ./query_gen @@ -23,6 +27,10 @@ if %errorlevel% neq 0 ( ) echo Running the query generator query_gen.exe +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) echo Building the executable go build -o gosora.exe @@ -31,6 +39,13 @@ if %errorlevel% neq 0 ( exit /b %errorlevel% ) +echo Building the templates +gosora.exe -build-templates +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) + echo Running Gosora gosora.exe rem Or you could redirect the output to a file diff --git a/run_mssql.bat b/run_mssql.bat index ed968f07..6a703423 100644 --- a/run_mssql.bat +++ b/run_mssql.bat @@ -14,6 +14,10 @@ if %errorlevel% neq 0 ( ) echo Running the router generator router_gen.exe +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) echo Building the query generator go build ./query_gen @@ -23,6 +27,10 @@ if %errorlevel% neq 0 ( ) echo Running the query generator query_gen.exe +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) echo Building the executable go build -o gosora.exe -tags mssql @@ -31,6 +39,13 @@ if %errorlevel% neq 0 ( exit /b %errorlevel% ) +echo Building the templates +gosora.exe -build-templates +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) + echo Running Gosora gosora.exe pause \ No newline at end of file diff --git a/run_tests.bat b/run_tests.bat index e6b1ec5a..d3c86d9c 100644 --- a/run_tests.bat +++ b/run_tests.bat @@ -14,6 +14,10 @@ if %errorlevel% neq 0 ( ) echo Running the router generator router_gen.exe +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) echo Building the query generator go build ./query_gen @@ -23,6 +27,10 @@ if %errorlevel% neq 0 ( ) echo Running the query generator query_gen.exe +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) echo Building the executable go test diff --git a/run_tests_mssql.bat b/run_tests_mssql.bat index f2b8aa95..119319e9 100644 --- a/run_tests_mssql.bat +++ b/run_tests_mssql.bat @@ -14,6 +14,10 @@ if %errorlevel% neq 0 ( ) echo Running the router generator router_gen.exe +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) echo Building the query generator go build ./query_gen @@ -23,6 +27,10 @@ if %errorlevel% neq 0 ( ) echo Running the query generator query_gen.exe +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) echo Building the executable go test -tags mssql diff --git a/schema/schema.json b/schema/schema.json new file mode 100644 index 00000000..68b3d0e2 --- /dev/null +++ b/schema/schema.json @@ -0,0 +1,3 @@ +{ + "Version":"0" +} \ No newline at end of file diff --git a/templates/overrides/filler.txt b/templates/overrides/filler.txt new file mode 100644 index 00000000..20e14b1e --- /dev/null +++ b/templates/overrides/filler.txt @@ -0,0 +1 @@ +This file is here so that Git will include this folder in the repository. \ No newline at end of file diff --git a/themes/cosora/theme.json b/themes/cosora/theme.json index 3718d748..ff7dd109 100644 --- a/themes/cosora/theme.json +++ b/themes/cosora/theme.json @@ -19,11 +19,13 @@ }, { "Name":"trumbowyg/trumbowyg.min.js", - "Location":"global" + "Location":"global", + "Loggedin": true }, { "Name":"trumbowyg/ui/trumbowyg.custom.css", - "Location":"global" + "Location":"global", + "Loggedin":true }, { "Name":"cosora/misc.js", diff --git a/update-deps-linux b/update-deps-linux index 21d1305a..90c897ac 100644 --- a/update-deps-linux +++ b/update-deps-linux @@ -26,4 +26,7 @@ echo "Updating the Rez Image Resizer" go get -u github.com/bamiaux/rez echo "Updating fsnotify" -go get -u github.com/fsnotify/fsnotify \ No newline at end of file +go get -u github.com/fsnotify/fsnotify + +echo "Updating Go Git" +go get -u gopkg.in/src-d/go-git.v4/... \ No newline at end of file diff --git a/update-deps.bat b/update-deps.bat index 510cb126..78b218f8 100644 --- a/update-deps.bat +++ b/update-deps.bat @@ -82,5 +82,12 @@ if %errorlevel% neq 0 ( exit /b %errorlevel% ) +echo Updating Go Git +go get -u gopkg.in/src-d/go-git.v4/... +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) + echo The dependencies were successfully updated pause diff --git a/update.bat b/update.bat new file mode 100644 index 00000000..b20e50e7 --- /dev/null +++ b/update.bat @@ -0,0 +1,103 @@ +@echo off +echo Updating the dependencies + +echo Updating the MySQL Driver +go get -u github.com/go-sql-driver/mysql +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) + +echo Updating the PostgreSQL Driver +go get -u github.com/lib/pq +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) + +echo Updating the MSSQL Driver +go get -u github.com/denisenkom/go-mssqldb +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) + +echo Updating the bcrypt library +go get -u golang.org/x/crypto/bcrypt +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) + +echo Updating /x/sys/windows (dependency for gopsutil) +go get -u golang.org/x/sys/windows +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) + +echo Updating wmi (dependency for gopsutil) +go get -u github.com/StackExchange/wmi +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) + +echo Updating the gopsutil library +go get -u github.com/Azareal/gopsutil +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) + +echo Updating the WebSockets library +go get -u github.com/gorilla/websocket +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) + +echo Updating Sourcemap (dependency for OttoJS) +go get -u gopkg.in/sourcemap.v1 +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) + +echo Updating OttoJS +go get -u github.com/robertkrimen/otto +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) + +echo Updating the Rez Image Resizer +go get -u github.com/bamiaux/rez +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) + +echo Updating fsnotify +go get -u github.com/fsnotify/fsnotify +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) + +echo Updating Go Git +go get -u gopkg.in/src-d/go-git.v4/... +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) + + +echo Building the updater +go generate +go build ./updater +if %errorlevel% neq 0 ( + pause + exit /b %errorlevel% +) +updater.exe diff --git a/updater/main.go b/updater/main.go new file mode 100644 index 00000000..9146b0f4 --- /dev/null +++ b/updater/main.go @@ -0,0 +1,68 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "runtime/debug" + + "gopkg.in/src-d/go-git.v4" +) + +func main() { + scanner := bufio.NewScanner(os.Stdin) + + // Capture panics instead of closing the window at a superhuman speed before the user can read the message on Windows + defer func() { + r := recover() + if r != nil { + fmt.Println(r) + debug.PrintStack() + pressAnyKey(scanner) + return + } + }() + + err := updater(scanner) + if err != nil { + fmt.Println(err) + } +} + +func pressAnyKey(scanner *bufio.Scanner) { + fmt.Println("Please press enter to exit...") + for scanner.Scan() { + _ = scanner.Text() + return + } +} + +func updater(scanner *bufio.Scanner) error { + fmt.Println("Welcome to Gosora's Upgrader") + fmt.Print("We're going to check for new updates, please wait patiently") + + repo, err := git.PlainOpen("./.git") + if err != nil { + return err + } + + workTree, err := repo.Worktree() + if err != nil { + return err + } + + err = workTree.Pull(&git.PullOptions{RemoteName: "origin"}) + if err != nil { + return err + } + + fmt.Println("Updated to the latest commit") + headRef, err := repo.Head() + if err != nil { + return err + } + + fmt.Println("Commit details:") + commit, err := repo.CommitObject(headRef.Hash()) + return err +}