Skip to content

Commit

Permalink
Merge pull request #609 from loco-rs/task-args
Browse files Browse the repository at this point in the history
move task args from BTreeMap to struct
  • Loading branch information
kaplanelad authored Jun 10, 2024
2 parents 8e53a9e + 1f5a7dd commit 58ed204
Show file tree
Hide file tree
Showing 17 changed files with 138 additions and 79 deletions.
40 changes: 30 additions & 10 deletions docs-site/content/docs/the-app/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,44 @@ Each task is designed to parse command-line arguments into flags, utilizing the

Generate the task:

<!-- <snip id="generate-task-help-command" inject_from="yaml" action="exec" template="sh"> -->
```sh
$ cargo loco generate task [OPTIONS] <TASK_NAME>
Generate a Task based on the given name

Usage: blo-cli generate task [OPTIONS] <NAME>

Arguments:
<NAME> Name of the thing to generate

Options:
-e, --environment <ENVIRONMENT> Specify the environment [default: development]
-h, --help Print help
-V, --version Print version

```
<!-- </snip> -->

## Running a Task

Execute the task you created in the previous step using the following command:

<!-- <snip id="run-task-command" inject_from="yaml" template="sh"> -->
```sh
$ cargo loco task <TASK_NAME>
cargo loco task <TASK_NAME>
```
<!-- </snip> -->


## Listing All Tasks

To view a list of all tasks that have been executed, use the following command:

<!-- <snip id="list-tasks-command" inject_from="yaml" template="sh"> -->
```sh
$ cargo loco task
cargo loco task
```
<!-- </snip> -->


## Creating a Task manually

Expand All @@ -58,24 +77,25 @@ If you prefer a manual approach to creating tasks in `Loco`, you can follow thes

Start by creating a new file under the path `src/tasks`. For example, let's create a file named `example.rs`:

<!-- <snip id="task-code-example" inject_from="code" template="rust"> -->
```rust
// src/tasks/example.rs
use loco_rs::prelude::*;

pub struct ExampleTask;
pub struct Foo;
#[async_trait]
impl Task for ExampleTask {
impl Task for Foo {
fn task(&self) -> TaskInfo {
TaskInfo {
name: "example".to_string(),
detail: "Example task executed successfully".to_string(),
name: "foo".to_string(),
detail: "run foo task".to_string(),
}
}
async fn run(&self, app_context: &AppContext, vars: &BTreeMap<String, String>) -> Result<()> {
println!("Example task executed successfully");
async fn run(&self, _app_context: &AppContext, _vars: &task::Vars) -> Result<()> {
Ok(())
}
}
```
<!-- </snip> -->

#### 2. Load the File in mod.rs

Expand Down
5 changes: 3 additions & 2 deletions examples/demo/examples/task.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use std::{collections::BTreeMap, env};
use std::env;

use blo::app::App;
use loco_rs::{
boot::{create_context, run_task},
environment::{resolve_from_env, Environment},
task,
};

#[tokio::main]
Expand All @@ -13,7 +14,7 @@ async fn main() -> eyre::Result<()> {
let args = env::args().collect::<Vec<_>>();
let cmd = args.get(1);
let app_context = create_context::<App>(&environment).await?;
run_task::<App>(&app_context, cmd, &BTreeMap::new()).await?;
run_task::<App>(&app_context, cmd, &task::Vars::default()).await?;

Ok(())
}
8 changes: 4 additions & 4 deletions examples/demo/src/tasks/foo.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::collections::BTreeMap;

// <snip id="task-code-example" />
use loco_rs::prelude::*;

