外层仓库管理 webgui 源码、Docker 编排与项目文档;rclone 作为
git submodule 锁定在上游 master HEAD(59c86b01b),不携带任何
我们的改动。
- webgui/: webgui 源码(原本位于 rclone/cmd/webgui/)
- web/: 原生 HTML/CSS/JS 静态前端(Anthropic 设计语言)
- webgui.go: Go 子命令源码,仅当自行构建 rclone 二进制时需要
- rclone-cmd-all-add-webgui-import.patch: 把 webgui 注册进
rclone 的 cmd/all/all.go 的补丁,留作 fork 时使用
- rclone/: submodule → github.com/rclone/rclone,纯净不改动
- Dockerfile.webgui: 基于 nginx:1.27-alpine,从 ./webgui/web/
COPY 静态资源
- docker/nginx.conf: SPA 静态托管 + 反向代理 RC API
(/config/、/operations/、/sync/、/job/ 等) 与文件下载
(/<remote>:<path>) 到 rclone rcd 容器,前端同源访问无 CORS
- docker-compose.yml: rclone (官方镜像 + rcd --rc-no-auth
--rc-serve) + gui (nginx) 双服务编排,config 走 bind mount
持久化
- DESIGN.md / CLAUDE.md / README.md: 文档
- .gitignore / .dockerignore: 排除 rclone.conf 等敏感文件,
Docker 构建上下文只剩 webgui/web/ + nginx 配置(几十 KB)
7.3 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project
Rclone ("rsync for cloud storage") is a command-line Go program that syncs files and directories to/from 70+ cloud storage providers. Entry point is rclone.go → cmd.Main(). Current Go toolchain requirement is in go.mod (the go directive); check it before assuming a version.
Build & install
go build # plain build
make # build with version metadata baked in (preferred on Unix)
make rclone # same as above, also installs into $(go env GOPATH)/bin
On Windows, make rclone also generates a version-stamped .syso resource file via bin/resource_windows.go before building, then deletes it. If you see a stray resource_windows_*.syso it was left behind by an interrupted build.
-X github.com/rclone/rclone/fs.Version=$(TAG) is passed via -ldflags; the version string the binary reports is built from VERSION + git metadata in the Makefile (TAG := $(VERSION)$(VERSION_SUFFIX)$(TAG_BRANCH)). Bump VERSION only via the startdev/startstable Makefile targets, not by hand.
Tests
Rclone's tests run against real backends configured as Test<Name>: sections in the rclone config file. Tests requiring a missing section are skipped automatically — a clean go test ./... from a fresh checkout just runs the local-FS-only subset.
# Run a single package's tests
cd backend/drive && go test -v
# Run one test in one package
cd fs/sync && go test -v -run TestSync
# Quick test of everything (no remote creds needed; sets bogus config to force skips)
make quicktest
# Run a package's integration tests against a configured remote
cd fs/sync && go test -v -remote TestDrive:
cd fs/sync && go test -v -remote TestDrive: -fast-list # exercise ListR path
cd fs/operations && go test -v -remote TestDrive:
# Full integration framework from repo root, one backend at a time
go run ./fstest/test_all -backends drive
# Race detector
make racequicktest
Backend test remotes are registered in fstest/test_all/config.yaml. Some tests there have ignore: entries that document intentional skips (e.g. B2 versioning makes certain purge tests impossible).
Lint / quality
make check # golangci-lint + markdownlint, same as CI
golangci-lint run ./... # Go only
bin/markdown-lint # Markdown only
.golangci.yml enables: errcheck, govet, ineffassign, staticcheck, unused, gocritic, misspell, revive, unconvert, plus the goimports formatter. gocritic ruleguard rules live in bin/rules.go. golangci-lint v2 config format is in use.
Architecture
Layered, with fs/ as the contract layer:
fs/— core interfaces and primitives.fs.Fs,fs.Object,fs.DirInfo(infs/types.goandfs/fs.go) are the contracts every backend implements. Sub-packages:fs/operations— primitives (Copy,Move,MoveDir,check, dedupe, listdirsorted, lsjson)fs/sync—sync.Sync(one-way) and the pipe-based engine; also drivesbisyncfs/march— walks two Fs trees in lock step, emitting diffsfs/filter— include/exclude rulesfs/config— config file, flags, obscured creds, rc config;configfile/configflags/configstruct/configmapare sub-packagesfs/fshttp— rclone'shttp.Client/Transport; backends must use this to inherit--dump,--tpslimit,--user-agent, etc.fs/accounting,fs/cache,fs/fspath,fs/hash,fs/log,fs/rc(+rcserver)
backend/— one subdirectory per provider (drive, s3, dropbox, sftp, local, …).backend/all/all.goimports them all via blank imports;rclone.goimportsbackend/all. There are virtual/wrapper backends too:alias,archive,cache,chunker,combine,compress,crypt,hasher,union.cmd/— one subdirectory per CLI subcommand (copy,sync,mount,serve,bisync, …).cmd/all/all.goregisters them;cmd/cmd.gois the cobra entry point.lib/— cross-cutting libraries backends and fs both use:rest(thin net/http wrapper for REST APIs),pacer(retry/backoff),dircache,oauthutil,encoder(filename encoding),readers,atexit,errcount,exitcode,multipart,plugin, etc.vfs/— virtual filesystem layer formount/cmount/mountlib/nfsmount.librclone/— embeddable in-memory API for users who want rclone as a library.fstest/— integration test framework:fstests(per-backend suite),mockdir/mockobject,test_all(driver that readsconfig.yaml).cmdtest/— end-to-end tests of CLI flags, env vars, exit codes.
rclone.go is intentionally tiny: it blank-imports backend/all, cmd/all, lib/plugin, then calls cmd.Main().
Conventions
Commit messages follow <area>: <summary> where <area> is the directory touched (drive:, fs/sync:, mount:, completion:). The changelog is generated from these first lines, so make them user-readable. Long form goes after a blank line, mentioning Fixes #N to auto-close.
New backend layout (see CONTRIBUTING.md "Writing a new backend"):
- Implement in a single
backend/<name>/<name>.go— do not split intofs.goandobject.go. The maintainers explicitly reject this for the >50 existing backends. - Put API type definitions in
api/types.go. - Follow the structure of
backend/box(directory-based) orbackend/b2(bucket-based) exactly — same function names, same order, same comments. - For HTTP backends, use
lib/restand the client fromfs/fshttp. Don't roll your own transport. - Register in
backend/all/all.goand add tofstest/test_all/config.yaml.
Backend options are declared in Go with Help: fields that get rendered into docs and --flag help. See CONTRIBUTING.md "Writing Documentation" for the rules: first sentence on one line ≤80 chars, ends with period, more detail after a blank "\n\n". The Markdown in docs/content/<name>.md between <!-- autogenerated options start -->…<!-- autogenerated options stop --> markers is regenerated by bin/make_backend_docs.py — never edit those regions by hand.
Documentation autogeneration. MANUAL.md, MANUAL.html, MANUAL.txt, rclone.1, docs/content/flags.md, docs/content/commands/*.md, and the autogenerated portions of backend docs are all produced from Go source by Makefile targets (make doc, make commanddocs, make backenddocs, make rcdocs). bin/check_autogenerated_edits.py runs in CI and rejects PRs that hand-edit those regions. You normally don't run these locally — they run during the release process. The docs/ site is built with Hugo (make serve to preview).
go generate is used in lib/transform and cmd/bisync (see the commanddocs target). Run those before regenerating command docs.
Configuration system. Top-level flags live in fs/config/configflags. Backend options are defined per-backend via Options structs with configstruct tags and surfaced automatically. The --config flag points at the rclone.conf used both at runtime and for Test<Name>: test remotes.
Version tagging. Tags are GPG-signed (make retag). make beta / make ci_beta publish to beta.rclone.org. Full release flow is in RELEASE.md.