Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rclone #377

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
11 changes: 6 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ module github.com/spf13/afero
require (
cloud.google.com/go/storage v1.14.0
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8
github.com/pkg/sftp v1.13.1
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99
golang.org/x/text v0.3.4
google.golang.org/api v0.40.0
github.com/pkg/sftp v1.13.5-0.20211228200725-31aac3e1878d
github.com/rclone/rclone v1.59.1 // indirect
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb
golang.org/x/text v0.3.7
google.golang.org/api v0.83.0
)

go 1.16
741 changes: 741 additions & 0 deletions go.sum

Large diffs are not rendered by default.

67 changes: 67 additions & 0 deletions rclonefs/example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
### How to pass this test

This test can be used with any cloud storage,
which is available in RClone.

You must have installed RClone on your computer.

### Example: how to run this test with PCloud

1. Create PCloud account.
2. Create rclone configuration using this instruction:

https://rclone.org/pcloud/

Let's presume that the name of your remote storage, which
you put during the first step, is pcloud1.

```
name> pcloud
```

3. Put the file employee.yml or any other to the root
directory of your PCloud storage.
4. Make sure that your configuration works. For example,
run this command:

```
rclone cat pcloud1:employee.yml
```

pcloud1 is the name of your remote storage:
(2. name> pcloud1), person.json is in the root folder.

- you will see the content of the file in your console.

If your cloud storage contains buckets (Amazon S3,
minio, Backblaze B2) and the file employee.yml is put into
the bucket1, the access to the file is:

```go
rclone cat minio1:bucket1/employee.yml
```

minio1 is the name of your cloud storage.

The data is stored in the file rclone.conf. On Linux,
its default path is:

```
${HOME}/.config/rclone/rclone.conf
```

5. Create "/cfg/json" directory in your remote storage.
It will be your working directory in the example.

6. Put the name of your remote storage with the full
path '/cfg/json' to the file 'cloud.txt'

```
pcloud_mv1:/cfg/json
```

7. Run the example:

```
go run example.go
```
13 changes: 13 additions & 0 deletions rclonefs/example/call.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"call": 12,
"call_inline_function": 25,
"call_method1": 9,
"call_multiline_function": [8, 9],
"len": [
5,
3
],
"named_params": 12,
"named_params2": 5,
"standard_lib": "foo bar"
}
1 change: 1 addition & 0 deletions rclonefs/example/cloud.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pcloud_mv1:/cfg/json
19 changes: 19 additions & 0 deletions rclonefs/example/employee.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
# An employee record
name: Martin D'vloper
job: Developer
skill: Elite
employed: True
foods:
- Apple
- Orange
- Strawberry
- Mango
languages:
perl: Elite
python: Elite
pascal: Lame
education: |
4 GCSEs
3 A-Levels
BSc in the Internet of Things
217 changes: 217 additions & 0 deletions rclonefs/example/example.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
// Example and test
package main

import (
// "bytes"
"encoding/json"
"fmt"
"os"
"log"
"strings"

"github.com/spf13/afero"
"github.com/spf13/afero/rclonefs"
)

