Introduce FilepathPathBridge

This commit introduces the new interface FilepathPathBridge to remove some code that differs only in their use of either the path or filepath package.
This commit is contained in:
bep 2015-01-27 11:44:41 +01:00
parent 5f9596e68c
commit bedc2d8488
3 changed files with 85 additions and 37 deletions

View file

@ -26,6 +26,44 @@ import (
"unicode" "unicode"
) )
// Bridge for common functionality in filepath vs path
type FilepathPathBridge interface {
Base(in string) string
Clean(in string) string
Dir(in string) string
Ext(in string) string
Join(elem ...string) string
Separator() string
}
type FilepathBridge struct {
}
func (FilepathBridge) Base(in string) string {
return filepath.Base(in)
}
func (FilepathBridge) Clean(in string) string {
return filepath.Clean(in)
}
func (FilepathBridge) Dir(in string) string {
return filepath.Dir(in)
}
func (FilepathBridge) Ext(in string) string {
return filepath.Ext(in)
}
func (FilepathBridge) Join(elem ...string) string {
return filepath.Join(elem...)
}
func (FilepathBridge) Separator() string {
return FilePathSeparator
}
var filepathBridge FilepathBridge
var sanitizeRegexp = regexp.MustCompile("[^a-zA-Z0-9./_-]") var sanitizeRegexp = regexp.MustCompile("[^a-zA-Z0-9./_-]")
// MakePath takes a string with any characters and replace it // MakePath takes a string with any characters and replace it
@ -64,7 +102,7 @@ func UnicodeSanitize(s string) string {
// ReplaceExtension takes a path and an extension, strips the old extension // ReplaceExtension takes a path and an extension, strips the old extension
// and returns the path with the new extension. // and returns the path with the new extension.
func ReplaceExtension(path string, newExt string) string { func ReplaceExtension(path string, newExt string) string {
f, _ := FileAndExt(path) f, _ := FileAndExt(path, filepathBridge)
return f + "." + newExt return f + "." + newExt
} }
@ -155,7 +193,7 @@ func MakePathRelative(inPath string, possibleDirectories ...string) (string, err
// Filename takes a path, strips out the extension, // Filename takes a path, strips out the extension,
// and returns the name of the file. // and returns the name of the file.
func Filename(in string) (name string) { func Filename(in string) (name string) {
name, _ = FileAndExt(in) name, _ = FileAndExt(in, filepathBridge)
return return
} }
@ -175,11 +213,11 @@ func Filename(in string) (name string) {
// If the path, in, represents a filename with an extension, // If the path, in, represents a filename with an extension,
// then name will be the filename minus any extension - including the dot // then name will be the filename minus any extension - including the dot
// and ext will contain the extension - minus the dot. // and ext will contain the extension - minus the dot.
func FileAndExt(in string) (name string, ext string) { func FileAndExt(in string, b FilepathPathBridge) (name string, ext string) {
ext = filepath.Ext(in) ext = b.Ext(in)
base := filepath.Base(in) // path.Base strips any trailing slash! base := b.Base(in)
return extractFilename(in, ext, base, FilePathSeparator), ext return extractFilename(in, ext, base, b.Separator()), ext
} }
func extractFilename(in, ext, base, pathSeparator string) (name string) { func extractFilename(in, ext, base, pathSeparator string) (name string) {
@ -267,20 +305,24 @@ func PathPrep(ugly bool, in string) string {
// /section/name/ becomes /section/name/index.html // /section/name/ becomes /section/name/index.html
// /section/name/index.html becomes /section/name/index.html // /section/name/index.html becomes /section/name/index.html
func PrettifyPath(in string) string { func PrettifyPath(in string) string {
return PrettiyPath(in, filepathBridge)
}
func PrettiyPath(in string, b FilepathPathBridge) string {
if filepath.Ext(in) == "" { if filepath.Ext(in) == "" {
// /section/name/ -> /section/name/index.html // /section/name/ -> /section/name/index.html
if len(in) < 2 { if len(in) < 2 {
return FilePathSeparator return b.Separator()
} }
return filepath.Join(filepath.Clean(in), "index.html") return b.Join(b.Clean(in), "index.html")
} else { } else {
name, ext := FileAndExt(in) name, ext := FileAndExt(in, b)
if name == "index" { if name == "index" {
// /section/name/index.html -> /section/name/index.html // /section/name/index.html -> /section/name/index.html
return filepath.Clean(in) return b.Clean(in)
} else { } else {
// /section/name.html -> /section/name/index.html // /section/name.html -> /section/name/index.html
return filepath.Join(filepath.Dir(in), name, "index"+ext) return b.Join(b.Dir(in), name, "index"+ext)
} }
} }
} }

View file

@ -461,7 +461,7 @@ func TestFileAndExt(t *testing.T) {
} }
for i, d := range data { for i, d := range data {
file, ext := FileAndExt(filepath.FromSlash(d.input)) file, ext := FileAndExt(filepath.FromSlash(d.input), filepathBridge)
if d.expectedFile != file { if d.expectedFile != file {
t.Errorf("Test %d failed. Expected filename %q got %q.", i, d.expectedFile, file) t.Errorf("Test %d failed. Expected filename %q got %q.", i, d.expectedFile, file)
} }

View file

@ -22,6 +22,35 @@ import (
"strings" "strings"
) )
type PathBridge struct {
}
func (PathBridge) Base(in string) string {
return path.Base(in)
}
func (PathBridge) Clean(in string) string {
return path.Clean(in)
}
func (PathBridge) Dir(in string) string {
return path.Dir(in)
}
func (PathBridge) Ext(in string) string {
return path.Ext(in)
}
func (PathBridge) Join(elem ...string) string {
return path.Join(elem...)
}
func (PathBridge) Separator() string {
return "/"
}
var pathBridge PathBridge
// SanitizeUrl sanitizes the input URL string. // SanitizeUrl sanitizes the input URL string.
func SanitizeUrl(in string) string { func SanitizeUrl(in string) string {
url, err := purell.NormalizeURLString(in, purell.FlagsSafe|purell.FlagRemoveTrailingSlash|purell.FlagRemoveDotSegments|purell.FlagRemoveDuplicateSlashes|purell.FlagRemoveUnnecessaryHostDots|purell.FlagRemoveEmptyPortSeparator) url, err := purell.NormalizeURLString(in, purell.FlagsSafe|purell.FlagRemoveTrailingSlash|purell.FlagRemoveDotSegments|purell.FlagRemoveDuplicateSlashes|purell.FlagRemoveUnnecessaryHostDots|purell.FlagRemoveEmptyPortSeparator)
@ -141,22 +170,7 @@ func PrettifyUrl(in string) string {
// /section/name/ becomes /section/name/index.html // /section/name/ becomes /section/name/index.html
// /section/name/index.html becomes /section/name/index.html // /section/name/index.html becomes /section/name/index.html
func PrettifyUrlPath(in string) string { func PrettifyUrlPath(in string) string {
if path.Ext(in) == "" { return PrettiyPath(in, pathBridge)
// /section/name/ -> /section/name/index.html
if len(in) < 2 {
return "/"
}
return path.Join(path.Clean(in), "index.html")
} else {
name, ext := ResourceAndExt(in)
if name == "index" {
// /section/name/index.html -> /section/name/index.html
return path.Clean(in)
} else {
// /section/name.html -> /section/name/index.html
return path.Join(path.Dir(in), name, "index"+ext)
}
}
} }
// Uglify does the opposite of PrettifyUrlPath(). // Uglify does the opposite of PrettifyUrlPath().
@ -171,7 +185,7 @@ func Uglify(in string) string {
// /section/name/ -> /section/name.html // /section/name/ -> /section/name.html
return path.Clean(in) + ".html" return path.Clean(in) + ".html"
} else { } else {
name, ext := ResourceAndExt(in) name, ext := FileAndExt(in, pathBridge)
if name == "index" { if name == "index" {
// /section/name/index.html -> /section/name.html // /section/name/index.html -> /section/name.html
d := path.Dir(in) d := path.Dir(in)
@ -186,11 +200,3 @@ func Uglify(in string) string {
} }
} }
} }
// Same as FileAndExt, but for URLs.
func ResourceAndExt(in string) (name string, ext string) {
ext = path.Ext(in)
base := path.Base(in)
return extractFilename(in, ext, base, "/"), ext
}