Apply module scope to file validation checks
This commit is contained in:
@@ -16,6 +16,7 @@ import (
|
||||
type CandidateTree struct {
|
||||
context context.Context
|
||||
repositoryDir string
|
||||
modulePath string
|
||||
entries []git.TreeEntry
|
||||
inputEntries []git.TreeEntry
|
||||
byPath map[string]int
|
||||
@@ -53,9 +54,14 @@ func ReadCandidateTreeForScope(ctx context.Context, repositoryDir, commit string
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
modulePath, err := repositoryModulePath(repositoryDir, scope.ModuleDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tree := &CandidateTree{
|
||||
context: ctx,
|
||||
repositoryDir: repositoryDir,
|
||||
modulePath: modulePath,
|
||||
entries: entries,
|
||||
byPath: make(map[string]int, len(entries)),
|
||||
directories: make(map[string]struct{}),
|
||||
@@ -68,7 +74,7 @@ func ReadCandidateTreeForScope(ctx context.Context, repositoryDir, commit string
|
||||
tree.directories[directory] = struct{}{}
|
||||
}
|
||||
}
|
||||
tree.inputEntries, err = selectInputEntries(repositoryDir, entries, tree.byPath, scope)
|
||||
tree.inputEntries, err = selectInputEntries(entries, tree.byPath, modulePath, scope.SharedFiles)
|
||||
if err != nil {
|
||||
_ = tree.Close()
|
||||
return nil, err
|
||||
@@ -88,34 +94,7 @@ func (tree *CandidateTree) InputEntries() []git.TreeEntry {
|
||||
return append([]git.TreeEntry(nil), tree.inputEntries...)
|
||||
}
|
||||
|
||||
func selectInputEntries(repositoryDir string, entries []git.TreeEntry, byPath map[string]int, scope TreeScope) ([]git.TreeEntry, error) {
|
||||
repositoryAbs, err := filepath.Abs(repositoryDir)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("resolve candidate repository directory: %w", err)
|
||||
}
|
||||
moduleDir := scope.ModuleDir
|
||||
if moduleDir == "" {
|
||||
moduleDir = repositoryAbs
|
||||
}
|
||||
if !filepath.IsAbs(moduleDir) {
|
||||
return nil, fmt.Errorf("selected module directory must be absolute: %q", moduleDir)
|
||||
}
|
||||
moduleAbs, err := filepath.Abs(moduleDir)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("resolve selected module directory: %w", err)
|
||||
}
|
||||
relative, err := filepath.Rel(repositoryAbs, moduleAbs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("make selected module relative to repository: %w", err)
|
||||
}
|
||||
if relative == ".." || strings.HasPrefix(relative, ".."+string(filepath.Separator)) || filepath.IsAbs(relative) {
|
||||
return nil, fmt.Errorf("selected module directory %q is outside repository %q", moduleDir, repositoryDir)
|
||||
}
|
||||
modulePath := filepath.ToSlash(relative)
|
||||
if relative == "." {
|
||||
modulePath = "."
|
||||
}
|
||||
|
||||
func selectInputEntries(entries []git.TreeEntry, byPath map[string]int, modulePath string, sharedFiles []string) ([]git.TreeEntry, error) {
|
||||
boundaries := make([]string, 0)
|
||||
for _, entry := range entries {
|
||||
moduleRelative, ok := relativeToModule(entry.Path, modulePath)
|
||||
@@ -145,7 +124,6 @@ func selectInputEntries(repositoryDir string, entries []git.TreeEntry, byPath ma
|
||||
}
|
||||
}
|
||||
|
||||
sharedFiles := scope.SharedFiles
|
||||
usingDefaults := sharedFiles == nil
|
||||
if usingDefaults {
|
||||
sharedFiles = []string{"COPYRIGHT", "LICENSE", "docs/oss/attribution.md"}
|
||||
@@ -153,14 +131,16 @@ func selectInputEntries(repositoryDir string, entries []git.TreeEntry, byPath ma
|
||||
for _, requested := range sharedFiles {
|
||||
name, err := normalizeSharedFile(requested)
|
||||
if err != nil {
|
||||
return nil, &Failure{Check: SharedFiles, Findings: []Finding{{Path: requested, Message: err.Error()}}}
|
||||
cause := fmt.Errorf("invalid shared file path %q: %w", requested, err)
|
||||
return nil, &Failure{Check: SharedFiles, Findings: []Finding{{Path: requested, Message: cause.Error()}}, Cause: cause}
|
||||
}
|
||||
index, exists := byPath[name]
|
||||
if !exists || entries[index].Type != "blob" {
|
||||
if usingDefaults {
|
||||
continue
|
||||
}
|
||||
return nil, &Failure{Check: SharedFiles, Findings: []Finding{{Path: name, Message: "selected shared file is not present in the committed tree"}}}
|
||||
cause := fmt.Errorf("selected shared file %q is not present in the committed tree", name)
|
||||
return nil, &Failure{Check: SharedFiles, Findings: []Finding{{Path: name, Message: "selected shared file is not present in the committed tree"}}, Cause: cause}
|
||||
}
|
||||
selected[name] = entries[index]
|
||||
}
|
||||
@@ -177,6 +157,35 @@ func selectInputEntries(repositoryDir string, entries []git.TreeEntry, byPath ma
|
||||
return inputs, nil
|
||||
}
|
||||
|
||||
func repositoryModulePath(repositoryDir, moduleDir string) (string, error) {
|
||||
repositoryAbs, err := filepath.Abs(repositoryDir)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("resolve candidate repository directory: %w", err)
|
||||
}
|
||||
if moduleDir == "" {
|
||||
moduleDir = repositoryAbs
|
||||
}
|
||||
if !filepath.IsAbs(moduleDir) {
|
||||
return "", fmt.Errorf("selected module directory must be absolute: %q", moduleDir)
|
||||
}
|
||||
moduleAbs, err := filepath.Abs(moduleDir)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("resolve selected module directory: %w", err)
|
||||
}
|
||||
relative, err := filepath.Rel(repositoryAbs, moduleAbs)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("make selected module relative to repository: %w", err)
|
||||
}
|
||||
if relative == ".." || strings.HasPrefix(relative, ".."+string(filepath.Separator)) || filepath.IsAbs(relative) {
|
||||
return "", fmt.Errorf("selected module directory %q is outside repository %q", moduleDir, repositoryDir)
|
||||
}
|
||||
modulePath := filepath.ToSlash(relative)
|
||||
if relative == "." {
|
||||
modulePath = "."
|
||||
}
|
||||
return modulePath, nil
|
||||
}
|
||||
|
||||
func relativeToModule(repositoryPath, modulePath string) (string, bool) {
|
||||
if modulePath == "." {
|
||||
return repositoryPath, true
|
||||
|
||||
Reference in New Issue
Block a user