Skip to content

Commit

Permalink
Merge b717104 into 60bd1e5
Browse files Browse the repository at this point in the history
  • Loading branch information
roblillack committed Mar 23, 2021
2 parents 60bd1e5 + b717104 commit 12f052e
Show file tree
Hide file tree
Showing 36 changed files with 562 additions and 441 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ env:
- GO111MODULE=on

go:
- 1.12
- 1.13
- 1.14
- 1.15
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2015–2020 Rob Lillack
Copyright (c) 2015–2021 Rob Lillack
Copyright (C) 2012 Rob Figueiredo
All Rights Reserved.

Expand Down
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,33 @@ Mars is a fork of the fantastic, yet not-that-idiomatic-and-pretty-much-abandone

## Quick Start

Hah. Sorry, nothing here, yet. But if you want to switch a Revel project to Mars--see below.
Getting started with Mars is as easy as:

1. Adding the package to your project

```sh
$ go get github.com/roblillack/mars
```

2. Creating an empty routes file in `conf/routes`

```sh
$ mkdir conf; echo > conf/routes
```

3. Running the server as part of your main package

```go
package main

import "github.com/roblillack/mars"

func main() {
mars.Run()
}
```

This essentially sets up an insecure server as part of your application that listens to HTTP (only) and responds to all requests with a 404. To learn where to go from here, please see the [Mars tutorial](http://mars.readthedocs.io/en/latest/getting-started/)

## Differences to Revel

Expand Down
2 changes: 1 addition & 1 deletion binder.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ func unbindSlice(output map[string]string, name string, val interface{}) {
func bindStruct(params *Params, name string, typ reflect.Type) reflect.Value {
result := reflect.New(typ).Elem()
fieldValues := make(map[string]reflect.Value)
for key, _ := range params.Values {
for key := range params.Values {
if !strings.HasPrefix(key, name+".") {
continue
}
Expand Down
12 changes: 6 additions & 6 deletions binder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,28 +274,28 @@ var unbinderTestCases = map[string]interface{}{
// Some of the unbinding results are not exactly what is in PARAMS, since it
// serializes implicit zero values explicitly.
var unbinderOverrideAnswers = map[string]map[string]string{
"arr": map[string]string{
"arr": {
"arr[0]": "1",
"arr[1]": "2",
"arr[2]": "0",
"arr[3]": "3",
},
"A": map[string]string{
"A": {
"A.ID": "123",
"A.Name": "rob",
"A.B.Extra": "",
},
"arrC": map[string]string{
"arrC": {
"arrC[0].ID": "5",
"arrC[0].Name": "rob",
"arrC[0].B.Extra": "foo",
"arrC[1].ID": "8",
"arrC[1].Name": "bill",
"arrC[1].B.Extra": "",
},
"m": map[string]string{"m[a]": "foo", "m[b]": "bar"},
"m2": map[string]string{"m2[1]": "foo", "m2[2]": "bar"},
"m3": map[string]string{"m3[a]": "1", "m3[b]": "2"},
"m": {"m[a]": "foo", "m[b]": "bar"},
"m2": {"m2[1]": "foo", "m2[2]": "bar"},
"m3": {"m3[a]": "1", "m3[b]": "2"},
}

func TestUnbinder(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions cert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (

func TestCertificateCreation(t *testing.T) {
for org, domains := range map[string][]string{
"ACME Inc.": []string{"acme.com", "acme.biz"},
"Me": []string{"::1", "127.0.0.1"},
"ACME Inc.": {"acme.com", "acme.biz"},
"Me": {"::1", "127.0.0.1"},
} {
keypair, err := createCertificate(org, strings.Join(domains, ", "))
if err != nil {
Expand Down
12 changes: 8 additions & 4 deletions cmd/mars-gen/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"bytes"
"fmt"
"go/format"
"os"
Expand All @@ -9,8 +10,6 @@ import (
"time"

"github.com/codegangsta/cli"

"github.com/roblillack/mars"
)

func fatalf(layout string, args ...interface{}) {
Expand Down Expand Up @@ -109,7 +108,12 @@ func reverseRoutes(ctx *cli.Context) {
}

func generateSources(tpl, filename string, templateArgs map[string]interface{}) {
sourceCode := mars.ExecuteTemplate(template.Must(template.New("").Parse(tpl)), templateArgs)
var b bytes.Buffer

tmpl := template.Must(template.New("").Parse(tpl))
if err := tmpl.Execute(&b, templateArgs); err != nil {
fatalf("Unable to create source file: %v", err)
}

if err := os.MkdirAll(path.Dir(filename), 0755); err != nil {
fatalf("Unable to create dir: %v", err)
Expand All @@ -122,7 +126,7 @@ func generateSources(tpl, filename string, templateArgs map[string]interface{})
}
defer file.Close()

formatted, err := format.Source([]byte(sourceCode))
formatted, err := format.Source(b.Bytes())
if err != nil {
fatalf("Failed to format file: %v", err)
}
Expand Down
25 changes: 20 additions & 5 deletions cmd/mars-gen/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ type SourceInfo struct {
// controllerSpecs lists type info for all structs found under
// app/controllers/... that embed (directly or indirectly) mars.Controller
controllerSpecs []*TypeInfo
// testSuites list the types that constitute the set of application tests.
testSuites []*TypeInfo
}

// TypeInfo summarizes information about a struct type in the app source code.
Expand Down Expand Up @@ -445,6 +443,15 @@ func getStructTypeDecl(decl ast.Decl, fset *token.FileSet) (spec *ast.TypeSpec,
return
}

func containsString(list []string, target string) bool {
for _, el := range list {
if el == target {
return true
}
}
return false
}

// TypesThatEmbed returns all types that (directly or indirectly) embed the
// target type, which must be a fully qualified type name,
// e.g. "github.com/roblillack/mars.Controller"
Expand All @@ -462,8 +469,7 @@ func (s *SourceInfo) TypesThatEmbed(targetType string) (filtered []*TypeInfo) {
// Look through all known structs.
for _, spec := range s.StructSpecs {
// If this one has been processed or is already in nodeQueue, then skip it.
if mars.ContainsString(processed, spec.String()) ||
mars.ContainsString(nodeQueue, spec.String()) {
if containsString(processed, spec.String()) || containsString(nodeQueue, spec.String()) {
continue
}

Expand Down Expand Up @@ -502,10 +508,19 @@ type TypeExpr struct {
Valid bool
}

func firstNonEmpty(strs ...string) string {
for _, str := range strs {
if len(str) > 0 {
return str
}
}
return ""
}

// TypeName returns the fully-qualified type name for this expression.
// The caller may optionally specify a package name to override the default.
func (e TypeExpr) TypeName(pkgOverride string) string {
pkgName := mars.FirstNonEmpty(pkgOverride, e.PkgName)
pkgName := firstNonEmpty(pkgOverride, e.PkgName)
if pkgName == "" {
return e.Expr
}
Expand Down
20 changes: 20 additions & 0 deletions cookie.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package mars

import (
"net/url"
"regexp"
)

var (
cookieKeyValueParser = regexp.MustCompile("\x00([^:]*):([^\x00]*)\x00")
)

// parseKeyValueCookie takes the raw (escaped) cookie value and parses out key values.
func parseKeyValueCookie(val string, cb func(key, val string)) {
val, _ = url.QueryUnescape(val)
if matches := cookieKeyValueParser.FindAllStringSubmatch(val, -1); matches != nil {
for _, match := range matches {
cb(match[1], match[2])
}
}
}
21 changes: 9 additions & 12 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,23 @@
There is _no_ fixed directory hierarchy with Mars, but a projects' structure typically looks like this:

```
- $GOPATH/src/myProject (Your project)
- myProject (Your project)
|
|-- main.go (Your main go code can live here)
|-- main.go (Your main go code might live here, but can also be in ./cmd/something)
|
|-- conf (Directory with configuration files which are needed at runtime)
| |
| |-- app.conf (main configuration file)
| |
| |-- routes (Configuration of the routes)
| +-- routes (Configuration of the routes)
|
|-- views (All the view templates are here)
| |
| |-- hotel (main configuration file)
| |-- hotel (view templates for the “Hotel” controller)
| |
| |-- routes (Configuration of the routes)
| +-- other (view templates for the “Other” controller)
|
|-- mySubpackage (Your code is in arbitrary sub packages)
| |
| |-- foo.go
|
|-- vendor (Your vendored dependencies are here)
|-- ...
```
+-- mySubpackage (Your code is in arbitrary sub packages)
|
+-- foo.go
```
6 changes: 6 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ type Error struct {
Link string // A configurable link to wrap the error source in
}

var _ error = &Error{}

// An object to hold the per-source-line details.
type sourceLine struct {
Source string
Expand All @@ -27,6 +29,10 @@ type sourceLine struct {
// Construct a plaintext version of the error, taking account that fields are optionally set.
// Returns e.g. Compilation Error (in views/header.html:51): expected right delim in end; got "}"
func (e *Error) Error() string {
if e == nil {
return "<nil>"
}

loc := ""
if e.Path != "" {
line := ""
Expand Down
14 changes: 7 additions & 7 deletions fakeapp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,19 @@ func (c MyStatic) Serve(prefix, filepath string) Result {
func startFakeBookingApp() {
RegisterController((*Hotels)(nil),
[]*MethodType{
&MethodType{
{
Name: "Index",
},
&MethodType{
{
Name: "Boom",
},
&MethodType{
{
Name: "Show",
Args: []*MethodArg{
{"id", reflect.TypeOf((*int)(nil))},
},
},
&MethodType{
{
Name: "Book",
Args: []*MethodArg{
{"id", reflect.TypeOf((*int)(nil))},
Expand All @@ -86,11 +86,11 @@ func startFakeBookingApp() {

RegisterController((*Static)(nil),
[]*MethodType{
&MethodType{
{
Name: "Serve",
Args: []*MethodArg{
&MethodArg{Name: "prefix", Type: reflect.TypeOf((*string)(nil))},
&MethodArg{Name: "filepath", Type: reflect.TypeOf((*string)(nil))},
{Name: "prefix", Type: reflect.TypeOf((*string)(nil))},
{Name: "filepath", Type: reflect.TypeOf((*string)(nil))},
},
},
})
Expand Down
2 changes: 1 addition & 1 deletion filterconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func FilterAction(methodRef interface{}) FilterConfigurator {
}

controllerType := methodType.In(0)
method := FindMethod(controllerType, methodValue)
method := findMethod(controllerType, methodValue)
if method == nil {
panic("Action not found on controller " + controllerType.Name())
}
Expand Down
2 changes: 1 addition & 1 deletion flash.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func restoreFlash(req *http.Request) Flash {
Out: make(map[string]string),
}
if cookie, err := req.Cookie(CookiePrefix + "_FLASH"); err == nil {
ParseKeyValueCookie(cookie.Value, func(key, val string) {
parseKeyValueCookie(cookie.Value, func(key, val string) {
flash.Data[key] = val
})
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/roblillack/mars

go 1.12
go 1.13

require (
github.com/agtorre/gocolorize v1.0.0
Expand Down
2 changes: 1 addition & 1 deletion i18n.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ var (
func MessageLanguages() []string {
languages := make([]string, len(messages))
i := 0
for language, _ := range messages {
for language := range messages {
languages[i] = language
i++
}
Expand Down
2 changes: 1 addition & 1 deletion internal/pathtree/tree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ func BenchmarkTree100(b *testing.B) {
b.ResetTimer()

for i := 0; i < b.N/len(queries); i++ {
for k, _ := range queries {
for k := range queries {
n.Find(k)
}
}
Expand Down

0 comments on commit 12f052e

Please sign in to comment.