Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ branches:
- /^v[0-9]\.[0-9]/

go:
- 1.7.x
- 1.8
- 1.8.x
- tip
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# essentials - aah framework
[![Build Status](https://travis-ci.org/go-aah/essentials.svg?branch=master)](https://travis-ci.org/go-aah/essentials) [![codecov](https://codecov.io/gh/go-aah/essentials/branch/master/graph/badge.svg)](https://codecov.io/gh/go-aah/essentials/branch/master) [![Go Report Card](https://goreportcard.com/badge/aahframework.org/essentials.v0)](https://goreportcard.com/report/aahframework.org/essentials.v0)
[![Version](https://img.shields.io/badge/version-0.5-blue.svg)](https://github.com/go-aah/essentials/releases/latest) [![GoDoc](https://godoc.org/aahframework.org/essentials.v0?status.svg)](https://godoc.org/aahframework.org/essentials.v0) [![License](https://img.shields.io/github/license/go-aah/essentials.svg)](LICENSE)
[![Version](https://img.shields.io/badge/version-0.6-blue.svg)](https://github.com/go-aah/essentials/releases/latest) [![GoDoc](https://godoc.org/aahframework.org/essentials.v0?status.svg)](https://godoc.org/aahframework.org/essentials.v0) [![License](https://img.shields.io/github/license/go-aah/essentials.svg)](LICENSE)

***v0.5 [released](https://github.com/go-aah/essentials/releases/latest) and tagged on Apr 07, 2017***
***v0.6 [released](https://github.com/go-aah/essentials/releases/latest) and tagged on Jul 22, 2017***

`essentials` contains simple & useful utils methods for Go. aah framework utilizes essentials (aka `ess`) library across. Essentials library complements with handy methods, refer godoc to know more about methods:
* filepath
Expand All @@ -24,4 +24,4 @@
go get -u aahframework.org/essentials.v0
```

See official page [TODO]
Visit official website https://aahframework.org to learn more.
9 changes: 9 additions & 0 deletions archive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package ess

import (
"io/ioutil"
"strings"
"testing"

"aahframework.org/test.v0/assert"
Expand Down Expand Up @@ -39,4 +40,12 @@ func TestArchiveZip(t *testing.T) {
err := Zip(zipName, join(testdataPath, "dirpaths"))
assert.Nil(t, err)
assert.True(t, IsFileExists(zipName))

err = Zip(zipName, join(testdataPath, "dirpaths1"))
assert.NotNil(t, err)
assert.True(t, strings.HasPrefix(err.Error(), "source does not exists:"))

err = Zip(zipName, join(testdataPath, "dirpaths"))
assert.NotNil(t, err)
assert.True(t, strings.HasPrefix(err.Error(), "destination archive already exists:"))
}
2 changes: 1 addition & 1 deletion essentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
package ess

// Version no. of essentials library
var Version = "0.5"
var Version = "0.6"
34 changes: 32 additions & 2 deletions filepath.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,23 @@ func DeleteFiles(files ...string) (errs []error) {

// DirsPath method returns all directories absolute path from given base path recursively.
func DirsPath(basePath string, recursive bool) (pdirs []string, err error) {
return DirsPathExcludes(basePath, recursive, Excludes{})
}

// DirsPathExcludes method returns all directories absolute path from given base path recursively
// excluding the excludes list.
func DirsPathExcludes(basePath string, recursive bool, excludes Excludes) (pdirs []string, err error) {
if err = excludes.Validate(); err != nil {
return
}

if recursive {
err = Walk(basePath, func(srcPath string, info os.FileInfo, err error) error {
if info.IsDir() && excludes.Match(filepath.Base(srcPath)) {
// excluding directory
return filepath.SkipDir
}

if info.IsDir() {
pdirs = append(pdirs, srcPath)
}
Expand All @@ -286,7 +301,7 @@ func DirsPath(basePath string, recursive bool) (pdirs []string, err error) {
}

for _, v := range list {
if v.IsDir() {
if v.IsDir() && !excludes.Match(v.Name()) {
pdirs = append(pdirs, filepath.Join(basePath, v.Name()))
}
}
Expand All @@ -296,8 +311,23 @@ func DirsPath(basePath string, recursive bool) (pdirs []string, err error) {

// FilesPath method returns all files absolute path from given base path recursively.
func FilesPath(basePath string, recursive bool) (files []string, err error) {
return FilesPathExcludes(basePath, recursive, Excludes{})
}

// FilesPathExcludes method returns all files absolute path from given base path recursively
// excluding the excludes list.
func FilesPathExcludes(basePath string, recursive bool, excludes Excludes) (files []string, err error) {
if err = excludes.Validate(); err != nil {
return
}

if recursive {
err = Walk(basePath, func(srcPath string, info os.FileInfo, err error) error {
if !info.IsDir() && excludes.Match(filepath.Base(srcPath)) {
// excluding file
return nil
}

if !info.IsDir() {
files = append(files, srcPath)
}
Expand All @@ -313,7 +343,7 @@ func FilesPath(basePath string, recursive bool) (files []string, err error) {
}

for _, v := range list {
if !v.IsDir() {
if !v.IsDir() && !excludes.Match(v.Name()) {
files = append(files, filepath.Join(basePath, v.Name()))
}
}
Expand Down
11 changes: 11 additions & 0 deletions filepath_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,9 @@ func TestStripExt(t *testing.T) {

name3 := StripExt("")
assert.Equal(t, "", name3)

name4 := StripExt("myname")
assert.Equal(t, "myname", name4)
}

func TestDirPaths(t *testing.T) {
Expand Down Expand Up @@ -250,6 +253,10 @@ func TestDirPaths(t *testing.T) {
assert.True(t, IsSliceContainsString(dirs, path11))
assert.True(t, IsSliceContainsString(dirs, path12))
assert.False(t, IsSliceContainsString(dirs, join(path22, "not-exists")))

dirs, err = DirsPathExcludes(join(testdataPath, "dirpaths"), true, Excludes{"level1-2", "level2-2"})
assert.FailOnError(t, err, "unable to get directory list")
assert.True(t, len(dirs) == 6)
}

func TestFilesPath(t *testing.T) {
Expand Down Expand Up @@ -284,4 +291,8 @@ func TestFilesPath(t *testing.T) {
files, err = FilesPath(path11, false)
assert.Nil(t, err)
assert.True(t, strings.HasSuffix(files[0], "file11.txt"))

files, err = FilesPathExcludes(join(testdataPath, "dirpaths"), true, Excludes{"file12.txt", "file22.txt"})
assert.Nil(t, err)
assert.True(t, len(files) == 3)
}
75 changes: 75 additions & 0 deletions fmt_flag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright (c) Jeevanandam M. (https://github.com/jeevatkm)
// go-aah/essentials source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.

package ess

import (
"fmt"
"strings"
)

var (
// FmtFlagSeparator is used parse flags pattern.
FmtFlagSeparator = "%"

// FmtFlagValueSeparator is used to parse into flag and value.
FmtFlagValueSeparator = ":"

defaultFormat = "%v"
)

type (
// FmtFlagPart is indiviual flag details
// For e.g.:
// part := FmtFlagPart{
// Flag: FmtFlagTime,
// Name: "time",
// Format: "2006-01-02 15:04:05.000",
// }
FmtFlagPart struct {
Flag FmtFlag
Name string
Format string
}

// FmtFlag type definition
FmtFlag uint8
)

// ParseFmtFlag it parses the given pattern, format flags into format flag parts.
// For e.g.:
// %time:2006-01-02 15:04:05.000 %level:-5 %message
// %clientip %reqid %reqtime %restime %resstatus %ressize %reqmethod %requrl %reqhdr:Referer %reshdr:Server
func ParseFmtFlag(pattern string, fmtFlags map[string]FmtFlag) ([]FmtFlagPart, error) {
var flagParts []FmtFlagPart
pattern = strings.TrimSpace(pattern)
formatFlags := strings.Split(pattern, FmtFlagSeparator)[1:]
for _, f := range formatFlags {
f = strings.TrimSpace(f)
parts := strings.SplitN(f, FmtFlagValueSeparator, 2)
flag, found := fmtFlags[parts[0]]
if !found {
return nil, fmt.Errorf("fmtflag: unknown flag '%s'", f)
}

part := FmtFlagPart{Flag: flag, Name: parts[0]}
switch len(parts) {
case 2:
// handle `time` related flag, `custom` flag
// and `hdr` flag particularly
if strings.Contains(parts[0], "time") || parts[0] == "custom" ||
strings.HasSuffix(parts[0], "hdr") {
part.Format = parts[1]
} else {
part.Format = "%" + parts[1] + "v"
}
default:
part.Format = defaultFormat
}

flagParts = append(flagParts, part)
}

return flagParts, nil
}
100 changes: 100 additions & 0 deletions fmt_flag_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright (c) Jeevanandam M. (https://github.com/jeevatkm)
// go-aah/essentials source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.

package ess

import (
"testing"

"aahframework.org/test.v0/assert"
)

func TestFmtParseFlagLog(t *testing.T) {
const (
FmtFlagLevel FmtFlag = iota
FmtFlagTime
FmtFlagUTCTime
FmtFlagLongfile
FmtFlagShortfile
FmtFlagLine
FmtFlagMessage
FmtFlagCustom
)

logFmtFlags := map[string]FmtFlag{
"level": FmtFlagLevel,
"time": FmtFlagTime,
"utctime": FmtFlagUTCTime,
"longfile": FmtFlagLongfile,
"shortfile": FmtFlagShortfile,
"line": FmtFlagLine,
"message": FmtFlagMessage,
"custom": FmtFlagCustom,
}

flagParts, err := ParseFmtFlag("%time:2006-01-02 15:04:05.000 %level %custom:- %message", logFmtFlags)
assert.Nil(t, err)

assertFlagPart(t, "time", "2006-01-02 15:04:05.000", FmtFlag(1), flagParts[0])
assertFlagPart(t, "level", "%v", FmtFlag(0), flagParts[1])
assertFlagPart(t, "custom", "-", FmtFlag(7), flagParts[2])
assertFlagPart(t, "message", "%v", FmtFlag(6), flagParts[3])

// Unknown flag
flagParts, err = ParseFmtFlag("%myflag", logFmtFlags)
assert.NotNil(t, err)
assert.Equal(t, "fmtflag: unknown flag 'myflag'", err.Error())
assert.True(t, len(flagParts) == 0)
}

func TestFmtParseFlagAccessLog(t *testing.T) {
const (
fmtFlagClientIP FmtFlag = iota
fmtFlagRequestTime
fmtFlagRequestURL
fmtFlagRequestMethod
fmtFlagRequestID
fmtFlagRequestHeader
fmtFlagQueryString
fmtFlagResponseStatus
fmtFlagResponseSize
fmtFlagResponseHeader
fmtFlagResponseTime
)

accessLogFmtFlags := map[string]FmtFlag{
"clientip": fmtFlagClientIP,
"reqtime": fmtFlagRequestTime,
"requrl": fmtFlagRequestURL,
"reqmethod": fmtFlagRequestMethod,
"reqid": fmtFlagRequestID,
"reqhdr": fmtFlagRequestHeader,
"querystr": fmtFlagQueryString,
"resstatus": fmtFlagResponseStatus,
"ressize": fmtFlagResponseSize,
"reshdr": fmtFlagResponseHeader,
"restime": fmtFlagResponseTime,
}

flagParts, err := ParseFmtFlag("%clientip %reqid %reqtime %restime %resstatus %ressize %reqmethod %requrl %reqhdr:Referer %reshdr:Server", accessLogFmtFlags)
assert.Nil(t, err)

assertFlagPart(t, "clientip", "%v", FmtFlag(0), flagParts[0])
assertFlagPart(t, "reqid", "%v", FmtFlag(4), flagParts[1])
assertFlagPart(t, "reqtime", "%v", FmtFlag(1), flagParts[2])
assertFlagPart(t, "restime", "%v", FmtFlag(10), flagParts[3])
assertFlagPart(t, "resstatus", "%v", FmtFlag(7), flagParts[4])
assertFlagPart(t, "ressize", "%v", FmtFlag(8), flagParts[5])
assertFlagPart(t, "reqmethod", "%v", FmtFlag(3), flagParts[6])
assertFlagPart(t, "requrl", "%v", FmtFlag(2), flagParts[7])
assertFlagPart(t, "reqhdr", "Referer", FmtFlag(5), flagParts[8])
assertFlagPart(t, "reshdr", "Server", FmtFlag(9), flagParts[9])
}

func assertFlagPart(t *testing.T, name, format string, fflag FmtFlag, flagPart FmtFlagPart) {
t.Logf("Fmt Flag: %v", format)
assert.Equal(t, name, flagPart.Name)
assert.Equal(t, format, flagPart.Format)
assert.Equal(t, fflag, flagPart.Flag)
}
2 changes: 1 addition & 1 deletion guid.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ var (
)

//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// Global methods
// Package methods
//___________________________________

// NewGUID method returns a new Globally Unique identifier (GUID).
Expand Down
6 changes: 3 additions & 3 deletions guid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,21 @@ type guidParts struct {
}

var uniqueIds = []guidParts{
guidParts{
{
"4d88e15b60f486e428412dc9",
1300816219,
[]byte{0x60, 0xf4, 0x86},
0xe428,
4271561,
},
guidParts{
{
"000000000000000000000000",
0,
[]byte{0x00, 0x00, 0x00},
0x0000,
0,
},
guidParts{
{
"00000000aabbccddee000001",
0,
[]byte{0xaa, 0xbb, 0xcc},
Expand Down
4 changes: 4 additions & 0 deletions io.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import "io"
// about error while `Close()` and helpful for code quality too.
func CloseQuietly(c ...interface{}) {
for _, v := range c {
if v == nil {
continue
}

if d, ok := v.(io.Closer); ok {
_ = d.Close()
}
Expand Down
2 changes: 1 addition & 1 deletion io_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ func TestCloseQuietly(t *testing.T) {

assert.FailOnError(t, err, "")

CloseQuietly(file)
CloseQuietly(file, nil)
}