pub struct Foo;
Expand All @@ -8,10 +7,11 @@ impl Task for Foo {
fn task(&self) -> TaskInfo {
TaskInfo {
name: "foo".to_string(),
detail: "test misaligned cli prints".to_string(),
detail: "run foo task".to_string(),
}
}
async fn run(&self, _app_context: &AppContext, _vars: &BTreeMap<String, String>) -> Result<()> {
async fn run(&self, _app_context: &AppContext, _vars: &task::Vars) -> Result<()> {
Ok(())
}
}
// </snip>
8 changes: 4 additions & 4 deletions examples/demo/src/tasks/seed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
//! command with the `refresh:true` argument: ```sh
//! cargo run task seed_data refresh:true
//! ```
use std::collections::BTreeMap;

use loco_rs::{db, prelude::*};
use migration::Migrator;

Expand All @@ -29,8 +27,10 @@ impl Task for SeedData {
detail: "Task for seeding data".to_string(),
}
}
async fn run(&self, app_context: &AppContext, vars: &BTreeMap<String, String>) -> Result<()> {
let refresh = vars.get("refresh").is_some_and(|refresh| refresh == "true");
async fn run(&self, app_context: &AppContext, vars: &task::Vars) -> Result<()> {
let refresh = vars
.cli_arg("refresh")
.is_ok_and(|refresh| refresh == "true");

if refresh {
db::reset::<Migrator>(&app_context.db).await?;
Expand Down
4 changes: 1 addition & 3 deletions examples/demo/src/tasks/user_report.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::collections::BTreeMap;

use loco_rs::prelude::*;

use crate::models::_entities::users;
Expand All @@ -13,7 +11,7 @@ impl Task for UserReport {
detail: "output a user report".to_string(),
}
}
async fn run(&self, app_context: &AppContext, vars: &BTreeMap<String, String>) -> Result<()> {
async fn run(&self, app_context: &AppContext, vars: &task::Vars) -> Result<()> {
let users = users::Entity::find().all(&app_context.db).await?;
println!("args: {vars:?}");
println!("!!! user_report: listing users !!!");
Expand Down
2 changes: 1 addition & 1 deletion examples/demo/tests/cmd/cli.trycmd
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Options:

```console
$ LOCO_ENV=test blo-cli task
foo [test misaligned cli prints]
foo [run foo task]
seed_data [Task for seeding data]
user_report [output a user report]

Expand Down
24 changes: 10 additions & 14 deletions examples/demo/tests/tasks/foo.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
use blo::app::App;
use loco_rs::testing;

use loco_rs::boot::run_task;
use migration::Migrator;
use loco_rs::{boot::run_task, task, testing};
use serial_test::serial;
use std::collections::BTreeMap;

#[tokio::test]
#[serial]
async fn test_can_seed_data() {
let boot = testing::boot_test::<App, Migrator>().await.unwrap();

let vars = BTreeMap::new();
async fn test_can_run_foo_task() {
let boot = testing::boot_test::<App>().await.unwrap();

assert!(
run_task::<App>(&boot.app_context, Some(&"foo".to_string()), &vars)
.await
.is_ok()
);
assert!(run_task::<App>(
&boot.app_context,
Some(&"foo".to_string()),
&task::Vars::default()
)
.await
.is_ok());
}
1 change: 1 addition & 0 deletions examples/demo/tests/tasks/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
mod foo;
mod seed;
18 changes: 8 additions & 10 deletions examples/demo/tests/tasks/seed.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
use std::collections::BTreeMap;

use blo::app::App;
use loco_rs::{boot::run_task, testing};
use loco_rs::{boot::run_task, task, testing};
use serial_test::serial;

#[tokio::test]
#[serial]
async fn test_can_seed_data() {
let boot = testing::boot_test::<App>().await.unwrap();

let vars = BTreeMap::new();

assert!(
run_task::<App>(&boot.app_context, Some(&"seed_data".to_string()), &vars)
.await
.is_ok()
);
assert!(run_task::<App>(
&boot.app_context,
Some(&"seed_data".to_string()),
&task::Vars::default()
)
.await
.is_ok());
}
4 changes: 2 additions & 2 deletions loco-extras/src/initializers/mongodb/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use async_trait::async_trait;
use axum::{Extension, Router as AxumRouter};
use loco_rs::prelude::*;

use mongodb::{bson::doc, options::ClientOptions, Client, Database};

#[allow(clippy::module_name_repetitions)]
Expand Down Expand Up @@ -106,7 +105,8 @@ fn merge_config_with_client(co: &mut ClientOptions, config: MongoDbConfig) -> Cl
.default_database
.or(co.default_database.clone());
co.tls = client_options.tls.or(co.tls.clone());
// co.tracing_max_document_length_bytes = client_options.tracing_max_document_length_bytes;
// co.tracing_max_document_length_bytes =
// client_options.tracing_max_document_length_bytes;
co.write_concern = client_options.write_concern.or(co.write_concern.clone());
co.srv_max_hosts = client_options.srv_max_hosts.or(co.srv_max_hosts.clone());

Expand Down
9 changes: 9 additions & 0 deletions snipdoc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,12 @@ snippets:
content: cargo loco generate scaffold posts
name:string title:string content:text
path: ./snipdoc.yml
generate-task-help-command:
content: cd ./examples/demo && cargo loco generate task --help
path: ./snipdoc.yml
run-task-command:
content: cargo loco task <TASK_NAME>
path: ./snipdoc.yml
list-tasks-command:
content: cargo loco task
path: ./snipdoc.yml
6 changes: 2 additions & 4 deletions src/boot.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
//! # Application Bootstrapping and Logic
//! This module contains functions and structures for bootstrapping and running
//! your application.
use std::collections::BTreeMap;

use axum::Router;
#[cfg(feature = "with-db")]
use sea_orm_migration::MigratorTrait;
Expand All @@ -21,7 +19,7 @@ use crate::{
mailer::{EmailSender, MailerWorker},
redis,
storage::{self, Storage},
task::Tasks,
task::{self, Tasks},
worker::{self, AppWorker, Pool, Processor, RedisConnectionManager, DEFAULT_QUEUES},
Result,
};
Expand Down Expand Up @@ -105,7 +103,7 @@ async fn process(processor: Processor) -> Result<()> {
pub async fn run_task<H: Hooks>(
app_context: &AppContext,
task: Option<&String>,
vars: &BTreeMap<String, String>,
vars: &task::Vars,
) -> Result<()> {
let mut tasks = Tasks::default();
H::register_tasks(&mut tasks);
Expand Down
12 changes: 3 additions & 9 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
//! cli::main::<App, Migrator>().await
//! }
//! ```
use std::collections::BTreeMap;

cfg_if::cfg_if! {
if #[cfg(feature = "with-db")] {
use sea_orm_migration::MigratorTrait;
Expand All @@ -37,7 +34,7 @@ use crate::{
},
environment::{resolve_from_env, Environment, DEFAULT_ENVIRONMENT},
gen::{self, Component},
logger,
logger, task,
};
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
Expand Down Expand Up @@ -338,12 +335,9 @@ pub async fn main<H: Hooks, M: MigratorTrait>() -> eyre::Result<()> {
show_list_endpoints::<H>(&app_context);
}
Commands::Task { name, params } => {
let mut hash = BTreeMap::new();
for (k, v) in params {
hash.insert(k, v);
}
let vars = task::Vars::from_cli_args(params);
let app_context = create_context::<H>(&environment).await?;
run_task::<H>(&app_context, name.as_ref(), &hash).await?;
run_task::<H>(&app_context, name.as_ref(), &vars).await?;
}
Commands::Generate { component } => {
gen::generate::<H>(component.into(), &config)?;
Expand Down
4 changes: 1 addition & 3 deletions src/gen/templates/task.t
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ injections:
after: "fn register_tasks"
content: " tasks.register(tasks::{{file_name}}::{{module_name}});"
---
use std::collections::BTreeMap;

use loco_rs::prelude::*;

pub struct {{module_name}};
Expand All @@ -24,7 +22,7 @@ impl Task for {{module_name}} {
detail: "Task generator".to_string(),
}
}
async fn run(&self, _app_context: &AppContext, _vars: &BTreeMap<String, String>) -> Result<()> {
async fn run(&self, _app_context: &AppContext, _vars: &task::Vars) -> Result<()> {
println!("Task {{module_name}} generated");
Ok(())
}
Expand Down
7 changes: 2 additions & 5 deletions src/gen/templates/task_test.t
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,18 @@ injections:
content: "pub mod {{ file_name }};"
---
use {{pkg_name}}::app::App;
use loco_rs::testing;
use loco_rs::{task, testing};

use loco_rs::boot::run_task;
use serial_test::serial;
use std::collections::BTreeMap;

#[tokio::test]
#[serial]
async fn test_can_run_{{name | snake_case}}() {
let boot = testing::boot_test::<App>().await.unwrap();

let vars = BTreeMap::new();

assert!(
run_task::<App>(&boot.app_context, Some(&"{{name}}".to_string()), &vars)
run_task::<App>(&boot.app_context, Some(&"{{name}}".to_string()), &task::Vars::default())
.await
.is_ok()
);
Expand Down
2 changes: 1 addition & 1 deletion src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub use crate::{
errors::Error,
mailer,
mailer::Mailer,
task::{Task, TaskInfo},
task::{self, Task, TaskInfo},
validation::{self, Validatable},
validator::Validate,
worker::{self, AppWorker},
Expand Down
Loading

0 comments on commit 58ed204

Please sign in to comment.