Skip to content

Commit

Permalink
Merge branch 'master' into wait-for-background-workers
Browse files Browse the repository at this point in the history
  • Loading branch information
jondot authored Oct 31, 2024
2 parents 192b38a + 8ce70ea commit 336e6e8
Show file tree
Hide file tree
Showing 46 changed files with 672 additions and 226 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## Unreleased

* `loco doctor` now checks for app-specific minimum dependency versions. This should help in upgrades. `doctor` also supports "production only" checks which you can run in production with `loco doctor --production`. This, for example, will check your connections but will not check dependencies.
*

## v0.12.0

This release have been primarily about cleanups and simplification.
Expand Down
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ serde = { workspace = true }
serde_json = { workspace = true }
serde_yaml = "0.9"
serde_variant = "0.1.2"
toml = "0.8"


async-trait = { workspace = true }

axum = { workspace = true }
axum-extra = { version = "0.9", features = ["cookie"] }
regex = { workspace = true }
lazy_static = { workspace = true }
fs-err = "2.11.0"
# mailer
tera = "1.19.1"
Expand Down Expand Up @@ -143,7 +143,6 @@ regex = "1"
thiserror = "1"
serde = "1"
serde_json = "1"
lazy_static = "1.4.0"
async-trait = { version = "0.1.74" }
axum = { version = "0.7.5", features = ["macros"] }
tower = "0.4"
Expand Down
18 changes: 18 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
## Blessed depdenencies maintenance and `loco doctor`

Loco contain a few major and "blessed" dependencies, these appear **both** in an app that was generated at the surface level in their `Cargo.toml` and in the core Loco framework.

If stale, may require an upgrade as a must.

Example for such dependencies:

* The `sea-orm-cli` - while Loco uses `SeaORM`, it uses the `SeaORM` CLI to generate entities, and so there may be an incompatibility if `SeaORM` has a too large breaking change between their CLI (which ships separately) and their framework.
* `axum`
* etc.

This is why we are checking these automatically as part of `loco doctor`.

We keep minimal version requirements for these. As a maintainer, you can update these **minimal** versions, only if required in [`doctor.rs`](src/doctor.rs).



## Running Tests

Before running tests make sure that:
Expand Down
7 changes: 7 additions & 0 deletions docs-site/content/docs/infrastructure/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,13 @@ auth:
```
<!-- </snip>-->
## Running `loco doctor`

You can run `loco doctor` in your server to check the connection health of your environment.

```sh
$ myapp doctor --production
```

## Generate

Expand Down
25 changes: 18 additions & 7 deletions examples/demo/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions examples/demo/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ impl Hooks for App {
}

// <snip id="app-initializers">
async fn initializers(ctx: &AppContext) -> Result<Vec<Box<dyn Initializer>>> {
let mut initializers: Vec<Box<dyn Initializer>> = vec![
async fn initializers(_ctx: &AppContext) -> Result<Vec<Box<dyn Initializer>>> {
let initializers: Vec<Box<dyn Initializer>> = vec![
Box::new(initializers::axum_session::AxumSessionInitializer),
Box::new(initializers::view_engine::ViewEngineInitializer),
Box::new(initializers::hello_view_engine::HelloViewEngineInitializer),
Expand Down
2 changes: 2 additions & 0 deletions examples/demo/tests/cmd/cli.trycmd
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ $ demo_app-cli doctor
✅ SeaORM CLI is installed
✅ DB connection: success
✅ redis queue: queue connection: success
✅ Dependencies


```

Expand Down
9 changes: 4 additions & 5 deletions examples/demo/tests/requests/notes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use insta::{assert_debug_snapshot, with_settings};
use loco_rs::testing;
use rstest::rstest;
use sea_orm::entity::prelude::*;
use serde_json;
use serial_test::serial;

