From bedc2d848803bfcc88de876f1a2d848ff8c57303 Mon Sep 17 00:00:00 2001 From: bep Date: Tue, 27 Jan 2015 11:44:41 +0100 Subject: [PATCH] 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. --- helpers/path.go | 64 ++++++++++++++++++++++++++++++++++++-------- helpers/path_test.go | 2 +- helpers/url.go | 56 +++++++++++++++++++++----------------- 3 files changed, 85 insertions(+), 37 deletions(-) diff --git a/helpers/path.go b/helpers/path.go index f236f30aa..351b7a11a 100644 --- a/helpers/path.go +++ b/helpers/path.go @@ -26,6 +26,44 @@ import ( "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./_-]") // 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 // and returns the path with the new extension. func ReplaceExtension(path string, newExt string) string { - f, _ := FileAndExt(path) + f, _ := FileAndExt(path, filepathBridge) return f + "." + newExt } @@ -155,7 +193,7 @@ func MakePathRelative(inPath string, possibleDirectories ...string) (string, err // Filename takes a path, strips out the extension, // and returns the name of the file. func Filename(in string) (name string) { - name, _ = FileAndExt(in) + name, _ = FileAndExt(in, filepathBridge) return } @@ -175,11 +213,11 @@ func Filename(in string) (name string) { // If the path, in, represents a filename with an extension, // then name will be the filename minus any extension - including the dot // and ext will contain the extension - minus the dot. -func FileAndExt(in string) (name string, ext string) { - ext = filepath.Ext(in) - base := filepath.Base(in) // path.Base strips any trailing slash! +func FileAndExt(in string, b FilepathPathBridge) (name string, ext string) { + ext = b.Ext(in) + 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) { @@ -267,20 +305,24 @@ func PathPrep(ugly bool, in string) string { // /section/name/ becomes /section/name/index.html // /section/name/index.html becomes /section/name/index.html func PrettifyPath(in string) string { + return PrettiyPath(in, filepathBridge) +} + +func PrettiyPath(in string, b FilepathPathBridge) string { if filepath.Ext(in) == "" { // /section/name/ -> /section/name/index.html 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 { - name, ext := FileAndExt(in) + name, ext := FileAndExt(in, b) if name == "index" { // /section/name/index.html -> /section/name/index.html - return filepath.Clean(in) + return b.Clean(in) } else { // /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) } } } diff --git a/helpers/path_test.go b/helpers/path_test.go index 0da8835a2..52f879174 100644 --- a/helpers/path_test.go +++ b/helpers/path_test.go @@ -461,7 +461,7 @@ func TestFileAndExt(t *testing.T) { } for i, d := range data { - file, ext := FileAndExt(filepath.FromSlash(d.input)) + file, ext := FileAndExt(filepath.FromSlash(d.input), filepathBridge) if d.expectedFile != file { t.Errorf("Test %d failed. Expected filename %q got %q.", i, d.expectedFile, file) } diff --git a/helpers/url.go b/helpers/url.go index 558ed9c97..e4db6ceb7 100644 --- a/helpers/url.go +++ b/helpers/url.go @@ -22,6 +22,35 @@ import ( "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. func SanitizeUrl(in string) string { 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/index.html becomes /section/name/index.html func PrettifyUrlPath(in string) string { - if path.Ext(in) == "" { - // /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) - } - } + return PrettiyPath(in, pathBridge) } // Uglify does the opposite of PrettifyUrlPath(). @@ -171,7 +185,7 @@ func Uglify(in string) string { // /section/name/ -> /section/name.html return path.Clean(in) + ".html" } else { - name, ext := ResourceAndExt(in) + name, ext := FileAndExt(in, pathBridge) if name == "index" { // /section/name/index.html -> /section/name.html 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 -}