Start writing CONTRIBUTING guide
This commit is contained in:
parent
2287fed422
commit
545e283f00
181
CONTRIBUTING.md
181
CONTRIBUTING.md
|
@ -1,7 +1,186 @@
|
|||
# Contributing
|
||||
|
||||
Before contributing to this repository, please first discuss the change you wish to make via issue of this repository before making a change.
|
||||
Please note we have a [code of conduct](./CODE_OF_CONDUCT.md), please follow it in all your interactions with the project.
|
||||
|
||||
- [Contributing](#contributing)
|
||||
- [Preferred contributions](#preferred-contributions)
|
||||
- [Pull Request Process](#pull-request-process)
|
||||
- [Developer contributions guide](#developer-contributions-guide)
|
||||
- [How TermSCP works](#how-termscp-works)
|
||||
- [Implementing File Transfers](#implementing-file-transfers)
|
||||
|
||||
---
|
||||
|
||||
TODO
|
||||
## Preferred contributions
|
||||
|
||||
At the moment, these kind of contributions are more appreciated and should be preferred:
|
||||
|
||||
- Fix for issues described in [Known Issues](./README.md#known-issues) or [issues reported by the community](https://github.com/ChristianVisintin/TermSCP/issues)
|
||||
- New file transfers: for further details see [Implementing File Transfer](#implementing-file-transfers)
|
||||
- Improvements to translators: any improvement to transliteration is accepted if makes sense, consider that my implementations could be not 100% correct (and probably they're not), indeed consider that I don't speak all these languages (tbh I only can speak Russian as a language with a different alphabet from latin - and I can't even speak it very well).
|
||||
- Code optimizations: any optimization to the code is welcome
|
||||
|
||||
For any other kind of contribution, especially for new features, please submit an issue first.
|
||||
|
||||
## Pull Request Process
|
||||
|
||||
Let's make it simple and clear:
|
||||
|
||||
1. Open an issue with an **appropriate label** (e.g. bug, new-feature, refactoring...).
|
||||
2. Write a **properly documentation** compliant with **rustdoc** standard.
|
||||
3. Write tests for your code. This doesn't apply necessarily for implementation regarding the user-interface module (`ui`).
|
||||
4. Report changes to the issue you opened, writing a report of what you changed and what you have introduced.
|
||||
5. Update the `CHANGELOG.md` file with details of changes to the application.
|
||||
6. Request maintainers to merge your changes.
|
||||
|
||||
## Developer contributions guide
|
||||
|
||||
Welcome to the contributions guide for TermSCP. This chapter DOESN'T contain the documentation for TermSCP, which can instead be found on Rust Docs at <https://docs.rs/termscp>
|
||||
This chapter describes how TermSCP works and the guide lines to implement stuff such as file transfers and add features to the user interface.
|
||||
|
||||
### How TermSCP works
|
||||
|
||||
TODO:
|
||||
|
||||
### Implementing File Transfers
|
||||
|
||||
This chapter describes how to implement a file transfer in TermSCP. A file transfer is a module which implements the `FileTransfer` trait. The file transfer provides different modules to interact with a remote server, which in addition to the most obvious methods, used to download and upload files, provides also methods to list files, delete files, create directories etc.
|
||||
|
||||
In the following steps I will describe how to implement a new file transfer, in this case I will be implementing the SCP file transfer (which I'm actually implementing the moment I'm writing this lines).
|
||||
|
||||
1. Add the Scp protocol to the `FileTransferProtocol` enum.
|
||||
|
||||
Move to `src/filetransfer/mod.rs` and add `Scp` to the `FileTransferProtocol` enum
|
||||
|
||||
```rs
|
||||
/// ## FileTransferProtocol
|
||||
///
|
||||
/// This enum defines the different transfer protocol available in TermSCP
|
||||
#[derive(std::cmp::PartialEq, std::fmt::Debug, std::clone::Clone)]
|
||||
pub enum FileTransferProtocol {
|
||||
Sftp,
|
||||
Ftp(bool), // Bool is for secure (true => ftps)
|
||||
Scp, // <-- here
|
||||
}
|
||||
```
|
||||
|
||||
In this case Scp is a "plain" enum type. If you need particular options, follow the implementation of `Ftp` which uses a boolean flag for indicating if using FTPS or FTP.
|
||||
|
||||
2. Implement the FileTransfer struct
|
||||
|
||||
Create a file at `src/filetransfer/mytransfer.rs`
|
||||
|
||||
Declare your file transfer struct
|
||||
|
||||
```rs
|
||||
/// ## ScpFileTransfer
|
||||
///
|
||||
/// SFTP file transfer structure
|
||||
pub struct ScpFileTransfer {
|
||||
session: Option<Session>,
|
||||
sftp: Option<Sftp>,
|
||||
wrkdir: PathBuf,
|
||||
}
|
||||
```
|
||||
|
||||
3. Implement the `FileTransfer` trait for it
|
||||
|
||||
You'll have to implement the following methods for your file transfer:
|
||||
|
||||
- connect: connect to remote server
|
||||
- disconnect: disconnect from remote server
|
||||
- is_connected: returns whether the file transfer is connected to remote
|
||||
- pwd: get working directory
|
||||
- change_dir: change working directory.
|
||||
- list_dir: get files and directories at a certain path
|
||||
- mkdir: make a new directory. Return an error in case the directory already exists
|
||||
- remove: remove a file or a directory. In case the protocol doesn't support recursive removing of directories you MUST implement this through a recursive algorithm
|
||||
- rename: rename a file or a directory
|
||||
- stat: returns detail for a certain path
|
||||
- send_file: opens a stream to a remote path for write purposes (write a remote file)
|
||||
- recv_file: opens a stream to a remote path for read purposes (write a local file)
|
||||
- on_sent: finalize a stream when writing a remote file. In case it's not necessary just return `Ok(())`
|
||||
- on_recv: fianlize a stream when reading a remote file. In case it's not necessary just return `Ok(())`
|
||||
|
||||
In case the protocol you're working on doesn't support any of this features, just return `Err(FileTransferError::new(FileTransferErrorType::UnsupportedFeature))`
|
||||
|
||||
4. Add your transfer to filetransfers:
|
||||
|
||||
Move to `src/filetransfer/mod.rs` and declare your file transfer:
|
||||
|
||||
```rs
|
||||
// Transfers
|
||||
pub mod ftp_transfer;
|
||||
pub mod scp_transfer; // <-- here
|
||||
pub mod sftp_transfer;
|
||||
```
|
||||
|
||||
5. Handle FileTransfer in `FileTransferActivity::new`
|
||||
|
||||
Move to `src/ui/activities/filetransfer_activity/mod.rs` and add the new protocol to the client match
|
||||
|
||||
```rs
|
||||
client: match protocol {
|
||||
FileTransferProtocol::Sftp => Box::new(SftpFileTransfer::new()),
|
||||
FileTransferProtocol::Ftp(ftps) => Box::new(FtpFileTransfer::new(ftps)),
|
||||
FileTransferProtocol::Scp => Box::new(ScpFileTransfer::new()), // <--- here
|
||||
},
|
||||
```
|
||||
|
||||
6. Handle right/left input events in `AuthActivity`:
|
||||
|
||||
Move to `src/ui/activities/auth_activity.rs` and handle the new protocol in `handle_input_event_mode_text` for `KeyCode::Left` and `KeyCode::Right`.
|
||||
Consider that the order they "rotate" must match the way they will be drawned in the interface.
|
||||
For newer protocols, please put them always at the end of the list. In this list I won't, because Scp is more important than Ftp imo.
|
||||
|
||||
```rs
|
||||
KeyCode::Left => {
|
||||
// If current field is Protocol handle event... (move element left)
|
||||
if self.selected_field == InputField::Protocol {
|
||||
self.protocol = match self.protocol {
|
||||
FileTransferProtocol::Sftp => FileTransferProtocol::Ftp(true), // End of list (wrap)
|
||||
FileTransferProtocol::Scp => FileTransferProtocol::Sftp,
|
||||
FileTransferProtocol::Ftp(ftps) => match ftps {
|
||||
false => FileTransferProtocol::Scp,
|
||||
true => FileTransferProtocol::Ftp(false),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
KeyCode::Right => {
|
||||
// If current field is Protocol handle event... ( move element right )
|
||||
if self.selected_field == InputField::Protocol {
|
||||
self.protocol = match self.protocol {
|
||||
FileTransferProtocol::Sftp => FileTransferProtocol::Scp,
|
||||
FileTransferProtocol::Scp => FileTransferProtocol::Ftp(false),
|
||||
FileTransferProtocol::Ftp(ftps) => match ftps {
|
||||
false => FileTransferProtocol::Ftp(true),
|
||||
true => FileTransferProtocol::Sftp, // End of list (wrap)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
7. Add your new file transfer to the protocol input field
|
||||
|
||||
Move to `AuthActivity::draw_protocol_select` method.
|
||||
Here add your new protocol to the `Spans` vector and to the match case, which chooses which element to highlight.
|
||||
|
||||
```rs
|
||||
let protocols: Vec<Spans> = vec![Spans::from("SFTP"), Spans::from("SCP"), Spans::from("FTP"), Spans::from("FTPS")];
|
||||
let index: usize = match self.protocol {
|
||||
FileTransferProtocol::Sftp => 0,
|
||||
FileTransferProtocol::Scp => 1,
|
||||
FileTransferProtocol::Ftp(ftps) => match ftps {
|
||||
false => 2,
|
||||
true => 3,
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Thank you for any contribution!
|
||||
Christian Visintin
|
||||
|
|
Loading…
Reference in a new issue