Skip to content

Commit

Permalink
chore: add taskfile and address clippy errors
Browse files Browse the repository at this point in the history
  • Loading branch information
rebelopsio committed Dec 1, 2024
1 parent 73d04d6 commit a92e330
Show file tree
Hide file tree
Showing 3 changed files with 224 additions and 7 deletions.
130 changes: 130 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
version: '3'

vars:
CARGO_INCREMENTAL: 0
RUSTFLAGS: "-D warnings"

tasks:
default:
cmds:
- task --list-all
silent: true

build:
desc: Build the project
cmds:
- cargo build
sources:
- src/**/*.rs
- Cargo.toml
generates:
- target/debug/tbd

test:
desc: Run all tests
cmds:
- cargo test --all-features

check:
desc: Run all checks (format, clippy, test)
cmds:
- task: fmt-check
- task: clippy
- task: test

clippy:
desc: Run clippy
cmds:
- cargo clippy --all-targets --all-features -- -D warnings

fmt:
desc: Format code
cmds:
- cargo fmt --all

fmt-check:
desc: Check code formatting
cmds:
- cargo fmt --all -- --check

clean:
desc: Clean build artifacts
cmds:
- cargo clean

doc:
desc: Generate documentation
cmds:
- cargo doc --no-deps
sources:
- src/**/*.rs
generates:
- target/doc

watch:
desc: Watch for changes and run tests
cmds:
- cargo watch -x test

release:
desc: Build release version
cmds:
- cargo build --release
sources:
- src/**/*.rs
- Cargo.toml
generates:
- target/release/tbd

install-tools:
desc: Install development tools
cmds:
- cargo install cargo-watch cargo-audit cargo-outdated
- rustup component add clippy rustfmt

audit:
desc: Run security audit
cmds:
- cargo audit

outdated:
desc: Check for outdated dependencies
cmds:
- cargo outdated

ci:
desc: Run CI pipeline locally
cmds:
- task: clean
- task: check
- task: build
- task: test
- task: audit

# Development workflow tasks
init:
desc: Initialize a new test project
dir: target
cmds:
- cargo run -- init --name {{.CLI_ARGS | default "test-project"}}

run:
desc: Run the CLI with arguments
cmds:
- cargo run -- {{.CLI_ARGS}}

dev:
desc: Start development environment
cmds:
- cargo watch -x 'run -- {{.CLI_ARGS}}'

# Container tasks
docker-build:
desc: Build Docker image
cmds:
- docker build -t tbdtools/tbd-iac:latest .

docker-run:
desc: Run Docker container
cmds:
- docker run --rm -it tbdtools/tbd-iac:latest {{.CLI_ARGS}}
7 changes: 3 additions & 4 deletions src/cli/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ mypy = "^1.0"
.context("Failed to create pyproject.toml")?;

// Create example stack
let example_stack = format!(
r#"from tbdtools import (
let example_stack = r#"from tbdtools import (
Stack,
aws,
Resource,
Expand Down Expand Up @@ -73,7 +72,7 @@ class MainStack(Stack):
# Initialize stack
stack = MainStack("main")
"#
);
.to_string();

fs::write(project_dir.join("stacks").join("main.py"), example_stack)
.context("Failed to create example stack")?;
Expand All @@ -91,7 +90,7 @@ Infrastructure as Code project using TBD Tools.
├── stacks/ # Stack definitions
├── modules/ # Reusable infrastructure modules
├── providers/ # Custom provider configurations
└── tests/ # Infrastructure tests
└── tests/ # Infrastructure tests
```
## Getting Started
Expand Down
94 changes: 91 additions & 3 deletions src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,109 @@ use serde::{Deserialize, Serialize};
use std::sync::Arc;
use tokio::sync::RwLock;

#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Resource {
id: String,
provider: String,
state: serde_json::Value,
}

#[derive(Default)]
pub struct StateManager {
resources: Arc<RwLock<Vec<Resource>>>,
}

impl StateManager {
pub fn new() -> Self {
Self {
resources: Arc::new(RwLock::new(Vec::new())),
Self::default()
}

/// Add a new resource to the state
pub async fn add_resource(&self, resource: Resource) -> Result<()> {
let mut resources = self.resources.write().await;
resources.push(resource);
Ok(())
}

/// Get a resource by ID
pub async fn get_resource(&self, id: &str) -> Option<Resource> {
let resources = self.resources.read().await;
resources.iter().find(|r| r.id == id).cloned()
}

/// List all resources
pub async fn list_resources(&self) -> Vec<Resource> {
let resources = self.resources.read().await;
resources.clone()
}

/// Remove a resource by ID
pub async fn remove_resource(&self, id: &str) -> Result<()> {
let mut resources = self.resources.write().await;
if let Some(index) = resources.iter().position(|r| r.id == id) {
resources.remove(index);
}
Ok(())
}
}

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

#[tokio::test]
async fn test_add_and_get_resource() {
let state = StateManager::new();
let resource = Resource {
id: "test-1".to_string(),
provider: "aws".to_string(),
state: json!({
"type": "aws_vpc",
"id": "vpc-123",
}),
};

state.add_resource(resource.clone()).await.unwrap();
let retrieved = state.get_resource("test-1").await.unwrap();
assert_eq!(retrieved.id, "test-1");
assert_eq!(retrieved.provider, "aws");
}

#[tokio::test]
async fn test_list_resources() {
let state = StateManager::new();
let resource1 = Resource {
id: "test-1".to_string(),
provider: "aws".to_string(),
state: json!({"type": "aws_vpc"}),
};
let resource2 = Resource {
id: "test-2".to_string(),
provider: "aws".to_string(),
state: json!({"type": "aws_subnet"}),
};

state.add_resource(resource1).await.unwrap();
state.add_resource(resource2).await.unwrap();

let resources = state.list_resources().await;
assert_eq!(resources.len(), 2);
}

#[tokio::test]
async fn test_remove_resource() {
let state = StateManager::new();
let resource = Resource {
id: "test-1".to_string(),
provider: "aws".to_string(),
state: json!({"type": "aws_vpc"}),
};

state.add_resource(resource).await.unwrap();
assert!(state.get_resource("test-1").await.is_some());

state.remove_resource("test-1").await.unwrap();
assert!(state.get_resource("test-1").await.is_none());
}
}

0 comments on commit a92e330

Please sign in to comment.