mirror of
https://github.com/samuelncui/acp.git
synced 2026-08-16 02:46:01 +00:00
feat: change path api
This commit is contained in:
@@ -10,7 +10,6 @@ import (
|
||||
"math/rand"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
@@ -519,8 +518,7 @@ func removeTmp(tmpFiles []string, tmp string) []string {
|
||||
|
||||
func findJob(report *acp.Report, filePath string) (*acp.Job, bool) {
|
||||
for _, job := range report.Jobs {
|
||||
full := job.Base + path.Join(job.Path...)
|
||||
if full == filePath {
|
||||
if job.FullPath == filePath {
|
||||
return job, true
|
||||
}
|
||||
}
|
||||
@@ -557,8 +555,7 @@ func mergeReport(jobs map[string]*acp.Job, errors *[]*acp.Error, report *acp.Rep
|
||||
return
|
||||
}
|
||||
for _, job := range report.Jobs {
|
||||
full := job.Base + path.Join(job.Path...)
|
||||
jobs[full] = job
|
||||
jobs[job.FullPath] = job
|
||||
}
|
||||
if len(report.Errors) > 0 {
|
||||
*errors = append(*errors, report.Errors...)
|
||||
@@ -603,9 +600,8 @@ func printDuplicates(jobs map[string]*acp.Job) {
|
||||
if job == nil || job.SHA256 == "" || job.Size == 0 {
|
||||
continue
|
||||
}
|
||||
full := job.Base + path.Join(job.Path...)
|
||||
key := dupKey{size: job.Size, hash: job.SHA256}
|
||||
dups[key] = append(dups[key], full)
|
||||
dups[key] = append(dups[key], job.FullPath)
|
||||
}
|
||||
|
||||
keys := make([]dupKey, 0, len(dups))
|
||||
|
||||
@@ -14,6 +14,7 @@ require (
|
||||
github.com/samuelncui/godf v0.0.0-20231004032257-e436410ad5a0
|
||||
github.com/schollz/progressbar/v3 v3.13.1
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
golang.org/x/sys v0.12.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -22,6 +23,5 @@ require (
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
||||
golang.org/x/sys v0.12.0 // indirect
|
||||
golang.org/x/term v0.12.0 // indirect
|
||||
)
|
||||
|
||||
@@ -8,8 +8,6 @@ import (
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -162,7 +160,7 @@ func (c *Copyer) walk(ctx context.Context) ([]*baseJob, error) {
|
||||
|
||||
appendJob(&baseJob{
|
||||
copyer: c,
|
||||
src: &source{base: "/", path: lo.Filter(strings.Split(j.src, "/"), func(s string, _ int) bool { return s != "" })},
|
||||
src: &source{base: "/", path: j.src},
|
||||
path: j.src,
|
||||
stat: stat,
|
||||
targets: j.dsts,
|
||||
@@ -175,13 +173,14 @@ func (c *Copyer) walk(ctx context.Context) ([]*baseJob, error) {
|
||||
|
||||
func (c *Copyer) joinJobs(jobs []*baseJob) ([]*baseJob, error) {
|
||||
sort.Slice(jobs, func(i int, j int) bool {
|
||||
return comparePath(jobs[i].src.path, jobs[j].src.path) < 0
|
||||
si, sj := strings.ReplaceAll(jobs[i].src.path, "/", "\x00"), strings.ReplaceAll(jobs[j].src.path, "/", "\x00")
|
||||
return si < sj
|
||||
})
|
||||
|
||||
var last *baseJob
|
||||
filtered := make([]*baseJob, 0, len(jobs))
|
||||
for _, job := range jobs {
|
||||
if last != nil && comparePath(last.src.path, job.src.path) == 0 {
|
||||
if last != nil && last.src.path == job.src.path {
|
||||
c.reportError(last.path, "", fmt.Errorf("same relative path, ignored, '%s'", job.path))
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/hex"
|
||||
"io"
|
||||
"io/fs"
|
||||
"path"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
@@ -92,8 +93,9 @@ func (j *baseJob) fail(path string, err error) {
|
||||
|
||||
func (j *baseJob) report() *Job {
|
||||
return &Job{
|
||||
Base: j.src.base,
|
||||
Path: j.src.path,
|
||||
FullPath: path.Join(j.src.base, j.src.path),
|
||||
Base: j.src.base,
|
||||
Path: j.src.path,
|
||||
|
||||
Status: statusMapping[j.status],
|
||||
SuccessTargets: j.successTargets,
|
||||
@@ -142,8 +144,9 @@ func (wj *writeJob) wait() {
|
||||
}
|
||||
|
||||
type Job struct {
|
||||
Base string `json:"base"`
|
||||
Path []string `json:"path"`
|
||||
FullPath string `json:"full_path"`
|
||||
Base string `json:"base"`
|
||||
Path string `json:"path"`
|
||||
|
||||
Status string `json:"status"`
|
||||
SuccessTargets []string `json:"success_target,omitempty"`
|
||||
|
||||
@@ -9,23 +9,19 @@ import (
|
||||
|
||||
type source struct {
|
||||
base string
|
||||
path []string
|
||||
path string
|
||||
}
|
||||
|
||||
func (s *source) src() string {
|
||||
return s.base + path.Join(s.path...)
|
||||
return path.Join(s.base, s.path)
|
||||
}
|
||||
|
||||
func (s *source) dst(dst string) string {
|
||||
return dst + path.Join(s.path...)
|
||||
return path.Join(dst, s.path)
|
||||
}
|
||||
|
||||
func (s *source) append(next ...string) *source {
|
||||
copyed := make([]string, len(s.path)+len(next))
|
||||
copy(copyed, s.path)
|
||||
copy(copyed[len(s.path):], next)
|
||||
|
||||
return &source{base: s.base, path: copyed}
|
||||
func (s *source) append(next string) *source {
|
||||
return &source{base: s.base, path: path.Join(s.path, next)}
|
||||
}
|
||||
|
||||
type option struct {
|
||||
@@ -79,7 +75,7 @@ type accurateJob struct {
|
||||
|
||||
func AccurateJob(src string, dsts []string) Option {
|
||||
return func(o *option) *option {
|
||||
o.accurateJobs = append(o.accurateJobs, &accurateJob{src: src, dsts: dsts})
|
||||
o.accurateJobs = append(o.accurateJobs, &accurateJob{src: path.Clean(src), dsts: dsts})
|
||||
return o
|
||||
}
|
||||
}
|
||||
@@ -144,48 +140,3 @@ func WithEventHandler(h EventHandler) Option {
|
||||
return o
|
||||
}
|
||||
}
|
||||
|
||||
func comparePath(a, b []string) int {
|
||||
al, bl := len(a), len(b)
|
||||
|
||||
l := al
|
||||
if bl < al {
|
||||
l = bl
|
||||
}
|
||||
|
||||
for idx := 0; idx < l; idx++ {
|
||||
if a[idx] < b[idx] {
|
||||
return -1
|
||||
}
|
||||
if a[idx] > b[idx] {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
if al < bl {
|
||||
return -1
|
||||
}
|
||||
if al > bl {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// isChild return -1(not) 0(equal) 1(child)
|
||||
func isChild(parent, child []string) int {
|
||||
pl, cl := len(parent), len(child)
|
||||
if pl > cl {
|
||||
return -1
|
||||
}
|
||||
|
||||
for idx := 0; idx < pl; idx++ {
|
||||
if parent[idx] != child[idx] {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
if pl == cl {
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
+15
-4
@@ -40,7 +40,8 @@ func (job *wildcardJob) check() error {
|
||||
return fmt.Errorf("source path not found")
|
||||
}
|
||||
sort.Slice(job.src, func(i, j int) bool {
|
||||
return comparePath(job.src[i].path, job.src[j].path) < 0
|
||||
si, sj := strings.ReplaceAll(job.src[i].path, "/", "\x00"), strings.ReplaceAll(job.src[j].path, "/", "\x00")
|
||||
return si < sj
|
||||
})
|
||||
for _, s := range job.src {
|
||||
src := s.src()
|
||||
@@ -79,16 +80,26 @@ func Source(paths ...string) WildcardJobOption {
|
||||
}
|
||||
|
||||
base, name := path.Split(p)
|
||||
j.src = append(j.src, &source{base: base, path: []string{name}})
|
||||
j.src = append(j.src, &source{base: base, path: name})
|
||||
}
|
||||
return j
|
||||
}
|
||||
}
|
||||
|
||||
func SourceWithPath(base string, paths ...string) WildcardJobOption {
|
||||
return func(j *wildcardJob) *wildcardJob {
|
||||
for _, p := range paths {
|
||||
j.src = append(j.src, &source{base: base, path: p})
|
||||
}
|
||||
return j
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated: use SourceWithPath instead
|
||||
func AccurateSource(base string, paths ...[]string) WildcardJobOption {
|
||||
return func(j *wildcardJob) *wildcardJob {
|
||||
for _, path := range paths {
|
||||
j.src = append(j.src, &source{base: base, path: path})
|
||||
for _, p := range paths {
|
||||
j.src = append(j.src, &source{base: base, path: path.Join(p...)})
|
||||
}
|
||||
return j
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user