1// Copyright 2017 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package base
6
7import (
8	"os"
9	"path/filepath"
10	"runtime"
11	"strings"
12	"sync"
13)
14
15var cwd string
16var cwdOnce sync.Once
17
18// UncachedCwd returns the current working directory.
19// Most callers should use Cwd, which caches the result for future use.
20// UncachedCwd is appropriate to call early in program startup before flag parsing,
21// because the -C flag may change the current directory.
22func UncachedCwd() string {
23	wd, err := os.Getwd()
24	if err != nil {
25		Fatalf("cannot determine current directory: %v", err)
26	}
27	return wd
28}
29
30// Cwd returns the current working directory at the time of the first call.
31func Cwd() string {
32	cwdOnce.Do(func() {
33		cwd = UncachedCwd()
34	})
35	return cwd
36}
37
38// ShortPath returns an absolute or relative name for path, whatever is shorter.
39func ShortPath(path string) string {
40	if rel, err := filepath.Rel(Cwd(), path); err == nil && len(rel) < len(path) {
41		return rel
42	}
43	return path
44}
45
46// RelPaths returns a copy of paths with absolute paths
47// made relative to the current directory if they would be shorter.
48func RelPaths(paths []string) []string {
49	var out []string
50	for _, p := range paths {
51		rel, err := filepath.Rel(Cwd(), p)
52		if err == nil && len(rel) < len(p) {
53			p = rel
54		}
55		out = append(out, p)
56	}
57	return out
58}
59
60// IsTestFile reports whether the source file is a set of tests and should therefore
61// be excluded from coverage analysis.
62func IsTestFile(file string) bool {
63	// We don't cover tests, only the code they test.
64	return strings.HasSuffix(file, "_test.go")
65}
66
67// IsNull reports whether the path is a common name for the null device.
68// It returns true for /dev/null on Unix, or NUL (case-insensitive) on Windows.
69func IsNull(path string) bool {
70	if path == os.DevNull {
71		return true
72	}
73	if runtime.GOOS == "windows" {
74		if strings.EqualFold(path, "NUL") {
75			return true
76		}
77	}
78	return false
79}
80