mirror of
https://github.com/rclone/rclone.git
synced 2026-01-12 05:23:55 +00:00
Compare commits
3 Commits
fix-bitrix
...
build-ndk
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7fb4d823b2 | ||
|
|
cfa35cec04 | ||
|
|
039acae160 |
199
.github/workflows/build.yml
vendored
199
.github/workflows/build.yml
vendored
@@ -14,205 +14,6 @@ on:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
timeout-minutes: 60
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
job_name: ['linux', 'mac_amd64', 'mac_arm64', 'windows_amd64', 'windows_386', 'other_os', 'go1.13', 'go1.14', 'go1.15']
|
||||
|
||||
include:
|
||||
- job_name: linux
|
||||
os: ubuntu-latest
|
||||
go: '1.16.x'
|
||||
gotags: cmount
|
||||
build_flags: '-include "^linux/"'
|
||||
check: true
|
||||
quicktest: true
|
||||
racequicktest: true
|
||||
deploy: true
|
||||
|
||||
- job_name: mac_amd64
|
||||
os: macOS-latest
|
||||
go: '1.16.x'
|
||||
gotags: 'cmount'
|
||||
build_flags: '-include "^darwin/amd64" -cgo'
|
||||
quicktest: true
|
||||
racequicktest: true
|
||||
deploy: true
|
||||
|
||||
- job_name: mac_arm64
|
||||
os: macOS-latest
|
||||
go: '1.16.x'
|
||||
gotags: 'cmount'
|
||||
build_flags: '-include "^darwin/arm64" -cgo -macos-arch arm64 -macos-sdk macosx11.1 -cgo-cflags=-I/usr/local/include -cgo-ldflags=-L/usr/local/lib'
|
||||
deploy: true
|
||||
|
||||
- job_name: windows_amd64
|
||||
os: windows-latest
|
||||
go: '1.16.x'
|
||||
gotags: cmount
|
||||
build_flags: '-include "^windows/amd64" -cgo'
|
||||
build_args: '-buildmode exe'
|
||||
quicktest: true
|
||||
racequicktest: true
|
||||
deploy: true
|
||||
|
||||
- job_name: windows_386
|
||||
os: windows-latest
|
||||
go: '1.16.x'
|
||||
gotags: cmount
|
||||
goarch: '386'
|
||||
cgo: '1'
|
||||
build_flags: '-include "^windows/386" -cgo'
|
||||
build_args: '-buildmode exe'
|
||||
quicktest: true
|
||||
deploy: true
|
||||
|
||||
- job_name: other_os
|
||||
os: ubuntu-latest
|
||||
go: '1.16.x'
|
||||
build_flags: '-exclude "^(windows/|darwin/|linux/)"'
|
||||
compile_all: true
|
||||
deploy: true
|
||||
|
||||
- job_name: go1.13
|
||||
os: ubuntu-latest
|
||||
go: '1.13.x'
|
||||
quicktest: true
|
||||
|
||||
- job_name: go1.14
|
||||
os: ubuntu-latest
|
||||
go: '1.14.x'
|
||||
quicktest: true
|
||||
racequicktest: true
|
||||
|
||||
- job_name: go1.15
|
||||
os: ubuntu-latest
|
||||
go: '1.15.x'
|
||||
quicktest: true
|
||||
racequicktest: true
|
||||
|
||||
name: ${{ matrix.job_name }}
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
stable: 'false'
|
||||
go-version: ${{ matrix.go }}
|
||||
|
||||
- name: Set environment variables
|
||||
shell: bash
|
||||
run: |
|
||||
echo 'GOTAGS=${{ matrix.gotags }}' >> $GITHUB_ENV
|
||||
echo 'BUILD_FLAGS=${{ matrix.build_flags }}' >> $GITHUB_ENV
|
||||
echo 'BUILD_ARGS=${{ matrix.build_args }}' >> $GITHUB_ENV
|
||||
if [[ "${{ matrix.goarch }}" != "" ]]; then echo 'GOARCH=${{ matrix.goarch }}' >> $GITHUB_ENV ; fi
|
||||
if [[ "${{ matrix.cgo }}" != "" ]]; then echo 'CGO_ENABLED=${{ matrix.cgo }}' >> $GITHUB_ENV ; fi
|
||||
|
||||
- name: Install Libraries on Linux
|
||||
shell: bash
|
||||
run: |
|
||||
sudo modprobe fuse
|
||||
sudo chmod 666 /dev/fuse
|
||||
sudo chown root:$USER /etc/fuse.conf
|
||||
sudo apt-get install fuse libfuse-dev rpm pkg-config
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
|
||||
- name: Install Libraries on macOS
|
||||
shell: bash
|
||||
run: |
|
||||
brew update
|
||||
brew install --cask macfuse
|
||||
if: matrix.os == 'macOS-latest'
|
||||
|
||||
- name: Install Libraries on Windows
|
||||
shell: powershell
|
||||
run: |
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
choco install -y winfsp zip
|
||||
echo "CPATH=C:\Program Files\WinFsp\inc\fuse;C:\Program Files (x86)\WinFsp\inc\fuse" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
if ($env:GOARCH -eq "386") {
|
||||
choco install -y mingw --forcex86 --force
|
||||
echo "C:\\ProgramData\\chocolatey\\lib\\mingw\\tools\\install\\mingw32\\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
}
|
||||
# Copy mingw32-make.exe to make.exe so the same command line
|
||||
# can be used on Windows as on macOS and Linux
|
||||
$path = (get-command mingw32-make.exe).Path
|
||||
Copy-Item -Path $path -Destination (Join-Path (Split-Path -Path $path) 'make.exe')
|
||||
if: matrix.os == 'windows-latest'
|
||||
|
||||
- name: Print Go version and environment
|
||||
shell: bash
|
||||
run: |
|
||||
printf "Using go at: $(which go)\n"
|
||||
printf "Go version: $(go version)\n"
|
||||
printf "\n\nGo environment:\n\n"
|
||||
go env
|
||||
printf "\n\nRclone environment:\n\n"
|
||||
make vars
|
||||
printf "\n\nSystem environment:\n\n"
|
||||
env
|
||||
|
||||
- name: Go module cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
|
||||
- name: Build rclone
|
||||
shell: bash
|
||||
run: |
|
||||
make
|
||||
|
||||
- name: Run tests
|
||||
shell: bash
|
||||
run: |
|
||||
make quicktest
|
||||
if: matrix.quicktest
|
||||
|
||||
- name: Race test
|
||||
shell: bash
|
||||
run: |
|
||||
make racequicktest
|
||||
if: matrix.racequicktest
|
||||
|
||||
- name: Code quality test
|
||||
shell: bash
|
||||
run: |
|
||||
make build_dep
|
||||
make check
|
||||
if: matrix.check
|
||||
|
||||
- name: Compile all architectures test
|
||||
shell: bash
|
||||
run: |
|
||||
make
|
||||
make compile_all
|
||||
if: matrix.compile_all
|
||||
|
||||
- name: Deploy built binaries
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "${{ matrix.os }}" == "ubuntu-latest" ]]; then make release_dep_linux ; fi
|
||||
if [[ "${{ matrix.os }}" == "windows-latest" ]]; then make release_dep_windows ; fi
|
||||
make ci_beta
|
||||
env:
|
||||
RCLONE_CONFIG_PASS: ${{ secrets.RCLONE_CONFIG_PASS }}
|
||||
# working-directory: '$(modulePath)'
|
||||
# Deploy binaries if enabled in config && not a PR && not a fork
|
||||
if: matrix.deploy && github.head_ref == '' && github.repository == 'rclone/rclone'
|
||||
|
||||
android:
|
||||
timeout-minutes: 30
|
||||
name: "android-all"
|
||||
|
||||
@@ -1137,7 +1137,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op
|
||||
// opts.Body=0), so upload it as a multipart form POST with
|
||||
// Content-Length set.
|
||||
if size == 0 {
|
||||
formReader, contentType, overhead, err := rest.MultipartUpload(ctx, in, opts.Parameters, "content", leaf)
|
||||
formReader, contentType, overhead, err := rest.MultipartUpload(in, opts.Parameters, "content", leaf)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to make multipart upload for 0 length file")
|
||||
}
|
||||
|
||||
@@ -682,7 +682,7 @@ func (f *Fs) upload(ctx context.Context, in io.Reader, uploadLink, filePath stri
|
||||
"need_idx_progress": {"true"},
|
||||
"replace": {"1"},
|
||||
}
|
||||
formReader, contentType, _, err := rest.MultipartUpload(ctx, in, parameters, "file", f.opt.Enc.FromStandardName(filename))
|
||||
formReader, contentType, _, err := rest.MultipartUpload(in, parameters, "file", f.opt.Enc.FromStandardName(filename))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to make multipart upload")
|
||||
}
|
||||
|
||||
@@ -1067,7 +1067,7 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string
|
||||
Path: addSlash(srcPath),
|
||||
NoResponse: true,
|
||||
ExtraHeaders: map[string]string{
|
||||
"Destination": destinationURL.String(),
|
||||
"Destination": addSlash(destinationURL.String()),
|
||||
"Overwrite": "F",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -647,7 +647,7 @@ func (f *Fs) upload(ctx context.Context, name string, parent string, size int64,
|
||||
params.Set("filename", name)
|
||||
params.Set("parent_id", parent)
|
||||
params.Set("override-name-exist", strconv.FormatBool(true))
|
||||
formReader, contentType, overhead, err := rest.MultipartUpload(ctx, in, nil, "content", name)
|
||||
formReader, contentType, overhead, err := rest.MultipartUpload(in, nil, "content", name)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to make multipart upload")
|
||||
}
|
||||
|
||||
@@ -476,4 +476,3 @@ put them back in again.` >}}
|
||||
* Naveen Honest Raj <naveendurai19@gmail.com>
|
||||
* Lucas Messenger <lmesseng@cisco.com>
|
||||
* Manish Kumar <krmanish260@gmail.com>
|
||||
* x0b <x0bdev@gmail.com>
|
||||
|
||||
@@ -8,8 +8,8 @@ Configure
|
||||
|
||||
First, you'll need to configure rclone. As the object storage systems
|
||||
have quite complicated authentication these are kept in a config file.
|
||||
(See the [`--config`](#config-config-file) entry for how to find the config
|
||||
file and choose its location.)
|
||||
(See the `--config` entry for how to find the config file and choose
|
||||
its location.)
|
||||
|
||||
The easiest way to make the config is to run rclone with the config
|
||||
option:
|
||||
@@ -639,7 +639,7 @@ See `--copy-dest` and `--backup-dir`.
|
||||
|
||||
### --config=CONFIG_FILE ###
|
||||
|
||||
Specify the location of the rclone configuration file.
|
||||
Specify the location of the rclone config file.
|
||||
|
||||
Normally the config file is in your home directory as a file called
|
||||
`.config/rclone/rclone.conf` (or `.rclone.conf` if created with an
|
||||
@@ -656,44 +656,8 @@ location is for you.
|
||||
Use this flag to override the config location, e.g. `rclone
|
||||
--config=".myconfig" .config`.
|
||||
|
||||
If the location is set to empty string `""` or the special value
|
||||
`/notfound`, or the os null device represented by value `NUL` on
|
||||
Windows and `/dev/null` on Unix systems, then rclone will keep the
|
||||
config file in memory only.
|
||||
|
||||
The file format is basic [INI](https://en.wikipedia.org/wiki/INI_file#Format):
|
||||
Sections of text, led by a `[section]` header and followed by
|
||||
`key=value` entries on separate lines. In rclone each remote is
|
||||
represented by its own section, where the section name defines the
|
||||
name of the remote. Options are specified as the `key=value` entries,
|
||||
where the key is the option name without the `--backend-` prefix,
|
||||
in lowercase and with `_` instead of `-`. E.g. option `--mega-hard-delete`
|
||||
corresponds to key `hard_delete`. Only backend options can be specified.
|
||||
A special, and required, key `type` identifies the [storage system](/overview/),
|
||||
where the value is the internal lowercase name as returned by command
|
||||
`rclone help backends`. Comments are indicated by `;` or `#` at the
|
||||
beginning of a line.
|
||||
|
||||
Example:
|
||||
|
||||
[megaremote]
|
||||
type = mega
|
||||
user = you@example.com
|
||||
pass = PDPcQVVjVtzFY-GTdDFozqBhTdsPg3qH
|
||||
|
||||
Note that passwords are in [obscured](/commands/rclone_obscure/)
|
||||
form. Also, many storage systems uses token-based authentication instead
|
||||
of passwords, and this requires additional steps. It is easier, and safer,
|
||||
to use the interactive command `rclone config` instead of manually
|
||||
editing the configuration file.
|
||||
|
||||
The configuration file will typically contain login information, and
|
||||
should therefore have restricted permissions so that only the current user
|
||||
can read it. Rclone tries to ensure this when it writes the file.
|
||||
You may also choose to [encrypt](#configuration-encryption) the file.
|
||||
|
||||
When token-based authentication are used, the configuration file
|
||||
must be writable, because rclone needs to update the tokens inside it.
|
||||
If this is set to empty string or the special value `/notfound` then
|
||||
rclone will keep the config file in memory only.
|
||||
|
||||
### --contimeout=TIME ###
|
||||
|
||||
|
||||
@@ -450,7 +450,6 @@ func TestRcFsInfo(t *testing.T) {
|
||||
func TestUploadFile(t *testing.T) {
|
||||
r, call := rcNewRun(t, "operations/uploadfile")
|
||||
defer r.Finalise()
|
||||
ctx := context.Background()
|
||||
|
||||
testFileName := "test.txt"
|
||||
testFileContent := "Hello World"
|
||||
@@ -461,7 +460,7 @@ func TestUploadFile(t *testing.T) {
|
||||
currentFile, err := os.Open(path.Join(r.LocalName, testFileName))
|
||||
require.NoError(t, err)
|
||||
|
||||
formReader, contentType, _, err := rest.MultipartUpload(ctx, currentFile, url.Values{}, "file", testFileName)
|
||||
formReader, contentType, _, err := rest.MultipartUpload(currentFile, url.Values{}, "file", testFileName)
|
||||
require.NoError(t, err)
|
||||
|
||||
httpReq := httptest.NewRequest("POST", "/", formReader)
|
||||
@@ -483,7 +482,7 @@ func TestUploadFile(t *testing.T) {
|
||||
currentFile, err = os.Open(path.Join(r.LocalName, testFileName))
|
||||
require.NoError(t, err)
|
||||
|
||||
formReader, contentType, _, err = rest.MultipartUpload(ctx, currentFile, url.Values{}, "file", testFileName)
|
||||
formReader, contentType, _, err = rest.MultipartUpload(currentFile, url.Values{}, "file", testFileName)
|
||||
require.NoError(t, err)
|
||||
|
||||
httpReq = httptest.NewRequest("POST", "/", formReader)
|
||||
|
||||
2
go.mod
2
go.mod
@@ -17,7 +17,7 @@ require (
|
||||
github.com/anacrolix/dms v1.2.0
|
||||
github.com/atotto/clipboard v0.1.2
|
||||
github.com/aws/aws-sdk-go v1.37.3
|
||||
github.com/billziss-gh/cgofuse v1.5.0
|
||||
github.com/billziss-gh/cgofuse v1.4.0
|
||||
github.com/buengese/sgzip v0.1.1
|
||||
github.com/calebcase/tmpfile v1.0.2 // indirect
|
||||
github.com/colinmarc/hdfs/v2 v2.2.0
|
||||
|
||||
2
go.sum
2
go.sum
@@ -113,8 +113,6 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/billziss-gh/cgofuse v1.4.0 h1:kju2jDmdNuDDCrxPob2ggmZr5Mj/odCjU1Y8kx0Th9E=
|
||||
github.com/billziss-gh/cgofuse v1.4.0/go.mod h1:LJjoaUojlVjgo5GQoEJTcJNqZJeRU0nCR84CyxKt2YM=
|
||||
github.com/billziss-gh/cgofuse v1.5.0 h1:kH516I/s+Ab4diL/Y/ayFeUjjA8ey+JK12xDfBf4HEs=
|
||||
github.com/billziss-gh/cgofuse v1.5.0/go.mod h1:LJjoaUojlVjgo5GQoEJTcJNqZJeRU0nCR84CyxKt2YM=
|
||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||
github.com/bradfitz/iter v0.0.0-20140124041915-454541ec3da2/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo=
|
||||
github.com/bradfitz/iter v0.0.0-20190303215204-33e6a9893b0c/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo=
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
package readers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
)
|
||||
|
||||
// NewContextReader creates a reader, that returns any errors that ctx gives
|
||||
func NewContextReader(ctx context.Context, r io.Reader) io.Reader {
|
||||
return &contextReader{
|
||||
ctx: ctx,
|
||||
r: r,
|
||||
}
|
||||
}
|
||||
|
||||
type contextReader struct {
|
||||
ctx context.Context
|
||||
r io.Reader
|
||||
}
|
||||
|
||||
// Read bytes as per io.Reader interface
|
||||
func (cr *contextReader) Read(p []byte) (n int, err error) {
|
||||
err = cr.ctx.Err()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return cr.r.Read(p)
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package readers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestContextReader(t *testing.T) {
|
||||
r := NewPatternReader(100)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cr := NewContextReader(ctx, r)
|
||||
|
||||
var buf = make([]byte, 3)
|
||||
|
||||
n, err := cr.Read(buf)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 3, n)
|
||||
assert.Equal(t, []byte{0, 1, 2}, buf)
|
||||
|
||||
cancel()
|
||||
|
||||
n, err = cr.Read(buf)
|
||||
assert.Equal(t, context.Canceled, err)
|
||||
assert.Equal(t, 0, n)
|
||||
}
|
||||
@@ -308,7 +308,7 @@ func (api *Client) Call(ctx context.Context, opts *Opts) (resp *http.Response, e
|
||||
// the int64 returned is the overhead in addition to the file contents, in case Content-Length is required
|
||||
//
|
||||
// NB This doesn't allow setting the content type of the attachment
|
||||
func MultipartUpload(ctx context.Context, in io.Reader, params url.Values, contentName, fileName string) (io.ReadCloser, string, int64, error) {
|
||||
func MultipartUpload(in io.Reader, params url.Values, contentName, fileName string) (io.ReadCloser, string, int64, error) {
|
||||
bodyReader, bodyWriter := io.Pipe()
|
||||
writer := multipart.NewWriter(bodyWriter)
|
||||
contentType := writer.FormDataContentType()
|
||||
@@ -343,21 +343,8 @@ func MultipartUpload(ctx context.Context, in io.Reader, params url.Values, conte
|
||||
|
||||
multipartLength := int64(buf.Len())
|
||||
|
||||
// Make sure we close the pipe writer to release the reader on context cancel
|
||||
quit := make(chan struct{})
|
||||
go func() {
|
||||
select {
|
||||
case <-quit:
|
||||
break
|
||||
case <-ctx.Done():
|
||||
_ = bodyWriter.CloseWithError(ctx.Err())
|
||||
}
|
||||
}()
|
||||
|
||||
// Pump the data in the background
|
||||
go func() {
|
||||
defer close(quit)
|
||||
|
||||
var err error
|
||||
|
||||
for key, vals := range params {
|
||||
@@ -465,7 +452,7 @@ func (api *Client) callCodec(ctx context.Context, opts *Opts, request interface{
|
||||
opts = opts.Copy()
|
||||
|
||||
var overhead int64
|
||||
opts.Body, opts.ContentType, overhead, err = MultipartUpload(ctx, opts.Body, params, opts.MultipartContentName, opts.MultipartFileName)
|
||||
opts.Body, opts.ContentType, overhead, err = MultipartUpload(opts.Body, params, opts.MultipartContentName, opts.MultipartFileName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user