Skip to content

Commit

Permalink
feat: add dependabot config, ci workflow, and makefile (#9)
Browse files Browse the repository at this point in the history
### Summary

This PR introduces the following updates:

- **Minimal CI Workflow**: Adds a basic continuous integration setup to
ensure maintainability.
- **Dependabot Configuration**: Introduces a dependabot config to
automatically check and update package versions.
- **Makefile**: Includes a Makefile with common cargo commands for
convenience (because I'm lazy LOL).

![image](https://github.com/user-attachments/assets/c94132d0-1645-49d3-93a4-d442199aff01)

---------

Co-authored-by: Daniel Boll <[email protected]>
  • Loading branch information
gvieira18 and Daniel-Boll authored Aug 23, 2024
1 parent e1df297 commit a878681
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 87 deletions.
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: 2

updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "weekly"
48 changes: 48 additions & 0 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: CI

on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
setup:
name: Setup rust
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Setup rust
uses: actions-rust-lang/setup-rust-toolchain@1fbea72663f6d4c03efaab13560c8a24cfd2a7cc # v1.9.0
with:
toolchain: stable
target: x86_64-unknown-linux-gnu
components: clippy, rustfmt
- name: Build project
run: make build
lint:
name: Run lint and format
needs: [setup]
runs-on: ubuntu-24.04
env:
RUSTFLAGS: "-Dwarnings"
steps:
- name: Checkout code
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Setup rust
uses: actions-rust-lang/setup-rust-toolchain@1fbea72663f6d4c03efaab13560c8a24cfd2a7cc # v1.9.0
with:
toolchain: stable
target: x86_64-unknown-linux-gnu
components: clippy, rustfmt
- name: Run Rustfmt
uses: actions-rust-lang/rustfmt@2d1d4e9f72379428552fa1def0b898733fb8472d # v1.1.0
- name: Run Clippy
uses: clechasseur/rs-clippy-check@a2a93bdcf05de7909aabd62eca762179ad3dbe50 # v3.0.5
with:
args: --all-features
48 changes: 48 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
CARGO := $(shell command -v cargo 2> /dev/null)

ifndef CARGO
$(error "Cannot find cargo. Please install and try again!")
endif

all: help

.PHONY: clean
clean: ## Cleans up the project by removing the target directory.
@$(CARGO) clean

.PHONY: lint
lint: ## Runs Clippy to lint the codebase.
@$(CARGO) clippy --no-deps

.PHONY: format
format: ## Formats the codebase using rustfmt.
@$(CARGO) fmt

.PHONY: check
check: format lint ## Formats the codebase and then lints it.

.PHONY: build
build: ## Compiles the project.
@$(CARGO) build

.PHONY: debug
debug: ## Compiles and runs the project.
@$(CARGO) run

.PHONY: run
run: ## Compiles and runs the project.
@$(CARGO) run --release

.PHONY: test
test: ## Runs the test suite.
@$(CARGO) test

.PHONY: release
release: clean ## Cleans up the project and compiles it for release profile.
@$(CARGO) build --release --locked

.PHONY: help
help: ## Shows the help message with available commands.
@echo "Available commands:"
@grep -E '^[^[:space:]]+:[^:]*?## .*$$' $(MAKEFILE_LIST) | \
awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-30s\033[0m %s\n", $$1, $$2}'
132 changes: 66 additions & 66 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,100 +6,100 @@ use std::io::Write;
use std::path::Path;

static DEFAULT_SETTINGS_STR: &str =
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/default_config.toml"));
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/default_config.toml"));

static SETTINGS_PATH: &str = concat!(env!("HOME"), "/.config/scyllash");

#[derive(Parser)]
#[command(author, version, about, long_about = None)]
pub struct Arguments {
#[command(subcommand)]
pub command: Option<Command>,
#[command(subcommand)]
pub command: Option<Command>,
}

#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Subcommand)]
pub enum Command {
/// Starts ScyllaSH with a provided connection
Run {
#[command(flatten)]
connection: ConnectionConfig,
},
/// Starts ScyllaSH with a provided connection
Run {
#[command(flatten)]
connection: ConnectionConfig,
},
}

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Args, Deserialize, Serialize)]
pub struct ConnectionConfig {
/// Scylla Host
#[arg(long, default_value_t = get_default_string_value("hostname"))]
pub hostname: String,
/// Scylla User
#[arg(short, long, default_value_t = get_default_string_value("username"))]
pub username: String,
/// Scylla Host
#[arg(long, default_value_t = get_default_string_value("hostname"))]
pub hostname: String,
/// Scylla User
#[arg(short, long, default_value_t = get_default_string_value("username"))]
pub username: String,

/// Scylla Password
#[arg(short, long, default_value_t = get_default_string_value("password"))]
pub password: String,
/// Scylla Password
#[arg(short, long, default_value_t = get_default_string_value("password"))]
pub password: String,

/// Scylla Timeout
#[arg(short, long, default_value_t = 5)]
pub timeout: u64,
/// Scylla Timeout
#[arg(short, long, default_value_t = 5)]
pub timeout: u64,
}

fn get_default_string_value(key: &str) -> String {
let config = ConfigToml::default();
let connection = config.connection.clone();
match key {
"hostname" => {
if !config.connection.hostname.is_empty() {
connection.hostname
} else {
String::from("localhost:9042")
}
}
"username" => {
if !config.connection.username.is_empty() {
connection.username
} else {
String::from("scylla")
}
}
"password" => {
if !config.connection.password.is_empty() {
connection.password
} else {
String::from("")
}
}
_ => String::from(""),
let config = ConfigToml::default();
let connection = config.connection.clone();
match key {
"hostname" => {
if !config.connection.hostname.is_empty() {
connection.hostname
} else {
String::from("localhost:9042")
}
}
"username" => {
if !config.connection.username.is_empty() {
connection.username
} else {
String::from("scylla")
}
}
"password" => {
if !config.connection.password.is_empty() {
connection.password
} else {
String::from("")
}
}
_ => String::from(""),
}
}

#[derive(Debug, Deserialize, Serialize)]
pub struct ConfigToml {
pub connection: ConnectionConfig,
pub connection: ConnectionConfig,
}

impl Default for ConfigToml {
fn default() -> Self {
let settings_path = Path::new(SETTINGS_PATH);
let file_path = settings_path.join("config.toml");

if !settings_path.exists() {
println!("No settings directory identified");
fs::create_dir_all(settings_path).expect("Failed to create settings directory");
}
fn default() -> Self {
let settings_path = Path::new(SETTINGS_PATH);
let file_path = settings_path.join("config.toml");

if !file_path.exists() {
println!("No config file identified");
let mut file = File::create(&file_path).expect("Failed to create settings file");
file
.write_all(DEFAULT_SETTINGS_STR.as_bytes())
.expect("Failed to write default settings");
}

let toml_str = fs::read_to_string(&file_path).expect("Failed to read settings file");
let cargo_toml: ConfigToml =
toml::from_str(&toml_str).expect("Failed to deserialize Cargo.toml");
if !settings_path.exists() {
println!("No settings directory identified");
fs::create_dir_all(settings_path).expect("Failed to create settings directory");
}

cargo_toml
if !file_path.exists() {
println!("No config file identified");
let mut file = File::create(&file_path).expect("Failed to create settings file");
file
.write_all(DEFAULT_SETTINGS_STR.as_bytes())
.expect("Failed to write default settings");
}

let toml_str = fs::read_to_string(&file_path).expect("Failed to read settings file");
let cargo_toml: ConfigToml =
toml::from_str(&toml_str).expect("Failed to deserialize Cargo.toml");

cargo_toml
}
}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
pub mod app;
pub mod tui;
pub mod args;
pub mod tui;
36 changes: 16 additions & 20 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,23 @@ use scyllash::args::Command;
use scyllash::{app::App, args::Arguments, tui};

fn main() -> color_eyre::Result<()> {
let args = Arguments::parse();

match &args.command {
Some(Command::Run { .. }) => {
run_interface()
}
None => {
run_interface()
}
}
let args = Arguments::parse();

match &args.command {
Some(Command::Run { .. }) => run_interface(),
None => run_interface(),
}
}

fn run_interface() -> color_eyre::Result<()> {
color_eyre::install()?;
let mut terminal = tui::init()?;
let app_result = App::default().run(&mut terminal);
if let Err(err) = tui::restore() {
eprintln!(
"failed to restore terminal. Run `reset` or restart your terminal to recover: {}",
err
);
}
app_result
color_eyre::install()?;
let mut terminal = tui::init()?;
let app_result = App::default().run(&mut terminal);
if let Err(err) = tui::restore() {
eprintln!(
"failed to restore terminal. Run `reset` or restart your terminal to recover: {}",
err
);
}
app_result
}

0 comments on commit a878681

Please sign in to comment.