Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ builds:
- darwin
ldflags:
- -s -w
- -X main.appVersion={{.Version}}
- -X main.appBuildDate={{.Date}}
- -X main.appGitCommit={{.FullCommit}}

archives:
- formats: ["tar.gz"]
Expand Down
277 changes: 239 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,70 +1,199 @@
# sftp-sync
<!-- Improved compatibility of back to top link: See: https://github.com/othneildrew/Best-README-Template/pull/73 -->
<a id="readme-top"></a>
<!--
*** Thanks for checking out the Best-README-Template. If you have a suggestion
*** that would make this better, please fork the repo and create a pull request
*** or simply open an issue with the tag "enhancement".
*** Don't forget to give the project a star!
*** Thanks again! Now go create something AMAZING! :D
-->



<!-- PROJECT SHIELDS -->
<!--
*** I'm using markdown "reference style" links for readability.
*** Reference links are enclosed in brackets [ ] instead of parentheses ( ).
*** See the bottom of this document for the declaration of the reference variables
*** for contributors-url, forks-url, etc. This is an optional, concise syntax you may use.
*** https://www.markdownguide.org/basic-syntax/#reference-style-links
-->
[![Code Size][code-size-shield]][code-size-url]
[![Contributors][contributors-shield]][contributors-url]
[![Forks][forks-shield]][forks-url]
[![Go Report Card][go-report-card-shield]][go-report-card-url]
[![Go Version][go-version-shield]][go-version-url]
[![Issues][issues-shield]][issues-url]
[![Last Commit][last-commit-shield]][last-commit-url]
[![License][license-shield]][license-url]
[![Stargazers][stars-shield]][stars-url]



<!-- PROJECT LOGO -->
<br />
<div align="center">
<a href="https://github.com/capcom6/sftp-sync">
<img src="images/logo.png" alt="Logo" width="80" height="80">
</a>

<h3 align="center">sftp-sync</h3>

<p align="center">
A command-line utility for syncing a local folder with a remote FTP server on every change of files or directories.
Comment thread
capcom6 marked this conversation as resolved.
<br />
<br />
<a href="https://github.com/capcom6/sftp-sync/issues/new?labels=bug&template=bug-report---.md">Report Bug</a>
&middot;
<a href="https://github.com/capcom6/sftp-sync/issues/new?labels=enhancement&template=feature-request---.md">Request Feature</a>
</p>
</div>

sftp-sync is a command-line utility for syncing a local folder with a remote FTP server on every change of files or directories.

## Table of contents

