···4747 chunk.WaitRetry = waitBetweenRetries
4848 chunk.ChunkSize = chunkSize
4949 chunk.RestartDownloads = restartDownloads
5050+ chunk.ProgressDir = progressDir
5051 prog := newProgress()
5152 for status := range chunk.Download(args...) {
5253 if status.Error != nil {
···6768 chunkSize int64
6869 waitBetweenRetries time.Duration
6970 restartDownloads bool
7171+ progressDir string
7072)
71737274func init() {
···7779 rootCmd.Flags().Int64VarP(&chunkSize, "chunk-size", "s", chunk.DefaultChunkSize, "maximum size of each HTTP request done using the content range header.")
7880 rootCmd.Flags().IntVarP(&concurrencyPerServer, "concurrency-per-server", "c", chunk.DefaultConcurrencyPerServer, "controls the max number of concurrent connections opened to the same server.")
7981 rootCmd.Flags().BoolVarP(&restartDownloads, "force-restart", "f", chunk.DefaultRestartDownload, "restart previous downloads, ignoring where they were stopped")
8282+ rootCmd.Flags().StringVarP(
8383+ &progressDir,
8484+ "progress-directory",
8585+ "p",
8686+ "",
8787+ fmt.Sprintf("directory where to track progress; %s under user's home directory if blank, or CHUNK_DIR environment variable", chunk.DefaultChunkDir),
8888+ )
8089}
81908291func main() {
+5-1
downloader.go
···9595 // RestartDownloads controls whether or not to continue the download of
9696 // previous download attempts, skipping chunks alreadt downloaded.
9797 RestartDownloads bool
9898+9999+ // ProgressDir is the directory where Chunk keeps track of each chunk
100100+ // downloaded of each file.
101101+ ProgressDir string
98102}
99103100104type chunk struct{ start, end int64 }
···248252 return
249253 }
250254 chunks := d.chunks(t)
251251- p, err := newProgress(s.DownloadedFilePath, s.URL, d.ChunkSize, len(chunks), d.RestartDownloads)
255255+ p, err := newProgress(s.DownloadedFilePath, d.ProgressDir, s.URL, d.ChunkSize, len(chunks), d.RestartDownloads)
252256 if err != nil {
253257 s.Error = fmt.Errorf("could not creat a progress file: %w", err)
254258 ch <- s
+19-11
progress.go
···1111 "sync/atomic"
1212)
13131414-const defaultChunkDir = ".chunk"
1414+// DefaultChunkDir is the directory where Chunk keeps track of each chunk
1515+// downloaded of each file. It us created under the user's home directory by
1616+// default. It can be replaced by the environment variable CHUNK_DIR.
1717+const DefaultChunkDir = ".chunk"
15181619// get the chunk directory under user's home directory
1720// TODO: make it configurable (maybe an envvar?)
1818-func getChunkDirectory() (string, error) {
1919- u, err := user.Current()
2020- if err != nil {
2121- return "", fmt.Errorf("could not get current user: %w", err)
2121+func getChunkProgressDir(dir string) (string, error) {
2222+ if dir == "" {
2323+ dir = os.Getenv("CHUNK_DIR")
2224 }
2323- d := filepath.Join(u.HomeDir, defaultChunkDir)
2424- if err := os.MkdirAll(d, 0755); err != nil {
2525- return "", fmt.Errorf("could not create chunk's directory %s: %w", d, err)
2525+ if dir == "" {
2626+ u, err := user.Current()
2727+ if err != nil {
2828+ return "", fmt.Errorf("could not get current user: %w", err)
2929+ }
3030+ dir = filepath.Join(u.HomeDir, DefaultChunkDir)
3131+ }
3232+ if err := os.MkdirAll(dir, 0755); err != nil {
3333+ return "", fmt.Errorf("could not create chunk's directory %s: %w", dir, err)
2634 }
2727- return d, nil
3535+ return dir, nil
2836}
29373038type progress struct {
···147155 return downloaded
148156}
149157150150-func newProgress(path, url string, chunkSize int64, chunks int, restart bool) (*progress, error) {
151151- dir, err := getChunkDirectory()
158158+func newProgress(path, dir string, url string, chunkSize int64, chunks int, restart bool) (*progress, error) {
159159+ dir, err := getChunkProgressDir(dir)
152160 if err != nil {
153161 return nil, fmt.Errorf("could not get chunk's directory: %w", err)
154162 }