Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

77 make the application modular #78

Merged
merged 2 commits into from
Sep 30, 2024
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
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
Loading