Merge branch 'rclone:master' into mct-install-set-modes-mac

This commit is contained in:
Michael C Tiernan - MIT-Research Computing Project 2022-05-19 08:22:38 -04:00 committed by GitHub
commit eab83baf6d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 194 additions and 103 deletions

View file

@ -245,18 +245,18 @@ retag:
startdev:
@echo "Version is $(VERSION)"
@echo "Next version is $(NEXT_VERSION)"
echo -e "package fs\n\n// Version of rclone\nvar Version = \"$(NEXT_VERSION)-DEV\"\n" | gofmt > fs/version.go
echo -e "package fs\n\n// VersionTag of rclone\nvar VersionTag = \"$(NEXT_VERSION)\"\n" | gofmt > fs/versiontag.go
echo -n "$(NEXT_VERSION)" > docs/layouts/partials/version.html
echo "$(NEXT_VERSION)" > VERSION
git commit -m "Start $(NEXT_VERSION)-DEV development" fs/version.go VERSION docs/layouts/partials/version.html
git commit -m "Start $(NEXT_VERSION)-DEV development" fs/versiontag.go VERSION docs/layouts/partials/version.html
startstable:
@echo "Version is $(VERSION)"
@echo "Next stable version is $(NEXT_PATCH_VERSION)"
echo -e "package fs\n\n// Version of rclone\nvar Version = \"$(NEXT_PATCH_VERSION)-DEV\"\n" | gofmt > fs/version.go
echo -e "package fs\n\n// VersionTag of rclone\nvar VersionTag = \"$(NEXT_PATCH_VERSION)\"\n" | gofmt > fs/versiontag.go
echo -n "$(NEXT_PATCH_VERSION)" > docs/layouts/partials/version.html
echo "$(NEXT_PATCH_VERSION)" > VERSION
git commit -m "Start $(NEXT_PATCH_VERSION)-DEV development" fs/version.go VERSION docs/layouts/partials/version.html
git commit -m "Start $(NEXT_PATCH_VERSION)-DEV development" fs/versiontag.go VERSION docs/layouts/partials/version.html
winzip:
zip -9 rclone-$(TAG).zip rclone.exe

View file

