From ba589bf18079c343652c8e17f5ffd2d996d96327 Mon Sep 17 00:00:00 2001 From: k1LoW Date: Tue, 23 Jan 2024 17:11:25 +0900 Subject: [PATCH] Fix path for Windows --- central/central.go | 6 ++-- config/build.go | 4 +-- config/config.go | 3 +- config/config_test.go | 8 +++-- coverage/coverage.go | 6 ++-- datastore/datastore.go | 7 ++++- datastore/datastore_test.go | 7 ----- datastore/datastore_unix_test.go | 45 +++++++++++++++++++++++++++ datastore/datastore_windows_test.go | 47 +++++++++++++++++++++++++++++ ratio/ratio.go | 6 ++++ 10 files changed, 120 insertions(+), 19 deletions(-) create mode 100644 datastore/datastore_unix_test.go create mode 100644 datastore/datastore_windows_test.go diff --git a/central/central.go b/central/central.go index f3f3e249..20bfed9c 100644 --- a/central/central.go +++ b/central/central.go @@ -15,11 +15,11 @@ import ( "text/template" "time" + "github.com/k1LoW/octocov/badge" "github.com/k1LoW/octocov/datastore" "github.com/k1LoW/octocov/datastore/local" "github.com/k1LoW/octocov/gh" "github.com/k1LoW/octocov/internal" - "github.com/k1LoW/octocov/badge" "github.com/k1LoW/octocov/report" ) @@ -266,8 +266,8 @@ func (c *Central) renderIndex(wr io.Writer) error { d := map[string]any{ "Host": host, "Reports": c.reports, - "BadgesLinkRel": badgesLinkRel, - "BadgesURLRel": badgesURLRel, + "BadgesLinkRel": filepath.ToSlash(badgesLinkRel), + "BadgesURLRel": filepath.ToSlash(badgesURLRel), "RootURL": rootURL, "IsPrivate": isPrivate, "Query": query, diff --git a/config/build.go b/config/build.go index fa864990..a3f000ba 100644 --- a/config/build.go +++ b/config/build.go @@ -4,7 +4,6 @@ import ( "fmt" "os" "path/filepath" - "strings" "github.com/k1LoW/octocov/internal" ) @@ -28,6 +27,7 @@ func (c *Config) Build() { } else { var paths []string for _, p := range c.Coverage.Paths { + p = filepath.FromSlash(p) paths = append(paths, filepath.Join(filepath.Dir(c.path), p)) } c.Coverage.Paths = paths @@ -45,7 +45,7 @@ func (c *Config) Build() { if c.Central.Root == "" { c.Central.Root = "." } - if !strings.HasPrefix(c.Central.Root, "/") { + if !filepath.IsAbs(c.Central.Root) { c.Central.Root = filepath.Clean(filepath.Join(c.Root(), c.Central.Root)) } if len(c.Central.Reports.Datastores) == 0 { diff --git a/config/config.go b/config/config.go index 94b41233..39d41c1f 100644 --- a/config/config.go +++ b/config/config.go @@ -152,6 +152,7 @@ func (c *Config) Setwd(path string) { } func (c *Config) Load(path string) error { + path = filepath.FromSlash(path) if path == "" { for _, p := range DefaultPaths { if f, err := os.Stat(filepath.Join(c.wd, p)); err == nil && !f.IsDir() { @@ -165,7 +166,7 @@ func (c *Config) Load(path string) error { if path == "" { return nil } - if strings.HasPrefix(path, "/") { + if filepath.IsAbs(path) { c.path = path } else { c.path = filepath.Join(c.wd, path) diff --git a/config/config_test.go b/config/config_test.go index d9478fce..31686e24 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -140,13 +140,17 @@ func TestCoveragePaths(t *testing.T) { for _, tt := range tests { t.Run(fmt.Sprintf("%v", tt.paths), func(t *testing.T) { c := New() - c.path = tt.configPath + c.path = filepath.FromSlash(tt.configPath) c.Coverage = &Coverage{ Paths: tt.paths, } c.Build() got := c.Coverage.Paths - if diff := cmp.Diff(got, tt.want, nil); diff != "" { + var want []string + for _, p := range tt.want { + want = append(want, filepath.FromSlash(p)) + } + if diff := cmp.Diff(got, want, nil); diff != "" { t.Error(diff) } }) diff --git a/coverage/coverage.go b/coverage/coverage.go index dd65cab5..6c555657 100644 --- a/coverage/coverage.go +++ b/coverage/coverage.go @@ -94,7 +94,7 @@ func (fc FileCoverages) FuzzyFindByFile(file string) (*FileCoverage, error) { // continue } // When coverages are recorded in the package path. ( ex. org/repo/package/path/to/Target.kt - if !strings.HasPrefix(c.File, "/") && strings.HasSuffix(file, c.File) { + if !filepath.IsAbs(c.File) && strings.HasSuffix(file, c.File) { if match == nil || len(match.File) > len(c.File) { match = c } @@ -130,7 +130,7 @@ func (fc FileCoverages) PathPrefix() (string, error) { //nostyle:recvtype p = p[:i] } s := strings.Join(p, "/") - if s == "" && strings.HasPrefix(fc[0].File, "/") { + if s == "" && filepath.IsAbs(fc[0].File) { s = "/" } if s == "." { @@ -174,7 +174,7 @@ func (dc DiffFileCoverages) FuzzyFindByFile(file string) (*DiffFileCoverage, err continue } // When coverages are recorded in the package path. ( ex. org/repo/package/path/to/Target.kt - if !strings.HasPrefix(c.File, "/") && strings.HasSuffix(file, c.File) { + if !filepath.IsAbs(c.File) && strings.HasSuffix(file, c.File) { if match == nil || len(match.File) > len(c.File) { match = c } diff --git a/datastore/datastore.go b/datastore/datastore.go index d7e4012a..53f9ce07 100644 --- a/datastore/datastore.go +++ b/datastore/datastore.go @@ -6,6 +6,7 @@ import ( "io/fs" "os" "path/filepath" + "runtime" "strings" "cloud.google.com/go/bigquery" @@ -222,7 +223,11 @@ func parse(u, root string) (Type, []string, error) { return Mackerel, []string{service}, nil default: p := strings.TrimSuffix(strings.TrimPrefix(strings.TrimPrefix(u, "file://"), "local://"), "/") - if strings.HasPrefix(p, "/") { + if runtime.GOOS == "windows" && strings.HasPrefix(p, "/") { + return UnknownType, nil, fmt.Errorf("invalid file path: %s", u) + } + p = filepath.FromSlash(p) + if filepath.IsAbs(p) { root = p } else { root = filepath.Join(root, p) diff --git a/datastore/datastore_test.go b/datastore/datastore_test.go index a56d62e2..76fb436c 100644 --- a/datastore/datastore_test.go +++ b/datastore/datastore_test.go @@ -42,13 +42,6 @@ func TestParse(t *testing.T) { {"mackerel://service", Mackerel, []string{"service"}, false}, {"mkr://service", Mackerel, []string{"service"}, false}, {"mkr://service/foo", UnknownType, []string{}, true}, - {"file://reports", Local, []string{filepath.Join(testdataDir(t), "reports")}, false}, - {"reports", Local, []string{filepath.Join(testdataDir(t), "reports")}, false}, - {"file:///reports", Local, []string{"/reports"}, false}, - {"/reports", Local, []string{"/reports"}, false}, - {"local://reports", Local, []string{filepath.Join(testdataDir(t), "reports")}, false}, - {"local://./reports", Local, []string{filepath.Join(testdataDir(t), "reports")}, false}, - {"local:///reports", Local, []string{"/reports"}, false}, } for _, tt := range tests { t.Run(tt.in, func(t *testing.T) { diff --git a/datastore/datastore_unix_test.go b/datastore/datastore_unix_test.go new file mode 100644 index 00000000..54ab6d8d --- /dev/null +++ b/datastore/datastore_unix_test.go @@ -0,0 +1,45 @@ +package datastore + +import ( + "path/filepath" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestParseUNIX(t *testing.T) { + var tests = []struct { + in string + wantType Type + wantArgs []string + wantError bool + }{ + {"file://reports", Local, []string{filepath.Join(testdataDir(t), "reports")}, false}, + {"reports", Local, []string{filepath.Join(testdataDir(t), "reports")}, false}, + {"file:///reports", Local, []string{"/reports"}, false}, + {"/reports", Local, []string{"/reports"}, false}, + {"local://reports", Local, []string{filepath.Join(testdataDir(t), "reports")}, false}, + {"local://./reports", Local, []string{filepath.Join(testdataDir(t), "reports")}, false}, + {"local:///reports", Local, []string{"/reports"}, false}, + } + for _, tt := range tests { + t.Run(tt.in, func(t *testing.T) { + gotType, gotArgs, err := parse(tt.in, testdataDir(t)) + if err != nil { + if !tt.wantError { + t.Errorf("got %v", err) + } + return + } + if err == nil && tt.wantError { + t.Error("want error") + } + if gotType != tt.wantType { + t.Errorf("got %v\nwant %v", gotType, tt.wantType) + } + if diff := cmp.Diff(gotArgs, tt.wantArgs, nil); diff != "" { + t.Error(diff) + } + }) + } +} diff --git a/datastore/datastore_windows_test.go b/datastore/datastore_windows_test.go new file mode 100644 index 00000000..b0c97a8c --- /dev/null +++ b/datastore/datastore_windows_test.go @@ -0,0 +1,47 @@ +package datastore + +import ( + "path/filepath" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestParseUNIX(t *testing.T) { + var tests = []struct { + in string + wantType Type + wantArgs []string + wantError bool + }{ + {"file://reports", Local, []string{filepath.Join(testdataDir(t), "reports")}, false}, + {"reports", Local, []string{filepath.Join(testdataDir(t), "reports")}, false}, + {"file:///reports", UnknownType, nil, true}, + {"/reports", UnknownType, nil, true}, + {"local://reports", Local, []string{filepath.Join(testdataDir(t), "reports")}, false}, + {"local://./reports", Local, []string{filepath.Join(testdataDir(t), "reports")}, false}, + {"local:///reports", UnknownType, nil, true}, + {"local://C:/reports", Local, []string{"C:\reports"}, false}, + {"local://C:\reports", Local, []string{"C:\reports"}, false}, + } + for _, tt := range tests { + t.Run(tt.in, func(t *testing.T) { + gotType, gotArgs, err := parse(tt.in, testdataDir(t)) + if err != nil { + if !tt.wantError { + t.Errorf("got %v", err) + } + return + } + if err == nil && tt.wantError { + t.Error("want error") + } + if gotType != tt.wantType { + t.Errorf("got %v\nwant %v", gotType, tt.wantType) + } + if diff := cmp.Diff(gotArgs, tt.wantArgs, nil); diff != "" { + t.Error(diff) + } + }) + } +} diff --git a/ratio/ratio.go b/ratio/ratio.go index 2a292a64..c4839415 100644 --- a/ratio/ratio.go +++ b/ratio/ratio.go @@ -68,6 +68,12 @@ func Measure(root string, code, test []string) (*Ratio, error) { ratio := New() defined := gocloc.NewDefinedLanguages() opts := gocloc.NewClocOptions() + for i, p := range code { + code[i] = filepath.FromSlash(p) + } + for i, p := range test { + test[i] = filepath.FromSlash(p) + } if err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error { if err != nil {