Skip to content

Commit

Permalink
Merge branch 'master' into documentation/update_zola.v0.19.2
Browse files Browse the repository at this point in the history
  • Loading branch information
kaplanelad authored Sep 19, 2024
2 parents d29c1e3 + 1c3d0bc commit 28e2810
Show file tree
Hide file tree
Showing 50 changed files with 734 additions and 29 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci-generators.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres_test

- name: controller
run: cargo run -- generate controller pages about && cargo build && cargo test pages
run: cargo run -- generate controller pages about --htmx && cargo build && cargo test pages
working-directory: ./examples/demo
env:
REDIS_URL: redis://localhost:${{job.services.redis.ports[6379]}}
Expand Down
6 changes: 3 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

## Unreleased


## v0.8.1
* fix: introduce secondary binary for compile-and-run on Windows. [https://github.com/loco-rs/loco/pull/727](https://github.com/loco-rs/loco/pull/727)
* Add fallback behavior. [https://github.com/loco-rs/loco/pull/732](https://github.com/loco-rs/loco/pull/732)
* Add Scheduler Feature for Running Cron Jobs. [https://github.com/loco-rs/loco/pull/735](https://github.com/loco-rs/loco/pull/735)
* Add `--html`, `--htmx` and `--api` flags to scaffold CLI command. [https://github.com/loco-rs/loco/pull/749](https://github.com/loco-rs/loco/pull/749)
* Add base template for scaffold generation. [https://github.com/loco-rs/loco/pull/752](https://github.com/loco-rs/loco/pull/752)
* Connect Redis only when the worker is BackgroundQueue. [https://github.com/loco-rs/loco/pull/755](https://github.com/loco-rs/loco/pull/755)

## v0.8.1
* fix: introduce secondary binary for compile-and-run on Windows. [https://github.com/loco-rs/loco/pull/727](https://github.com/loco-rs/loco/pull/727)


## v0.8.0
Expand Down
13 changes: 7 additions & 6 deletions src/boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,11 +396,12 @@ fn create_mailer(config: &config::Mailer) -> Result<Option<EmailSender>> {
// TODO: Refactor to eliminate unwrapping and instead return an appropriate
// error type.
pub async fn connect_redis(config: &Config) -> Option<Pool<RedisConnectionManager>> {
if let Some(redis) = &config.queue {
let manager = RedisConnectionManager::new(redis.uri.clone()).unwrap();
let redis = Pool::builder().build(manager).await.unwrap();
Some(redis)
} else {
None
if config.workers.mode == config::WorkerMode::BackgroundQueue {
if let Some(redis) = &config.queue {
let manager = RedisConnectionManager::new(redis.uri.clone()).unwrap();
let redis = Pool::builder().build(manager).await.unwrap();
return Some(redis);
}
}
None
}
47 changes: 39 additions & 8 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,21 @@ enum ComponentArg {
/// Actions
actions: Vec<String>,

/// The kind of scaffold to generate
#[clap(short, long, value_enum, default_value_t = gen::ScaffoldKind::Api)]
kind: gen::ScaffoldKind,
/// The kind of controller actions to generate
#[clap(short, long, value_enum, group = "scaffold_kind_group")]
kind: Option<gen::ScaffoldKind>,

/// Use HTMX controller actions
#[clap(long, group = "scaffold_kind_group")]
htmx: bool,

/// Use HTML controller actions
#[clap(long, group = "scaffold_kind_group")]
html: bool,

/// Use API controller actions
#[clap(long, group = "scaffold_kind_group")]
api: bool,
},
/// Generate a Task based on the given name
Task {
Expand Down Expand Up @@ -256,11 +268,30 @@ impl TryFrom<ComponentArg> for Component {
name,
actions,
kind,
} => Ok(Self::Controller {
name,
actions,
kind,
}),
htmx,
html,
api,
} => {
let kind = if let Some(kind) = kind {
kind
} else if htmx {
ScaffoldKind::Htmx
} else if html {
ScaffoldKind::Html
} else if api {
ScaffoldKind::Api
} else {
return Err(crate::Error::string(
"Error: One of `kind`, `htmx`, `html`, or `api` must be specified.",
));
};

Ok(Self::Controller {
name,
actions,
kind,
})
}
ComponentArg::Task { name } => Ok(Self::Task { name }),
ComponentArg::Scheduler {} => Ok(Self::Scheduler {}),
ComponentArg::Worker { name } => Ok(Self::Worker { name }),
Expand Down
2 changes: 1 addition & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ pub struct Workers {
}

/// Worker mode configuration
#[derive(Clone, Default, Serialize, Deserialize, Debug)]
#[derive(Clone, Default, Serialize, Deserialize, Debug, PartialEq, Eq)]
pub enum WorkerMode {
/// Workers operate asynchronously in the background, processing queued
/// tasks. **Requires a Redis connection**.
Expand Down
107 changes: 107 additions & 0 deletions src/controller/app_routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,3 +521,110 @@ fn handle_panic(err: Box<dyn std::any::Any + Send + 'static>) -> axum::response:

errors::Error::InternalServerError.into_response()
}

#[cfg(test)]
mod tests {

use super::*;
use crate::prelude::*;
use crate::tests_cfg;
use insta::assert_debug_snapshot;
use rstest::rstest;
use tower::ServiceExt;

async fn action() -> Result<Response> {
format::json("loco")
}

#[test]
fn can_load_app_route_from_default() {
for route in AppRoutes::with_default_routes().collect() {
assert_debug_snapshot!(
format!("[{}]", route.uri.replace('/', "[slash]")),
format!("{:?} {}", route.actions, route.uri)
);
}
}

#[test]
fn can_load_empty_app_routes() {
assert_eq!(AppRoutes::empty().collect().len(), 0);
}

#[test]
fn can_load_routes() {
let router_without_prefix = Routes::new().add("/", get(action));
let normalizer = Routes::new()
.prefix("/normalizer")
.add("no-slash", get(action))
.add("/", post(action))
.add("//loco///rs//", delete(action))
.add("//////multiple-start", head(action))
.add("multiple-end/////", trace(action));

let app_router = AppRoutes::empty()
.add_route(router_without_prefix)
.add_route(normalizer)
.add_routes(vec![
Routes::new().add("multiple1", put(action)),
Routes::new().add("multiple2", options(action)),
Routes::new().add("multiple3", patch(action)),
]);

for route in app_router.collect() {
assert_debug_snapshot!(
format!("[{}]", route.uri.replace('/', "[slash]")),
format!("{:?} {}", route.actions, route.uri)
);
}
}

#[test]
fn can_load_routes_with_root_prefix() {
let router_without_prefix = Routes::new()
.add("/loco", get(action))
.add("loco-rs", get(action));

let app_router = AppRoutes::empty()
.prefix("api")
.add_route(router_without_prefix);

for route in app_router.collect() {
assert_debug_snapshot!(
format!("[{}]", route.uri.replace('/', "[slash]")),
format!("{:?} {}", route.actions, route.uri)
);
}
}
#[rstest]
#[case(axum::http::Method::GET, get(action))]
#[case(axum::http::Method::POST, post(action))]
#[case(axum::http::Method::DELETE, delete(action))]
#[case(axum::http::Method::HEAD, head(action))]
#[case(axum::http::Method::OPTIONS, options(action))]
#[case(axum::http::Method::PATCH, patch(action))]
#[case(axum::http::Method::POST, post(action))]
#[case(axum::http::Method::PUT, put(action))]
#[case(axum::http::Method::TRACE, trace(action))]
#[tokio::test]
async fn can_xx(
#[case] http_method: axum::http::Method,
#[case] method: axum::routing::MethodRouter<AppContext>,
) {
let router_without_prefix = Routes::new().add("/loco", method);

let app_router = AppRoutes::empty().add_route(router_without_prefix);

let ctx = tests_cfg::app::get_app_context().await;
let router = app_router.to_router(ctx, axum::Router::new()).unwrap();

let req = axum::http::Request::builder()
.uri("/loco")
.method(http_method)
.body(axum::body::Body::empty())
.unwrap();

let response = router.oneshot(req).await.unwrap();
assert!(response.status().is_success());
}
}
2 changes: 1 addition & 1 deletion src/controller/fallback.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

<body class="bg-gray-100 text-gray-900">
<div class="min-h-screen flex flex-col justify-center items-center py-8">
<div class=" shadow-md rounded-lg p-8 max-w-xl text-center">
<div class="bg-white shadow-md rounded-lg p-8 max-w-xl text-center">
<svg class="mx-auto my-4" width="113" height="" viewBox="0 0 413 413" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_201_516" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="413" height="413">
<circle cx="206.5" cy="206.5" r="206.5" fill="white"/>
Expand Down
Loading

0 comments on commit 28e2810

Please sign in to comment.