Skip to content

Latest commit

 

History

History
153 lines (111 loc) · 6.16 KB

File metadata and controls

153 lines (111 loc) · 6.16 KB

🐻 Welcome to Our Neck of the Woods!

Remembear is a Rust library which can be built as a binary application. This guide will get you up to speed on how to contribute

🌟 Getting Started

  1. Install Rust, then install clippy and rustfmt for linting

     rustup component add clippy
     rustup component add rustfmt
    
  2. Install Sqlite3 for the database

     brew install sqlite # macOS
     apt-get install sqlite # Ubuntu/Mint/others
    
  3. Clone remembear

     git clone git@github.com:codehearts/remembear.git
     cd remembear
    
  4. Make sure you can lint and test the project. This will also install Git hooks

     cargo clippy --all-features
     cargo fmt --all -- --check
     cargo test
    
  5. Now all that's left is to run remembear locally!

     cargo run
    

Helpful Resources

If you're new to Rust, you may find these resources helpful:

🌿 Project Structure

This project uses a data provider model, with most modules being organized into these three files:

  • error.rs - Error types specific to the module
  • model.rs - Models, usually structs, for representing the module's data
  • provider.rs - Utilizes dependencies like the database to provide model data

The overall project structure is as follows:

  • src/ - Source code
    • lib.rs - Library entrypoint
    • main.rs - Binary entrypoint
    • command/ - Command-line interface module
    • database/ - Database integration
    • integration/ - Integrations with external services
    • reminder/ - Reminder datatypes
    • schedule/ - Stateless schedule datatype
      • provider/ - Provides schedule data from the database
        • model/ - Models for serialized schedule data
    • scheduler/ - Real-time reminder scheduler
    • user/ - User datatypes
  • tests/ - Integration tests
    • assets/ - Integration test assets
    • common/ - Common integration test functionality
    • common_database/ - Common functionality for integration tests that need a database
  • migrations/ - Database schemas for use with Diesel
  • diesel.toml - Configurations for Diesel
  • remembear.yml - Default configuration file for remembear

💻 Development

Remembear is written with the latest stable version of Rust and makes extensive use of these crates:

  • Diesel for persistent storage with sqlite3

Adding Service Integrations

Integration with external services can be added with support for local storage.

  1. Create a directory for your integration in src/integration/
  2. Implement the Integration trait
  • name should return a name for your integration
  • execute is where you can implement a CLI interface for your integration
  • notify is called when a scheduled reminder goes off. This is where you'll integrate with the external service and do something with the reminder.
  1. Initialize your integration in Integrations::new()
  2. Last but not least, enable your integration in remembear.yml!

You can look at src/integration/console/ for an example which writes to stdout, with support for setting colors for assignees in the database via a CLI interface.

Unit Tests

Code changes should be unit tested whenever possible. Place your tests in a tests module at the bottom of the file and annotate your test functions with #[test]. Tests will have access to private functions and should have a descriptive name beginning with it_ (my preference, nbd!)

Note that order doesn't matter in assertions, Rust uses "left/right" instead of "expected/actual"

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_adds_2_and_2_to_4() {
        assert_eq!(4, 2 + 2);
    }
}

Run unit tests with Cargo:

cargo test # test everything
cargo test it_adds # tests all functions matching "it_adds"

Integration Tests

Code changes that impact connectivity between modules or which can't be unit tested should have integration tests. These tests go in tests/ and should have a descriptive rustdoc at the top. If a test is resource intensive or slow, be sure to annotate it with #[ignored]

//! Integration tests for adding two numbers ¯\_(ツ)_/¯

#[test]
#[ignored]
fn it_adds_2_and_2_to_4() {
    assert_eq!(4, 2 + 2);
}

Integration tests are run the same as unit tests, but tests annotated with #[ignored] must be run like so:

cargo test -- --ignored # test everything
cargo test it_adds -- --ignored # tests ignored functions matching "it_adds"

📨 Submitting Changes

Once your code is polished and tests are passing, it's time to submit a pull request! When the CI build for your branch passes and a project owner reviews your code (which should happen within a few days), your change will be rebased into the master branch and your contribution complete! Nice work! 💖

☎️ Getting in Touch

For features or bugs, you can create a new issue in the tracker

For questions or concerns, feel free to reach out to @codehearts on Twitter or by email!