- [sftp-sync](#sftp-sync)
- [Table of contents](#table-of-contents)
<!-- TABLE OF CONTENTS -->
- [About The Project](#about-the-project)
- [Features](#features)
- [Installation](#installation)
- [Usage](#usage)
- [Options](#options)
- [Arguments](#arguments)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
- [License](#license)
- [Built With](#built-with)
- [Installation](#installation)
- [Prerequisites](#prerequisites)
- [Installation Methods](#installation-methods)
- [Method 1: Using Go Install (Recommended)](#method-1-using-go-install-recommended)
- [Method 2: Using Release Binaries](#method-2-using-release-binaries)
- [Method 3: Building from Source](#method-3-building-from-source)
- [Usage](#usage)
- [Environment Variables](#environment-variables)
- [Global Options](#global-options)
- [Sync Command Options](#sync-command-options)
- [Sync Command Arguments](#sync-command-arguments)
- [Error Handling](#error-handling)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
- [License](#license)
- [Contact](#contact)
- [Acknowledgments](#acknowledgments)
Comment thread
capcom6 marked this conversation as resolved.

<!-- ABOUT THE PROJECT -->
## About The Project

## Features
<!-- [![Product Name Screen Shot][product-screenshot]](https://example.com) -->

sftp-sync is a command-line utility for syncing a local folder with a remote FTP server on every change of files or directories.

### Features

- Continuous synchronization: Automatically syncs local changes to the remote FTP server whenever files or directories are added, modified, or deleted.
- Exclude paths: Allows you to exclude specific paths from being synced.
- Easy to use: Simple and intuitive command-line interface.

<p align="right">(<a href="#readme-top">back to top</a>)</p>

### Built With

* [![Go][Go.dev]][Go-url]
* [![urfave/cli][urfave-cli-v3]][urfave-cli-v3-url]
* [![fsnotify][fsnotify]][fsnotify-url]
* [![joho/godotenv][godotenv]][godotenv-url]

<p align="right">(<a href="#readme-top">back to top</a>)</p>



<!-- INSTALLATION -->
## Installation

You can download the pre-built binary for your operating system from the [Releases](https://github.com/capcom6/sftp-sync/releases) section of the GitHub repository.
### Prerequisites

If you prefer to build from source, make sure you have Go installed. If not, you can download it from the official Go website: https://golang.org/dl/
- Go 1.24.3 or higher installed on your system
- Access to an FTP server with valid credentials

Then, follow these steps:
### Installation Methods

1. Clone the sftp-sync repository:
```shell
git clone https://github.com/capcom6/sftp-sync.git
```
#### Method 1: Using Go Install (Recommended)

2. Build the sftp-sync binary using the following command:
```shell
cd sftp-sync
go build -o sftp-sync .
```
Install the latest version directly from the repository:

3. The binary will be generated in the current directory. You can move it to a location in your PATH for easy access.
```shell
go install github.com/capcom6/sftp-sync@latest
```

This will install `sftp-sync` to your `$GOBIN` directory. Make sure your `$GOBIN` is in your `$PATH`.

## Usage
#### Method 2: Using Release Binaries

Download the pre-compiled binaries from the [GitHub Releases](https://github.com/capcom6/sftp-sync/releases) page:

1. Download the binary for your operating system and architecture
2. Make the binary executable:
```shell
chmod +x sftp-sync
```
3. Move it to a directory in your `$PATH`:
```shell
sudo mv sftp-sync /usr/local/bin/
```

#### Method 3: Building from Source

If you prefer to build from source:

Run the `sftp-sync` command followed by the necessary options and arguments:
```shell
git clone https://github.com/capcom6/sftp-sync.git
cd sftp-sync
make build
```

The binary will be available in the `bin/` directory.

<p align="right">(<a href="#readme-top">back to top</a>)</p>



<!-- USAGE EXAMPLES -->
## Usage
Run the `sftp-sync` command with the necessary options and arguments:

```shell
sftp-sync --dest=ftp://username:password@hostname:port/path/to/remote/folder --exclude=.git /path/to/local/folder
sftp-sync --dest=ftp://username:password@hostname:port/path/to/remote/folder \
--exclude=.git /path/to/local/folder
```
Comment thread
capcom6 marked this conversation as resolved.

### Options
### Environment Variables

- `DEBUG`: When set to any value, enables debug mode (equivalent to `--debug` flag).

### Global Options

- `--debug`: Enable debug mode (can also be set via `DEBUG` environment variable).
- `--version`: Print version information.

### Sync Command Options

- `--dest`: The destination FTP server URL. It should follow the format `ftp://username:password@hostname:port/path/to/remote/folder`.
- `--exclude`: (Optional) Specifies paths or patterns to exclude from the synchronization process. You can specify multiple `--exclude` options to exclude multiple paths or patterns.
- `--debug`: Enable debug mode.

### Arguments
### Sync Command Arguments

- The local folder path: The path to the local folder you want to sync with the remote FTP server.
- `source`: The local folder path to watch for changes (required positional argument).

## Roadmap
<p align="right">(<a href="#readme-top">back to top</a>)</p>

### Error Handling

The application uses structured error handling with specific exit codes:

- `0`: Success - operation completed successfully
- `1`: Parameters Error - invalid command arguments or options
- `2`: Client Error - FTP client connection or operation failed
- `3`: Output Error - logging or output system failed
- `4`: Internal Error - unexpected internal error

Here are some ideas and suggestions for future releases:
<p align="right">(<a href="#readme-top">back to top</a>)</p>



<!-- ROADMAP -->
## Roadmap

- [ ] Support for patterns in the `--exclude` option.
- [ ] Support of Secure FTP (SFTP) protocol.
Expand All @@ -77,12 +206,84 @@ Here are some ideas and suggestions for future releases:
- [ ] Parallel sync in multiple threads.
- [ ] Batching events for more effective sync on frequently changes.

Feel free to open an issue or submit a pull request if you have any other ideas or suggestions!
See the [open issues](https://github.com/capcom6/sftp-sync/issues) for a full list of proposed features (and known issues).

<p align="right">(<a href="#readme-top">back to top</a>)</p>



<!-- CONTRIBUTING -->
## Contributing

Contributions are welcome! If you find any issues or have suggestions for improvements, please open an issue or submit a pull request on the GitHub repository.
Contributions are what make the open-source community a great place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.

If you have a suggestion to improve this project, please fork the repository and open a pull request. You can also open an issue with the `enhancement` label.
If this project is useful to you, consider starring it.

1. Fork the Project
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the Branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request

<p align="right">(<a href="#readme-top">back to top</a>)</p>

<!-- LICENSE -->
## License

This project is licensed under the [Apache License 2.0](LICENSE).
Distributed under the Apache License 2.0. See `LICENSE` for more information.

<p align="right">(<a href="#readme-top">back to top</a>)</p>



<!-- CONTACT -->
## Contact

Project Link: [https://github.com/capcom6/sftp-sync](https://github.com/capcom6/sftp-sync)

<p align="right">(<a href="#readme-top">back to top</a>)</p>



<!-- ACKNOWLEDGMENTS -->
## Acknowledgments

* [Best-README-Template](https://github.com/othneildrew/Best-README-Template)
* [urfave/cli](https://github.com/urfave/cli)
* [fsnotify](https://github.com/fsnotify/fsnotify)

<p align="right">(<a href="#readme-top">back to top</a>)</p>



<!-- MARKDOWN LINKS & IMAGES -->
<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
[contributors-shield]: https://img.shields.io/github/contributors/capcom6/sftp-sync.svg?style=for-the-badge
[contributors-url]: https://github.com/capcom6/sftp-sync/graphs/contributors
[forks-shield]: https://img.shields.io/github/forks/capcom6/sftp-sync.svg?style=for-the-badge
[forks-url]: https://github.com/capcom6/sftp-sync/network/members
[stars-shield]: https://img.shields.io/github/stars/capcom6/sftp-sync.svg?style=for-the-badge
[stars-url]: https://github.com/capcom6/sftp-sync/stargazers
[issues-shield]: https://img.shields.io/github/issues/capcom6/sftp-sync.svg?style=for-the-badge
[issues-url]: https://github.com/capcom6/sftp-sync/issues
[license-shield]: https://img.shields.io/github/license/capcom6/sftp-sync.svg?style=for-the-badge
[license-url]: https://github.com/capcom6/sftp-sync/blob/master/LICENSE
[product-screenshot]: images/screenshot.png
<!-- Shields.io badges. You can a comprehensive list with many more badges at: https://github.com/inttter/md-badges -->
[Go.dev]: https://img.shields.io/badge/Go-00ADD8?style=for-the-badge&logo=go&logoColor=white
[Go-url]: https://golang.org/
[urfave-cli-v3]: https://img.shields.io/badge/urfave%2Fcli-00ADD8?style=for-the-badge&logo=go&logoColor=white
[urfave-cli-v3-url]: https://github.com/urfave/cli
[fsnotify]: https://img.shields.io/badge/fsnotify-00ADD8?style=for-the-badge&logo=go&logoColor=white
[fsnotify-url]: https://github.com/fsnotify/fsnotify
[godotenv]: https://img.shields.io/badge/joho%2Fgodotenv-00ADD8?style=for-the-badge&logo=go&logoColor=white
[godotenv-url]: https://github.com/joho/godotenv
[go-report-card-shield]: https://goreportcard.com/badge/github.com/capcom6/sftp-sync
[go-report-card-url]: https://goreportcard.com/report/github.com/capcom6/sftp-sync
[go-version-shield]: https://img.shields.io/github/go-mod/go-version/capcom6/sftp-sync?style=for-the-badge
[go-version-url]: https://github.com/capcom6/sftp-sync/blob/master/go.mod
[code-size-shield]: https://img.shields.io/github/languages/code-size/capcom6/sftp-sync?style=for-the-badge
[code-size-url]: https://github.com/capcom6/sftp-sync
[last-commit-shield]: https://img.shields.io/github/last-commit/capcom6/sftp-sync?style=for-the-badge
[last-commit-url]: https://github.com/capcom6/sftp-sync/commits/master
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
module github.com/capcom6/sftp-sync

go 1.20
go 1.24.3

require (
github.com/capcom6/logutils v0.0.0-20230920155643-1a119fe7e5e7
github.com/fsnotify/fsnotify v1.6.0
github.com/go-core-fx/cli-logger v0.0.0-20260319073231-90ee4649c242
github.com/jlaffaye/ftp v0.2.0
github.com/joho/godotenv v1.5.1
github.com/samber/lo v1.52.0
github.com/urfave/cli/v3 v3.7.0
)

require (
Expand Down
14 changes: 11 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
github.com/capcom6/logutils v0.0.0-20230920155643-1a119fe7e5e7 h1:x1ods8rvbs4zNsOvEo/J8bHCMguAI70wBaWrJTn29/k=
github.com/capcom6/logutils v0.0.0-20230920155643-1a119fe7e5e7/go.mod h1:9dTHOvevK7Fwj4eBAbKDWSz+zarTV5pRatjmsDCL690=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/go-core-fx/cli-logger v0.0.0-20260319073231-90ee4649c242 h1:pZh2A/UZEceQZo4FMos2L1ZHO8QHxWpqNQ5ybqoWlnc=
github.com/go-core-fx/cli-logger v0.0.0-20260319073231-90ee4649c242/go.mod h1:6xzOTd0JZcXvC1ZwjU97rbbY4IjvicVZVIB3OjFm1f8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/jlaffaye/ftp v0.2.0 h1:lXNvW7cBu7R/68bknOX3MrRIIqZ61zELs1P2RAiA3lg=
github.com/jlaffaye/ftp v0.2.0/go.mod h1:is2Ds5qkhceAPy2xD6RLI6hmp/qysSoymZ+Z2uTnspI=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/samber/lo v1.52.0 h1:Rvi+3BFHES3A8meP33VPAxiBZX/Aws5RxrschYGjomw=
github.com/samber/lo v1.52.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0=
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/urfave/cli/v3 v3.7.0 h1:AGSnbUyjtLiM+WJUb4dzXKldl/gL+F8OwmRDtVr6g2U=
github.com/urfave/cli/v3 v3.7.0/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Binary file added images/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions internal/cli/codes/codes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package codes

const (
Success = iota
ParamsError
ClientError
OutputError
InternalError
)
Loading
Loading