func main() {
rawpath, err := os.ReadFile("cloud.txt")
if err != nil {
log.Fatalf("Error in ReadFile: %v\n", err)
}

path := strings.TrimSpace(string(rawpath))

RFS, err := rclonefs.CreateRCFS(path, "")
if err != nil {
log.Fatalf("Error in CreateRCFS: %v\n", err)
}

// Test examples start.
// File path beginning from / is the absolute path.
// Otherwise it is the relative path.
fmt.Printf("Checking...\n")

// Create() test
file1, err := RFS.Create("/cfg/json/object.json") // absolute path
if err != nil {
log.Fatal("Create() test FAILED\n")
}
file1.Close()
ok, err := afero.Exists(RFS, "object.json") // relative path
if err != nil {
log.Fatalf("Error in Exists(): %v\n", err)
}
if ok {
fmt.Printf("Create() test passed.\n")
}

// Mkdir() test
err = RFS.Mkdir("../yml", 0750) // absolute path: /cfg/yml
if err != nil {
log.Fatal("Mkdir() test FAILED\n")
}
ok, err = afero.DirExists(RFS, "../yml")
if err != nil {
log.Fatalf("Error in DirExists(): %v\n", err)
}
if ok {
fmt.Printf("Mkdir() test passed.\n")
}

// MkdirAll() test
err = RFS.MkdirAll("../../data/passwords/sites", 0750) // absolute path: /data/passwords/sites
if err != nil {
log.Fatal("MkdirAll() test FAILED\n")
}
ok, err = afero.DirExists(RFS, "/data/passwords/sites")
if err != nil {
log.Fatalf("Error in DirExists(): %v\n", err)
}
if ok {
fmt.Printf("MkdirAll() test passed.\n")
}

// afero.WriteFile() test - the function is based on OpenFile()
// copying object.json to remote storage
data, err := os.ReadFile("object.json")
if err != nil {
log.Fatalf("Error in ReadFile(): %v\n", err)
}
afero.WriteFile(RFS, "object.json", data, 0644)

// Open() test
file1, err = RFS.Open("object.json")
if err != nil {
log.Fatal("Open() test FAILED\n")
}

// Stat() test
if fi, err := file1.Stat(); err == nil {
if size := fi.Size(); size == 129 {
fmt.Printf("Stat() test passed.\n")
}
}
file1.Close()

// afero.ReadFile() test - the function is based on Open()
data, err = afero.ReadFile(RFS, "object.json")
if err != nil {
log.Fatalf("Error in afero.ReadFile(): %v\n", err)
}

mp := make(map[string]interface{})
err = json.Unmarshal(data, &mp)
if err != nil {
log.Fatalf("Error in json.Unmarshal(): %v\n", err)
}

var test2 int = int(mp["test2"].(float64))
if test2 != 7 {
log.Fatal("afero.ReadFile() / Open() test FAILED")
}

fmt.Printf("Open(): all tests passed.\n")
fmt.Printf("OpenFile() test passed.\n")

// GetTempDir example
// Relative paths like "../cfg" do not work.
afero.GetTempDir(RFS, "cfg")

// SafeWriteReader example
srcfile, err := os.OpenFile("call.json", os.O_RDWR, 0644)
if err != nil {
log.Fatalf("Error in os.OpenFile(): %v\n", err)
}

err = afero.SafeWriteReader(RFS, "../../data/passwords/sites/github/call.json", srcfile)
if err != nil {
log.Fatalf("SafeWriteReader() test FAILED")
}
srcfile.Close()

ok, err = afero.Exists(RFS, "/data/passwords/sites/github/call.json")
if err != nil {
log.Fatalf("Error in afero.Exists(): %v\n", err)
}
if ok {
fmt.Printf("SafeWriteReader() / MkdirAll() test passed.\n")
}

// WriteReader example
srcfile, err = os.OpenFile("employee.yml", os.O_RDWR, 0644)
if err != nil {
log.Fatalf("Error in os.OpenFile(): %v\n", err)
}

err = afero.WriteReader(RFS, "/data/passwords/employee.yml", srcfile)
if err != nil {
log.Fatalf("WriteReader() test FAILED")
}
srcfile.Close()

ok, err = afero.Exists(RFS, "/data/passwords/employee.yml")
if err != nil {
log.Fatalf("Error in afero.Exists(): %v\n", err)
}
if ok {
fmt.Printf("WriteReader() / OpenFile() test passed.\n")
}

// TempDir() example
tdir, err := afero.TempDir(RFS, "../../cfg", "tmp")
if err != nil {
log.Fatalf("Error in afero.TempDir(): %v\n", err)
}

ok, err = afero.DirExists(RFS, tdir)
if err != nil {
log.Fatalf("Error in DirExists(): %v\n", err)
}
if ok {
fmt.Printf("TempDir() test passed.\n")
}

// Remove() test
err = RFS.Remove("/data/passwords/employee.yml")
if err != nil {
log.Fatal("Remove() test FAILED\n")
}

ok, err = afero.Exists(RFS, "/data/passwords/employee.yml")
if err != nil {
log.Fatal("Error in afero.Exists(): %v\n", err)
}
if !ok {
fmt.Printf("Remove() test passed.\n")
}

// RemoveAll() test
err = RFS.RemoveAll("../../data/passwords") // relative path
if err != nil {
log.Fatal("RemoveAll() test FAILED\n")
}

ok, err = afero.DirExists(RFS, "/data/passwords") // absolute path
if err != nil {
log.Fatal("Error in afero.DirExists(): %v\n", err)
}
if !ok {
fmt.Printf("RemoveAll() test passed.\n")
}

// Rename() test
err = RFS.Rename("object.json", "object2.json") // relative paths
if err != nil {
log.Fatal("Rename() test FAILED\n")
}

ok, err = afero.Exists(RFS, "/cfg/json/object2.json") // absolute path
if err != nil {
log.Fatal("Error in afero.Exists(): %v\n")
}
if ok {
fmt.Printf("Rename() test passed.\n")
}

fmt.Printf("ALL TESTS PASSED\n")
}
13 changes: 13 additions & 0 deletions rclonefs/example/object.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"object": {
"f": 1,
"g": 2
},
"test1": [
{
"kind": "Whiskey",
"qty": 1
}
],
"test2": 7
}