@ -515,7 +515,7 @@ func (f *Fs) setChunkNameFormat(pattern string) error {
strRegex := regexp.QuoteMeta(pattern)
strRegex = reHashes.ReplaceAllLiteralString(strRegex, reDataOrCtrl)
strRegex = strings.Replace(strRegex, "\\*", mainNameRegStr, -1)
strRegex = strings.ReplaceAll(strRegex, "\\*", mainNameRegStr)
strRegex = fmt.Sprintf("^%s(?:%s|%s)?$", strRegex, tempSuffixRegStr, tempSuffixRegOld)
f.nameRegexp = regexp.MustCompile(strRegex)
@ -524,7 +524,7 @@ func (f *Fs) setChunkNameFormat(pattern string) error {
if numDigits > 1 {
fmtDigits = fmt.Sprintf("%%0%dd", numDigits)
}
strFmt := strings.Replace(pattern, "%", "%%", -1)
strFmt := strings.ReplaceAll(pattern, "%", "%%")
strFmt = strings.Replace(strFmt, "*", "%s", 1)
f.dataNameFmt = reHashes.ReplaceAllLiteralString(strFmt, fmtDigits)
f.ctrlNameFmt = reHashes.ReplaceAllLiteralString(strFmt, "_%s")

View file

@ -70,7 +70,7 @@ const (
// 1<<18 is the minimum size supported by the Google uploader, and there is no maximum.
minChunkSize = fs.SizeSuffix(googleapi.MinUploadChunkSize)
defaultChunkSize = 8 * fs.Mebi
partialFields = "id,name,size,md5Checksum,trashed,explicitlyTrashed,modifiedTime,createdTime,mimeType,parents,webViewLink,shortcutDetails,exportLinks"
partialFields = "id,name,size,md5Checksum,trashed,explicitlyTrashed,modifiedTime,createdTime,mimeType,parents,webViewLink,shortcutDetails,exportLinks,resourceKey"
listRGrouping = 50 // number of IDs to search at once when using ListR
listRInputBuffer = 1000 // size of input buffer when using ListR
defaultXDGIcon = "text-html"
@ -660,6 +660,7 @@ type baseObject struct {
mimeType string // The object MIME type
bytes int64 // size of the object
parents []string // IDs of the parent directories
resourceKey *string // resourceKey is needed for link shared objects
}
type documentObject struct {
baseObject
@ -829,8 +830,8 @@ func (f *Fs) list(ctx context.Context, dirIDs []string, title string, directorie
if title != "" {
searchTitle := f.opt.Enc.FromStandardName(title)
// Escaping the backslash isn't documented but seems to work
searchTitle = strings.Replace(searchTitle, `\`, `\\`, -1)
searchTitle = strings.Replace(searchTitle, `'`, `\'`, -1)
searchTitle = strings.ReplaceAll(searchTitle, `\`, `\\`)
searchTitle = strings.ReplaceAll(searchTitle, `'`, `\'`)
var titleQuery bytes.Buffer
_, _ = fmt.Fprintf(&titleQuery, "(name='%s'", searchTitle)
@ -1319,12 +1320,16 @@ func (f *Fs) newRegularObject(remote string, info *drive.File) fs.Object {
}
}
}
return &Object{
o := &Object{
baseObject: f.newBaseObject(remote, info),
url: fmt.Sprintf("%sfiles/%s?alt=media", f.svc.BasePath, actualID(info.Id)),
md5sum: strings.ToLower(info.Md5Checksum),
v2Download: f.opt.V2DownloadMinSize != -1 && info.Size >= int64(f.opt.V2DownloadMinSize),
}
if info.ResourceKey != "" {
o.resourceKey = &info.ResourceKey
}
return o
}
// newDocumentObject creates an fs.Object for a google docs drive.File
@ -2429,11 +2434,12 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object,
var info *drive.File
err = f.pacer.Call(func() (bool, error) {
info, err = f.svc.Files.Copy(id, createInfo).
copy := f.svc.Files.Copy(id, createInfo).
Fields(partialFields).
SupportsAllDrives(true).
KeepRevisionForever(f.opt.KeepRevisionForever).
Context(ctx).Do()
KeepRevisionForever(f.opt.KeepRevisionForever)
srcObj.addResourceKey(copy.Header())
info, err = copy.Context(ctx).Do()
return f.shouldRetry(ctx, err)
})
if err != nil {
@ -3530,6 +3536,14 @@ func (o *baseObject) Storable() bool {
return true
}
// addResourceKey adds a X-Goog-Drive-Resource-Keys header for this
// object if required.
func (o *baseObject) addResourceKey(header http.Header) {
if o.resourceKey != nil {
header.Add("X-Goog-Drive-Resource-Keys", fmt.Sprintf("%s/%s", o.id, *o.resourceKey))
}
}
// httpResponse gets an http.Response object for the object
// using the url and method passed in
func (o *baseObject) httpResponse(ctx context.Context, url, method string, options []fs.OpenOption) (req *http.Request, res *http.Response, err error) {
@ -3545,6 +3559,7 @@ func (o *baseObject) httpResponse(ctx context.Context, url, method string, optio
// Don't supply range requests for 0 length objects as they always fail
delete(req.Header, "Range")
}
o.addResourceKey(req.Header)
err = o.fs.pacer.Call(func() (bool, error) {
res, err = o.fs.client.Do(req)
if err == nil {

View file

@ -562,7 +562,7 @@ func (f *Fs) list(ctx context.Context, filter api.SearchFilter, fn listFn) (err
for i := range items {
item := &result.MediaItems[i]
remote := item.Filename
remote = strings.Replace(remote, "/", "", -1)
remote = strings.ReplaceAll(remote, "/", "")
err = fn(remote, item, false)
if err != nil {
return err

View file

@ -119,7 +119,7 @@ func (f *Fs) getCredentials(ctx context.Context) (err error) {
defer fs.CheckClose(resp.Body, &err)
if resp.StatusCode < 200 || resp.StatusCode > 299 {
body, _ := ioutil.ReadAll(resp.Body)
bodyStr := strings.TrimSpace(strings.Replace(string(body), "\n", " ", -1))
bodyStr := strings.TrimSpace(strings.ReplaceAll(string(body), "\n", " "))
return fmt.Errorf("failed to get credentials: %s: %s", resp.Status, bodyStr)
}
decoder := json.NewDecoder(resp.Body)

View file

@ -191,7 +191,7 @@ machines.`)
m.Set("auth_code", "")
return fs.ConfigGoto("legacy_do_auth")
case "legacy_auth_code":
authCode := strings.Replace(config.Result, "-", "", -1) // remove any "-" contained in the code so we have a 6 digit number
authCode := strings.ReplaceAll(config.Result, "-", "") // remove any "-" contained in the code so we have a 6 digit number
m.Set("auth_code", authCode)
return fs.ConfigGoto("legacy_do_auth")
case "legacy_do_auth":
@ -649,7 +649,7 @@ func errorHandler(resp *http.Response) error {
// Jottacloud wants '+' to be URL encoded even though the RFC states it's not reserved
func urlPathEscape(in string) string {
return strings.Replace(rest.URLPathEscape(in), "+", "%2B", -1)
return strings.ReplaceAll(rest.URLPathEscape(in), "+", "%2B")
}
// filePathRaw returns an unescaped file path (f.root, file)

View file

@ -1294,7 +1294,7 @@ For more info visit https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview
Note that this ACL is applied when server-side copying objects as S3
doesn't copy the ACL from the source but rather writes a fresh one.`,
Provider: "!Storj",
Provider: "!Storj,Cloudflare",
Examples: []fs.OptionExample{{
Value: "default",
Help: "Owner gets Full_CONTROL.\nNo one else has access rights (default).",
@ -2966,7 +2966,7 @@ func (f *Fs) Precision() time.Duration {
// pathEscape escapes s as for a URL path. It uses rest.URLPathEscape
// but also escapes '+' for S3 and Digital Ocean spaces compatibility
func pathEscape(s string) string {
return strings.Replace(rest.URLPathEscape(s), "+", "%2B", -1)
return strings.ReplaceAll(rest.URLPathEscape(s), "+", "%2B")
}
// copy does a server-side copy

View file

@ -1311,7 +1311,7 @@ var shellEscapeRegex = regexp.MustCompile("[^A-Za-z0-9_.,:/\\@\u0080-\uFFFFFFFF\
// when sending it to a shell.
func shellEscape(str string) string {
safe := shellEscapeRegex.ReplaceAllString(str, `\$0`)
return strings.Replace(safe, "\n", "'\n'", -1)
return strings.ReplaceAll(safe, "\n", "'\n'")
}
// Converts a byte array from the SSH session returned by

View file

@ -173,8 +173,8 @@ func buildZip(dir string) string {
func buildDebAndRpm(dir, version, goarch string) []string {
// Make internal version number acceptable to .deb and .rpm
pkgVersion := version[1:]
pkgVersion = strings.Replace(pkgVersion, "β", "-beta", -1)
pkgVersion = strings.Replace(pkgVersion, "-", ".", -1)
pkgVersion = strings.ReplaceAll(pkgVersion, "β", "-beta")
pkgVersion = strings.ReplaceAll(pkgVersion, "-", ".")
nfpmArch, ok := goarchToNfpm[goarch]
if !ok {
nfpmArch = goarch

View file

@ -79,7 +79,7 @@ rclone.org website.`,
var description = map[string]string{}
var addDescription func(root *cobra.Command)
addDescription = func(root *cobra.Command) {
name := strings.Replace(root.CommandPath(), " ", "_", -1) + ".md"
name := strings.ReplaceAll(root.CommandPath(), " ", "_") + ".md"
description[name] = root.Short
for _, c := range root.Commands() {
addDescription(c)
@ -93,11 +93,11 @@ rclone.org website.`,
base := strings.TrimSuffix(name, path.Ext(name))
data := frontmatter{
Date: now,
Title: strings.Replace(base, "_", " ", -1),
Title: strings.ReplaceAll(base, "_", " "),
Description: description[name],
Slug: base,
URL: "/commands/" + strings.ToLower(base) + "/",
Source: strings.Replace(strings.Replace(base, "rclone", "cmd", -1), "_", "/", -1) + "/",
Source: strings.ReplaceAll(strings.ReplaceAll(base, "rclone", "cmd"), "_", "/") + "/",
}
var buf bytes.Buffer
err := frontmatterTemplate.Execute(&buf, data)

View file

@ -290,7 +290,7 @@ func list(ctx context.Context) error {
if !ok {
return errors.New("bad JSON")
}
fmt.Printf("### %s: %s {#%s}\n\n", info["Path"], info["Title"], strings.Replace(info["Path"].(string), "/", "-", -1))
fmt.Printf("### %s: %s {#%s}\n\n", info["Path"], info["Title"], strings.ReplaceAll(info["Path"].(string), "/", "-"))
fmt.Printf("%s\n\n", info["Help"])
if authRequired := info["AuthRequired"]; authRequired != nil {
if authRequired.(bool) {

View file

@ -43,7 +43,7 @@ var shellUnEscapeRegex = regexp.MustCompile(`\\(.)`)
// Unescape a string that was escaped by rclone
func shellUnEscape(str string) string {
str = strings.Replace(str, "'\n'", "\n", -1)
str = strings.ReplaceAll(str, "'\n'", "\n")
str = shellUnEscapeRegex.ReplaceAllString(str, `$1`)
return str
}

View file

@ -593,3 +593,6 @@ put them back in again.` >}}
* Kaspian <34658474+KaspianDev@users.noreply.github.com>
* Werner <EvilOlaf@users.noreply.github.com>
* Hugal31 <hugo.laloge@gmail.com>
* Christian Galo <36752715+cgalo5758@users.noreply.github.com>
* Erik van Velzen <erik@evanv.nl>
* Derek Battams <derek@battams.ca>

View file

@ -3,11 +3,11 @@ title: "Install"
description: "Rclone Installation"
---
# Install #
# Install
Rclone is a Go program and comes as a single binary file.
## Quickstart ##
## Quickstart
* [Download](/downloads/) the relevant binary.
* Extract the `rclone` executable, `rclone.exe` on Windows, from the archive.
@ -22,7 +22,7 @@ run `rclone -h`.
Already installed rclone can be easily updated to the latest version
using the [rclone selfupdate](/commands/rclone_selfupdate/) command.
## Script installation ##
## Script installation
To install rclone on Linux/macOS/BSD systems, run:
@ -35,7 +35,7 @@ For beta installation, run:
Note that this script checks the version of rclone installed first and
won't re-download if not needed.
## Linux installation from precompiled binary ##
## Linux installation from precompiled binary
Fetch and unpack
@ -59,7 +59,7 @@ Run `rclone config` to setup. See [rclone config docs](/docs/) for more details.
rclone config
## macOS installation with brew ##
## macOS installation with brew
brew install rclone
@ -68,7 +68,7 @@ NOTE: This version of rclone will not support `mount` any more (see
on macOS, either install a precompiled binary or enable the relevant option
when [installing from source](#install-from-source).
## macOS installation from precompiled binary, using curl ##
## macOS installation from precompiled binary, using curl
To avoid problems with macOS gatekeeper enforcing the binary to be signed and
notarized it is enough to download with `curl`.
@ -96,20 +96,20 @@ Run `rclone config` to setup. See [rclone config docs](/docs/) for more details.
rclone config
## macOS installation from precompiled binary, using a web browser ##
## macOS installation from precompiled binary, using a web browser
When downloading a binary with a web browser, the browser will set the macOS
gatekeeper quarantine attribute. Starting from Catalina, when attempting to run
`rclone`, a pop-up will appear saying:
“rclone” cannot be opened because the developer cannot be verified.
"rclone" cannot be opened because the developer cannot be verified.
macOS cannot verify that this app is free from malware.
The simplest fix is to run
xattr -d com.apple.quarantine rclone
## Install with docker ##
## Install with docker
The rclone maintains a [docker image for rclone](https://hub.docker.com/r/rclone/rclone).
These images are autobuilt by docker hub from the rclone source based
@ -188,39 +188,93 @@ ls ~/data/mount
kill %1
```
## Install from source ##
## Install from source
Make sure you have at least [Go](https://golang.org/) go1.16
installed. [Download go](https://golang.org/dl/) if necessary. The
latest release is recommended. Then
Make sure you have git and [Go](https://golang.org/) installed.
Go version 1.16 or newer is required, latest release is recommended.
You can get it from your package manager, or download it from
[golang.org/dl](https://golang.org/dl/). Then you can run the following:
```sh
```
git clone https://github.com/rclone/rclone.git
cd rclone
go build
# If on macOS and mount is wanted, instead run: make GOTAGS=cmount
./rclone version
```
This will leave you a checked out version of rclone you can modify and
send pull requests with. If you use `make` instead of `go build` then
the rclone build will have the correct version information in it.
This will check out the rclone source in subfolder rclone, which you can later
modify and send pull requests with. Then it will build the rclone executable
in the same folder. As an initial check you can now run `./rclone version`
(`.\rclone version` on Windows).
You can also build the latest stable rclone with:
Note that on macOS and Windows the [mount](https://rclone.org/commands/rclone_mount/)
command will not be available unless you specify additional build tag `cmount`.
go get github.com/rclone/rclone
```
go build -tags cmount
```
or the latest version (equivalent to the beta) with
This assumes you have a GCC compatible C compiler (GCC or Clang) in your PATH,
as it uses [cgo](https://pkg.go.dev/cmd/cgo). But on Windows, the
[cgofuse](https://github.com/winfsp/cgofuse) library that the cmount
implementation is based on, also supports building
[without cgo](https://github.com/golang/go/wiki/WindowsDLLs), i.e. by setting
environment variable CGO_ENABLED to value 0 (static linking). This is how the
official Windows release of rclone is being built, starting with version 1.59.
It is still possible to build with cgo on Windows as well, by using the MinGW
port of GCC, e.g. by installing it in a [MSYS2](https://www.msys2.org)
distribution (make sure you install it in the classic mingw64 subsystem, the
ucrt64 version is not compatible).
go get github.com/rclone/rclone@master
Additionally, on Windows, you must install the third party utility
[WinFsp](http://www.secfs.net/winfsp/), with the "Developer" feature selected.
If building with cgo, you must also set environment variable CPATH pointing to
the fuse include directory within the WinFsp installation
(normally `C:\Program Files (x86)\WinFsp\inc\fuse`).
These will build the binary in `$(go env GOPATH)/bin`
(`~/go/bin/rclone` by default) after downloading the source to the go
module cache. Note - do **not** use the `-u` flag here. This causes go
to try to update the dependencies that rclone uses and sometimes these
don't work with the current version of rclone.
You may also add arguments `-ldflags -s` (with or without `-tags cmount`),
to omit symbol table and debug information, making the executable file smaller,
and `-trimpath` to remove references to local file system paths. This is how
the official rclone releases are built.
## Installation with Ansible ##
```
go build -trimpath -ldflags -s -tags cmount
```
Instead of executing the `go build` command directly, you can run it via the
Makefile, which also sets version information and copies the resulting rclone
executable into your GOPATH bin folder (`$(go env GOPATH)/bin`, which
corresponds to `~/go/bin/rclone` by default).
```
make
```
To include mount command on macOS and Windows with Makefile build:
```
make GOTAGS=cmount
```
As an alternative you can download the source, build and install rclone in one
operation, as a regular Go package. The source will be stored it in the Go
module cache, and the resulting executable will be in your GOPATH bin folder
(`$(go env GOPATH)/bin`, which corresponds to `~/go/bin/rclone` by default).
With Go version 1.17 or newer:
```
go install github.com/rclone/rclone@latest
```
With Go versions older than 1.17 (do **not** use the `-u` flag, it causes Go to
try to update the dependencies that rclone uses and sometimes these don't work
with the current version):
```
go get github.com/rclone/rclone
```
## Installation with Ansible
This can be done with [Stefan Weichinger's ansible
role](https://github.com/stefangweichinger/ansible-rclone).
@ -236,7 +290,7 @@ Instructions
- rclone
```
## Portable installation ##
## Portable installation
As mentioned [above](https://rclone.org/install/#quickstart), rclone is single
executable (`rclone`, or `rclone.exe` on Windows) that you can download as a
@ -314,7 +368,7 @@ the [PsExec](https://docs.microsoft.com/en-us/sysinternals/downloads/psexec)
utility from Microsoft's Sysinternals suite, which takes option `-s` to
execute commands as the `SYSTEM` user.
#### Start from Startup folder ###
#### Start from Startup folder
To quickly execute an rclone command you can simply create a standard
Windows Explorer shortcut for the complete rclone command you want to run. If you
@ -329,7 +383,7 @@ functionality to set it to run as different user, or to set conditions or
actions on certain events. Setting up a scheduled task as described below
will often give you better results.
#### Start from Task Scheduler ###
#### Start from Task Scheduler
Task Scheduler is an administrative tool built into Windows, and it can be used to
configure rclone to be started automatically in a highly configurable way, e.g.
@ -339,14 +393,14 @@ be available to all users it can run as the `SYSTEM` user.
For technical information, see
https://docs.microsoft.com/windows/win32/taskschd/task-scheduler-start-page.
#### Run as service ###
#### Run as service
For running rclone at system startup, you can create a Windows service that executes
your rclone command, as an alternative to scheduled task configured to run at startup.
##### Mount command built-in service integration ####
##### Mount command built-in service integration
For mount commands, Rclone has a built-in Windows service integration via the third-party
For mount commands, rclone has a built-in Windows service integration via the third-party
WinFsp library it uses. Registering as a regular Windows service easy, as you just have to
execute the built-in PowerShell command `New-Service` (requires administrative privileges).
@ -366,7 +420,7 @@ Windows standard methods for managing network drives. This is currently not
officially supported by Rclone, but with WinFsp version 2019.3 B2 / v1.5B2 or later
it should be possible through path rewriting as described [here](https://github.com/rclone/rclone/issues/3340).
##### Third-party service integration #####
##### Third-party service integration
To Windows service running any rclone command, the excellent third-party utility
[NSSM](http://nssm.cc), the "Non-Sucking Service Manager", can be used.

View file

@ -150,6 +150,16 @@ use these methods. The alternative is to use `--rc-user` and
Default Off.
### --rc-baseurl
Prefix for URLs.
Default is root
### --rc-template
User-specified template.
## Accessing the remote control via the rclone rc command {#api-rc}
Rclone itself implements the remote control protocol in its `rclone

View file

@ -2575,6 +2575,10 @@ Here is an example of making a Cloudflare R2 configuration. First run:
This will guide you through an interactive setup process.
Note that all buckets are private, and all are stored in the same
"auto" region. It is necessary to use Cloudflare workers to share the
content of a bucket publicly.
```
No remotes found, make a new one?
n) New remote
@ -2631,19 +2635,6 @@ Endpoint for S3 API.
Required when using an S3 clone.
Enter a value. Press Enter to leave empty.
endpoint> https://ACCOUNT_ID.r2.cloudflarestorage.com
Option acl.
Canned ACL used when creating buckets and storing or copying objects.
This ACL is used for creating objects and if bucket_acl isn't set, for creating buckets too.
For more info visit https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl
Note that this ACL is applied when server-side copying objects as S3
doesn't copy the ACL from the source but rather writes a fresh one.
Choose a number from below, or type in your own value.
Press Enter to leave empty.
/ Owner gets FULL_CONTROL.
1 | No one else has access rights (default).
\ (private)
...
acl> 1
Edit advanced config?
y) Yes
n) No (default)

View file

@ -230,7 +230,7 @@ func ConfigChoose(state string, name string, help string, n int, getItem func(i
// StatePush pushes a new values onto the front of the config string
func StatePush(state string, values ...string) string {
for i := range values {
values[i] = strings.Replace(values[i], ",", "", -1) // replace comma with unicode wide version
values[i] = strings.ReplaceAll(values[i], ",", "") // replace comma with unicode wide version
}
if state != "" {
values = append(values[:len(values):len(values)], state)
@ -262,7 +262,7 @@ func StatePop(state string) (newState string, value string) {
return "", state
}
value, newState = state[:comma], state[comma+1:]
value = strings.Replace(value, "", ",", -1) // replace unicode wide comma with comma
value = strings.ReplaceAll(value, "", ",") // replace unicode wide comma with comma
return newState, value
}

View file

@ -248,11 +248,11 @@ func AddConfig(ctx context.Context) (context.Context, *ConfigInfo) {
// "ignore-size") into an environment name
// "RCLONE_CONFIG_MY-REMOTE_IGNORE_SIZE"
func ConfigToEnv(section, name string) string {
return "RCLONE_CONFIG_" + strings.ToUpper(section+"_"+strings.Replace(name, "-", "_", -1))
return "RCLONE_CONFIG_" + strings.ToUpper(section+"_"+strings.ReplaceAll(name, "-", "_"))
}
// OptionToEnv converts an option name, e.g. "ignore-size" into an
// environment name "RCLONE_IGNORE_SIZE"
func OptionToEnv(name string) string {
return "RCLONE_" + strings.ToUpper(strings.Replace(name, "-", "_", -1))
return "RCLONE_" + strings.ToUpper(strings.ReplaceAll(name, "-", "_"))
}

View file

@ -50,7 +50,7 @@ func setConfigFile(t *testing.T, data string) func() {
// toUnix converts \r\n to \n in buf
func toUnix(buf string) string {
if runtime.GOOS == "windows" {
return strings.Replace(buf, "\r\n", "\n", -1)
return strings.ReplaceAll(buf, "\r\n", "\n")
}
return buf
}

View file

@ -417,7 +417,7 @@ func ChooseOption(o *fs.Option, name string) string {
fmt.Printf("Option %s.\n", o.Name)
if o.Help != "" {
// Show help string without empty lines.
help := strings.Replace(strings.TrimSpace(o.Help), "\n\n", "\n", -1)
help := strings.ReplaceAll(strings.TrimSpace(o.Help), "\n\n", "\n")
fmt.Println(help)
}

View file

@ -208,7 +208,7 @@ loop:
value := path[prev : i-1]
// replace any doubled quotes if there were any
if doubled {
value = strings.Replace(value, string(quote)+string(quote), string(quote), -1)
value = strings.ReplaceAll(value, string(quote)+string(quote), string(quote))
}
prev = i + 1
parsed.Config[param] = value

View file

@ -1407,7 +1407,7 @@ func TestDirMove(t *testing.T) {
require.NoError(t, operations.DirMove(ctx, r.Fremote, "A1", "A2"))
for i := range files {
files[i].Path = strings.Replace(files[i].Path, "A1/", "A2/", -1)
files[i].Path = strings.ReplaceAll(files[i].Path, "A1/", "A2/")
}
fstest.CheckListingWithPrecision(
@ -1432,7 +1432,7 @@ func TestDirMove(t *testing.T) {
require.NoError(t, operations.DirMove(ctx, r.Fremote, "A2", "A3"))
for i := range files {
files[i].Path = strings.Replace(files[i].Path, "A2/", "A3/", -1)
files[i].Path = strings.ReplaceAll(files[i].Path, "A2/", "A3/")
}
fstest.CheckListingWithPrecision(

View file

@ -44,7 +44,7 @@ type RegInfo struct {
// FileName returns the on disk file name for this backend
func (ri *RegInfo) FileName() string {
return strings.Replace(ri.Name, " ", "", -1)
return strings.ReplaceAll(ri.Name, " ", "")
}
// Options is a slice of configuration Option for a backend
@ -210,7 +210,7 @@ func (o *Option) Type() string {
// FlagName for the option
func (o *Option) FlagName(prefix string) string {
name := strings.Replace(o.Name, "_", "-", -1) // convert snake_case to kebab-case
name := strings.ReplaceAll(o.Name, "_", "-") // convert snake_case to kebab-case
if !o.NoPrefix {
name = prefix + "-" + name
}

View file

@ -1,4 +1,14 @@
package fs
// Version of rclone
var Version = "v1.59.0-DEV"
// Version of rclone containing the complete version string
var Version string
func init() {
if Version == "" {
if VersionSuffix == "" {
Version = VersionTag
} else {
Version = VersionTag + "-" + VersionSuffix
}
}
}

4
fs/versionsuffix.go Normal file
View file

@ -0,0 +1,4 @@
package fs
// VersionSuffix of rclone containing the pre-release label if any
var VersionSuffix = "DEV"

4
fs/versiontag.go Normal file
View file

@ -0,0 +1,4 @@
package fs
// VersionTag of rclone
var VersionTag = "v1.59.0"

View file

@ -317,7 +317,7 @@ func (r *Run) RemoveTestBinary() {
func (r *Run) Name() string {
ns := []string{
r.Backend,
strings.Replace(r.Path, "/", ".", -1),
strings.ReplaceAll(r.Path, "/", "."),
r.Remote,
}
if r.FastList {
@ -325,7 +325,7 @@ func (r *Run) Name() string {
}
ns = append(ns, fmt.Sprintf("%d", r.Try))
s := strings.Join(ns, "-")
s = strings.Replace(s, ":", "", -1)
s = strings.ReplaceAll(s, ":", "")
return s
}

View file

@ -30,7 +30,7 @@ func Add(fileName string, t time.Time) string {
base, ext := splitExt(fileName)
s := t.Format(versionFormat)
// Replace the '.' with a '-'
s = strings.Replace(s, ".", "-", -1)
s = strings.ReplaceAll(s, ".", "-")
return base + s + ext
}

View file

@ -365,32 +365,32 @@ func rename(osOldPath, osNewPath string) error {
if os.IsNotExist(err) {
return nil
}
return fmt.Errorf("Failed to stat source: %s: %w", osOldPath, err)
return fmt.Errorf("failed to stat source: %s: %w", osOldPath, err)
}
if !sfi.Mode().IsRegular() {
// cannot copy non-regular files (e.g., directories, symlinks, devices, etc.)
return fmt.Errorf("Non-regular source file: %s (%q)", sfi.Name(), sfi.Mode().String())
return fmt.Errorf("non-regular source file: %s (%q)", sfi.Name(), sfi.Mode().String())
}
dfi, err := os.Stat(osNewPath)
if err != nil {
if !os.IsNotExist(err) {
return fmt.Errorf("Failed to stat destination: %s: %w", osNewPath, err)
return fmt.Errorf("failed to stat destination: %s: %w", osNewPath, err)
}
parent := vfscommon.OsFindParent(osNewPath)
parent := vfscommon.OSFindParent(osNewPath)
err = createDir(parent)
if err != nil {
return fmt.Errorf("Failed to create parent dir: %s: %w", parent, err)
return fmt.Errorf("failed to create parent dir: %s: %w", parent, err)
}
} else {
if !(dfi.Mode().IsRegular()) {
return fmt.Errorf("Non-regular destination file: %s (%q)", dfi.Name(), dfi.Mode().String())
return fmt.Errorf("non-regular destination file: %s (%q)", dfi.Name(), dfi.Mode().String())
}
if os.SameFile(sfi, dfi) {
return nil
}
}
if err = os.Rename(osOldPath, osNewPath); err != nil {
return fmt.Errorf("Failed to rename in cache: %s to %s: %w", osOldPath, osNewPath, err)
return fmt.Errorf("failed to rename in cache: %s to %s: %w", osOldPath, osNewPath, err)
}
return nil
}

View file

@ -5,11 +5,11 @@ import (
"path/filepath"
)
// OsFindParent returns the parent directory of name, or "" for the
// OSFindParent returns the parent directory of name, or "" for the
// root for OS native paths.
func OsFindParent(name string) string {
func OSFindParent(name string) string {
parent := filepath.Dir(name)
if parent == "." || parent == "/" {
if parent == "." || (len(parent) == 1 && parent[0] == filepath.Separator) {
parent = ""
}
return parent