// TODO: see how to dedup / extract this to app-local test utils
Expand Down Expand Up @@ -34,7 +33,7 @@ async fn can_get_notes(#[case] test_name: &str, #[case] params: serde_json::Valu

with_settings!({
filters => {
let mut combined_filters = testing::CLEANUP_DATE.to_vec();
let mut combined_filters = testing::get_cleanup_date().clone();
combined_filters.extend(vec![(r#"\"id\\":\d+"#, r#""id\":ID"#)]);
combined_filters
}
Expand Down Expand Up @@ -62,7 +61,7 @@ async fn can_add_note() {

with_settings!({
filters => {
let mut combined_filters = testing::CLEANUP_DATE.to_vec();
let mut combined_filters = testing::get_cleanup_date().clone();
combined_filters.extend(vec![(r#"\"id\\":\d+"#, r#""id\":ID"#)]);
combined_filters
}
Expand All @@ -87,7 +86,7 @@ async fn can_get_note() {

with_settings!({
filters => {
let mut combined_filters = testing::CLEANUP_DATE.to_vec();
let mut combined_filters = testing::get_cleanup_date().clone();
combined_filters.extend(vec![(r#"\"id\\":\d+"#, r#""id\":ID"#)]);
combined_filters
}
Expand All @@ -113,7 +112,7 @@ async fn can_delete_note() {

with_settings!({
filters => {
let mut combined_filters = testing::CLEANUP_DATE.to_vec();
let mut combined_filters = testing::get_cleanup_date().clone();
combined_filters.extend(vec![(r#"\"id\\":\d+"#, r#""id\":ID"#)]);
combined_filters
}
Expand Down
2 changes: 1 addition & 1 deletion loco-cli/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub fn for_options(
match assetopt {
AssetsOption::Clientside => res.push(format!(
"{}: You've selected `{}` for your asset serving configuration.\n\nNext step, build \
your frontend:\n $ cd {}\n $ npm install && npm build\n",
your frontend:\n $ cd {}\n $ npm install && npm run build\n",
"assets".underline(),
"clientside".yellow(),
"frontend/".yellow()
Expand Down
1 change: 0 additions & 1 deletion loco-gen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ path = "src/lib.rs"

[dependencies]

lazy_static = { workspace = true }
rrgen = "0.5.3"
serde = { workspace = true }
serde_json = { workspace = true }
Expand Down
11 changes: 6 additions & 5 deletions loco-gen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// TODO: should be more properly aligned with extracting out the db-related gen
// code and then feature toggling it
#![allow(dead_code)]
use lazy_static::lazy_static;
use rrgen::{GenResult, RRgen};
use serde::{Deserialize, Serialize};
use serde_json::json;
Expand All @@ -14,7 +13,7 @@ mod model;
mod scaffold;
#[cfg(test)]
mod testutil;
use std::str::FromStr;
use std::{str::FromStr, sync::OnceLock};

const CONTROLLER_T: &str = include_str!("templates/controller.t");
const CONTROLLER_TEST_T: &str = include_str!("templates/request_test.t");
Expand Down Expand Up @@ -109,11 +108,13 @@ impl Mappings {
}
}

lazy_static! {
static ref MAPPINGS: Mappings = {
static MAPPINGS: OnceLock<Mappings> = OnceLock::new();

fn get_mappings() -> &'static Mappings {
MAPPINGS.get_or_init(|| {
let json_data = include_str!("./mappings.json");
serde_json::from_str(json_data).expect("JSON was not well-formatted")
};
})
}

#[derive(clap::ValueEnum, Clone, Debug)]
Expand Down
8 changes: 5 additions & 3 deletions loco-gen/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ use rrgen::RRgen;
use serde_json::json;

use super::{Error, Result};
use crate::get_mappings;

const MODEL_T: &str = include_str!("templates/model.t");
const MODEL_TEST_T: &str = include_str!("templates/model_test.t");

use super::{collect_messages, AppInfo, MAPPINGS};
use super::{collect_messages, AppInfo};

/// skipping some fields from the generated models.
/// For example, the `created_at` and `updated_at` fields are automatically
Expand Down Expand Up @@ -44,11 +45,12 @@ pub fn generate(
// user, user_id
references.push((fname, fkey));
} else {
let schema_type = MAPPINGS.schema_field(ftype.as_str()).ok_or_else(|| {
let mappings = get_mappings();
let schema_type = mappings.schema_field(ftype.as_str()).ok_or_else(|| {
Error::Message(format!(
"type: {} not found. try any of: {:?}",
ftype,
MAPPINGS.schema_fields()
mappings.schema_fields()
))
})?;
columns.push((fname.to_string(), schema_type.as_str()));
Expand Down
9 changes: 5 additions & 4 deletions loco-gen/src/scaffold.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use rrgen::RRgen;
use serde_json::json;

use crate as gen;
use crate::{self as gen, get_mappings};

const API_CONTROLLER_SCAFFOLD_T: &str = include_str!("templates/scaffold/api/controller.t");
const API_CONTROLLER_TEST_T: &str = include_str!("templates/scaffold/api/test.t");
Expand All @@ -22,7 +22,7 @@ const HTML_VIEW_CREATE_SCAFFOLD_T: &str = include_str!("templates/scaffold/html/
const HTML_VIEW_SHOW_SCAFFOLD_T: &str = include_str!("templates/scaffold/html/view_show.t");
const HTML_VIEW_LIST_SCAFFOLD_T: &str = include_str!("templates/scaffold/html/view_list.t");

use super::{collect_messages, model, AppInfo, Error, Result, MAPPINGS};
use super::{collect_messages, model, AppInfo, Error, Result};

pub fn generate(
rrgen: &RRgen,
Expand All @@ -35,6 +35,7 @@ pub fn generate(
// - never run with migration_only, because the controllers will refer to the
// models. the models only arrive after migration and entities sync.
let model_messages = model::generate(rrgen, name, false, false, fields, appinfo)?;
let mappings = get_mappings();

let mut columns = Vec::new();
for (fname, ftype) in fields {
Expand All @@ -46,11 +47,11 @@ pub fn generate(
continue;
}
if ftype != "references" {
let schema_type = MAPPINGS.rust_field(ftype.as_str()).ok_or_else(|| {
let schema_type = mappings.rust_field(ftype.as_str()).ok_or_else(|| {
Error::Message(format!(
"type: {} not found. try any of: {:?}",
ftype,
MAPPINGS.rust_fields()
mappings.rust_fields()
))
})?;
columns.push((fname.to_string(), schema_type.as_str(), ftype));
Expand Down
4 changes: 2 additions & 2 deletions loco-gen/src/templates/controller/api/test.t
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{% set module_name = file_name | pascal_case -%}
to: tests/requests/{{ file_name }}.rs
skip_exists: true
message: "Tests for controller `{{module_name}}` was added successfully. Run `cargo run test`."
message: "Tests for controller `{{module_name}}` was added successfully. Run `cargo test`."
injections:
- into: tests/requests/mod.rs
append: true
Expand All @@ -16,7 +16,7 @@ use serial_test::serial;
#[serial]
async fn can_get_{{ name | plural | snake_case }}() {
testing::request::<App, _, _>(|request, _ctx| async move {
let res = request.get("/{{ name | plural | snake_case }}/").await;
let res = request.get("/api/{{ name | plural | snake_case }}/").await;
assert_eq!(res.status_code(), 200);

// you can assert content like this:
Expand Down
2 changes: 1 addition & 1 deletion loco-gen/src/templates/request_test.t
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{% set module_name = file_name | pascal_case -%}
to: tests/requests/{{ file_name }}.rs
skip_exists: true
message: "Tests for controller `{{module_name}}` was added successfully. Run `cargo run test`."
message: "Tests for controller `{{module_name}}` was added successfully. Run `cargo test`."
injections:
- into: tests/requests/mod.rs
append: true
Expand Down
4 changes: 2 additions & 2 deletions loco-gen/src/templates/scaffold/api/test.t
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{% set module_name = file_name | pascal_case -%}
to: tests/requests/{{ file_name }}.rs
skip_exists: true
message: "Tests for controller `{{module_name}}` was added successfully. Run `cargo run test`."
message: "Tests for controller `{{module_name}}` was added successfully. Run `cargo test`."
injections:
- into: tests/requests/mod.rs
append: true
Expand All @@ -16,7 +16,7 @@ use serial_test::serial;
#[serial]
async fn can_get_{{ name | plural | snake_case }}() {
testing::request::<App, _, _>(|request, _ctx| async move {
let res = request.get("/{{ name | plural | snake_case }}/").await;
let res = request.get("/api/{{ name | plural | snake_case }}/").await;
assert_eq!(res.status_code(), 200);

// you can assert content like this:
Expand Down
2 changes: 2 additions & 0 deletions loco-gen/src/templates/scaffold/html/base.t
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ message: "Base template was added successfully."
<html lang="en">

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{% raw %}{% block title %}{% endblock title %}{% endraw %}</title>
<script src="https://cdn.tailwindcss.com?plugins=forms,typography,aspect-ratio,line-clamp"></script>
{% raw %}{% block head %}{% endraw %}
Expand Down
2 changes: 2 additions & 0 deletions loco-gen/src/templates/scaffold/htmx/base.t
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ message: "Base template was added successfully."
<html lang="en">

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{% raw %}{% block title %}{% endblock title %}{% endraw %}</title>

<script src="https://unpkg.com/[email protected]/dist/htmx.min.js"></script>
Expand Down
Loading

0 comments on commit 336e6e8

Please sign in to comment.