Skip to content

Commit

Permalink
Merge pull request #78 from opeolluwa/77-make-the-application-modular
Browse files Browse the repository at this point in the history
77 make the application modular
  • Loading branch information
opeolluwa authored Sep 30, 2024
2 parents d4eaf71 + 90d2f86 commit 91d1a6b
Show file tree
Hide file tree
Showing 169 changed files with 340 additions and 670 deletions.
Binary file modified .DS_Store
Binary file not shown.
5 changes: 0 additions & 5 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
{
"workbench.colorCustomizations": {
"activityBar.background": "#462511",
"titleBar.activeBackground": "#613417",
"titleBar.activeForeground": "#FDFAF8"
},
"rust-analyzer.linkedProjects": [
"./Cargo.toml",
"./utils-server/Cargo.toml",
Expand Down
35 changes: 5 additions & 30 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,14 @@ version = "1.1.1"
license = "Apache-2.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html





[workspace]
members = [".", "entity", "migration",]
exclude = ["sandbox"]



members = ["cli", "migration", "entity", "config", "style"]

[dependencies]
assert_cmd = "2.0.16"
bcrypt = "0.15.1"
chrono = "0.4.38"
clap = {version = "4.5.16", features = ["derive"] }
console = "0.15.8"
dialoguer = {version = "0.10.4", features = ["fuzzy-select", "completion"] }
dirs = "5.0.1"
include_dir = "0.7.4"
indicatif = "0.17.8"
lazy_static = "1.5.0"
serde = { version = "1.0.209", features = ["derive"] }
serde_json = "1.0.127"
tokio = {version = "1.39.3", features = ["macros", "rt-multi-thread"] }
uuid = {version = "1.10.0", features = ["v4", "fast-rng", "macro-diagnostics"] }
sea-orm = { version = "0.12", features = [ "sqlx-sqlite", "runtime-tokio-native-tls", "macros" , "with-uuid", "with-time"] }
anyhow = "1.0.86"
utils-cli-entity = { path = "entity", version = "1.0.5"}
utils-cli-migration = { path = "migration", version = "1.0.0"}
online = "4.0.2"
configparser = "3.1.0"
regex = "1.10.6"
confy = "0.6.1"

tokio = { version = "1.39.3", features = ["full"] }
utils_entity = { path = "entity", version = "1.0.5" }
utils_migration = { path = "migration", version = "1.0.0" }
utils_cli = { path = "cli" }

83 changes: 71 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
# Utility Suite
# Utils CLI

An efficient tool to transform the developer experience with a comprehensive suite of Utilities designed to streamline workflows, boost productivity, and elevate the quality of projects.
Utils CLI is a powerful command-line interface (CLI) tool designed to
supercharge your productivity by providing essential utilities for software
projects. This tool supports storing key-value pairs, generating `.gitignore`
files, managing README files, and more. Utils CLI is lightweight, easy to use,
and integrates seamlessly with your projects.

## Installation

## Installation
As of this time, Utils is still experimental and can only be built ffrom source
As of this time, Utils CLI only be built from source

```sh
git clone https://github.com/opeolluwa/utils.git
cd utils
cargo build --release
cargo install --path .
```
```sh
git clone https://github.com/opeolluwa/utils.git
cd utils
cargo build --release
cargo install --path .
```

### Executing program

Expand All @@ -21,8 +25,63 @@ To run the application locally
cargo run -- --help
```

## Usage

```sh
utils <COMMAND>
```

### Commands

- **store**: Store and retrieve data as key-value pairs.

```sh
utils store --key=<KEY> --value=<Value> --secure
```

- **ignore**: Generate a .gitignore file for your project tooling.

```sh
utils ignore <tool-name>
```

- **readme**: Add a README.md to your project.

```sh
utils readme <project-name>
```

- **upgrade**: Upgrade the CLI tool to the latest version.

```sh
utils upgrade
```

- **sync**: Synchronize the data with a remote database.

```sh
utils sync --database-url=<REMOTE_DATABASE_CONNECTION>
```

- **config**: Configure CLI behavior using a config file at
`$HOME/.utils/utils.conf`

```sh
utils config | vi
```

- **help**: Display the help message for available commands.

```sh
utils help
```

### Options

The basic usage of Utils CLI involves passing a command followed by optional
arguments.

## License

This project is licensed under the Apache License
Version 2.0 License - see the [LICENSE](./LICENSE) file for details
This project is licensed under the Apache License Version 2.0 License - see the
[LICENSE](./LICENSE) file for details
28 changes: 28 additions & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "utils_cli"
version = "0.1.0"
edition = "2021"

[dependencies]
anyhow = "1.0.86"
bcrypt = "0.15.1"
chrono = "0.4.38"
clap = { version = "4.5.16", features = ["derive"] }
console = "0.15.8"
dialoguer = { version = "0.10.4", features = ["fuzzy-select", "completion"] }
dirs = "5.0.1"
include_dir = "0.7.4"
lazy_static = "1.5.0"
online = "4.0.2"
sea-orm = { version = "1.0.1", features = [
"sqlx-sqlite",
"runtime-tokio-rustls",
"macros",
"with-uuid",
"with-time",
"debug-print",
] }
serde = { version = "1.0.209", features = ["derive"] }
utils_entity = { path = "../entity" }
utils_style = { path = "../style" }
utils_migration = { path = "../migration" }
2 changes: 1 addition & 1 deletion src/commands/cli.rs → cli/src/commands/cli.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::style::LogMessage;
use utils_style::style::LogMessage;
use ::std::io::BufRead;
use anyhow::Result;
use online::check;
Expand Down
12 changes: 4 additions & 8 deletions src/commands/gitignore.rs → cli/src/commands/gitignore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,15 @@ use std::{
io::Write,
path::Path,
};

use console::Style;

use crate::pkg::{WriteContent, FileExists};
use serde::Serialize;

use crate::{
style::LogMessage,
utils::{FileExists, WriteContent},
SOURCE_DIR,
};
use utils_style::style::LogMessage;
use crate::constants::SOURCE_DIR;
use console::Term;
use dialoguer::{theme::ColorfulTheme, FuzzySelect};


#[derive(clap::Args, Debug, Serialize)]
pub struct GitIgnoreCommands {
/// the path to generate the .gitignore file
Expand Down
3 changes: 0 additions & 3 deletions src/commands/mod.rs → cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
pub mod auth;
pub mod cli;
pub mod download;
pub mod gitignore;
pub mod readme;
pub mod sms;
pub mod store;
6 changes: 2 additions & 4 deletions src/commands/readme.rs → cli/src/commands/readme.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
use crate::style::LogMessage;
use dialoguer::theme::ColorfulTheme;
use dialoguer::Confirm;
use dialoguer::Input;
use dialoguer::{theme::ColorfulTheme, Confirm, Input};
use serde::Serialize;
use std::fs::{self, File};
use std::io::Write;
use std::path::Path;
use utils_style::style::LogMessage;
/// the readme utils is used to for generating project readme
/// # Example
/// the basic examples are listed thus:
Expand Down
40 changes: 20 additions & 20 deletions src/commands/store.rs → cli/src/commands/store.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
use crate::security_questions::{self, security_questions};
use dialoguer::{theme::ColorfulTheme, Input, Select};
use entity::password;
use utils_entity::password;
use password::Entity as Password;
use std::time::Duration;
use utils_cli_entity as entity;

use crate::{style::LogMessage, DB_URL};
// use crate::{, DB_URL};
use utils_style::style::LogMessage;
use anyhow::{Ok, Result};
use bcrypt::{hash, verify, DEFAULT_COST};
use chrono::Local;
use clap::{Args, Subcommand};
use dialoguer::{Confirm, Password as PassPhrase};
use entity::store::{self, Entity as Store};
use utils_entity::store::{self, Entity as Store};
use sea_orm::{
ActiveModelTrait, ColumnTrait, ConnectionTrait, DatabaseBackend, DbBackend, ExecResult,
Statement,
Expand Down Expand Up @@ -66,7 +66,7 @@ impl StoreCommands {
};
let date_added = Local::now().to_rfc2822();
let last_updated = Local::now().to_rfc2822();
let record = entity::store::ActiveModel {
let record = store::ActiveModel {
key: Set(key.to_string()),
value: Set(value.to_string()),
last_updated: Set(date_added),
Expand All @@ -85,7 +85,7 @@ impl StoreCommands {
}
/// find all
async fn list() -> Result<()> {
let data: Vec<entity::store::Model> =
let data: Vec<store::Model> =
Store::find().all(&Self::db_connection().await?).await?;

if data.is_empty() {
Expand All @@ -110,10 +110,10 @@ impl StoreCommands {

/// update recoird n the store
async fn update(key: &str, value: &str) -> Result<()> {
let mut record: entity::store::ActiveModel = Self::find_one(key).await?.into();
let mut record: store::ActiveModel = Self::find_one(key).await?.into();
record.value = Set(value.to_owned());

let _: entity::store::Model = record.update(&Self::db_connection().await?).await?;
let _: store::Model = record.update(&Self::db_connection().await?).await?;

let message = format!("{key} successfully updated");
LogMessage::success(&message);
Expand All @@ -124,7 +124,7 @@ impl StoreCommands {
/// delte all record in the database
async fn clear() -> Result<()> {
// fetch the password
let saved_password = entity::password::Entity::find()
let saved_password = password::Entity::find()
.from_raw_sql(Statement::from_sql_and_values(
DbBackend::Sqlite,
r#"SELECT * FROM password WHERE id = $1"#,
Expand Down Expand Up @@ -218,10 +218,10 @@ impl StoreCommands {
Ok(())
}

/// the databse connections
/// the database connections
async fn db_connection() -> Result<DatabaseConnection> {
// the databse connection options/configuration
let mut opt = ConnectOptions::new(DB_URL.as_str());
let mut opt = ConnectOptions::new(crate::constants::DB_URL.as_str());
opt.max_connections(100)
.min_connections(5)
.connect_timeout(Duration::from_secs(8))
Expand All @@ -236,12 +236,12 @@ impl StoreCommands {
}

/// find a record by key
async fn find_one(key: &str) -> Result<entity::store::Model> {
let record = entity::store::Entity::find()
async fn find_one(key: &str) -> Result<store::Model> {
let record = store::Entity::find()
.filter(
Condition::all().add(entity::store::Column::Key.like(format!("%{}%", key.trim()))),
Condition::all().add(store::Column::Key.like(format!("%{}%", key.trim()))),
)
.order_by_asc(entity::store::Column::DateAdded)
.order_by_asc(store::Column::DateAdded)
.all(&Self::db_connection().await?)
.await?;

Expand All @@ -260,12 +260,12 @@ impl StoreCommands {
// udate authorization
async fn update_security_question() -> Result<()> {
// fetch the auth creds
let authorization_creds: Option<entity::password::Model> = Password::find_by_id(1)
let authorization_creds: Option<password::Model> = Password::find_by_id(1)
.one(&Self::db_connection().await?)
.await?;

//coerce into the active model type
let mut authorization_creds: entity::password::ActiveModel =
let mut authorization_creds: password::ActiveModel =
authorization_creds.unwrap().into();

// get the updated security question
Expand All @@ -290,7 +290,7 @@ impl StoreCommands {
authorization_creds.answer_hash = Set(hashed_answer);

// execute the update
let _: entity::password::Model = authorization_creds
let _: password::Model = authorization_creds
.update(&Self::db_connection().await?)
.await?;

Expand All @@ -317,7 +317,7 @@ impl StoreCommands {

let hashed_answer = hash(answer.trim().to_lowercase(), DEFAULT_COST)?;

let record = entity::password::ActiveModel {
let record = password::ActiveModel {
id: Set(1),
sequrity_question: Set(selected_question.to_owned()),
answer_hash: Set(hashed_answer),
Expand All @@ -331,7 +331,7 @@ impl StoreCommands {
}

async fn _require_authorization(raw_password: &str) -> Result<bool> {
let saved_password = entity::password::Entity::find()
let saved_password = password::Entity::find()
.from_raw_sql(Statement::from_sql_and_values(
DbBackend::Sqlite,
r#"SELECT * FROM password WHERE id = $1"#,
Expand Down
Loading

0 comments on commit 91d1a6b

Please sign in to comment.