Skip to content

Commit

Permalink
Merge branch 'master' into new-loco-cli-generator
Browse files Browse the repository at this point in the history
  • Loading branch information
jondot authored Nov 14, 2024
2 parents 52a2ae0 + 5c4ed5d commit 24e952b
Show file tree
Hide file tree
Showing 28 changed files with 724 additions and 84 deletions.
60 changes: 60 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,66 @@

## Unreleased

## v0.13.0

* Added SQLite background job support [https://github.com/loco-rs/loco/pull/969](https://github.com/loco-rs/loco/pull/969)
* Added automatic updating of `updated_at` on change [https://github.com/loco-rs/loco/pull/962](https://github.com/loco-rs/loco/pull/962)
* fixed codegen injection point in migrations [https://github.com/loco-rs/loco/pull/952](https://github.com/loco-rs/loco/pull/952)

**NOTE: update your migration listing module like so:**

```rust
// migrations/src/lib.rs
vec![
Box::new(m20220101_000001_users::Migration),
Box::new(m20231103_114510_notes::Migration),
Box::new(m20240416_071825_roles::Migration),
Box::new(m20240416_082115_users_roles::Migration),
// inject-above (do not remove this comment)
]
```

Add the comment just before the closing array (`inject-above`)

* Added ability to name references in [https://github.com/loco-rs/loco/pull/955](https://github.com/loco-rs/loco/pull/955):

```sh
$ generate scaffold posts title:string! content:string! written_by:references:users approved_by:references:users
```

* Added hot-reload like experience to Tera templates [https://github.com/loco-rs/loco/issues/977](https://github.com/loco-rs/loco/issues/977), in debug builds only.

**NOTE: update your initializers `after_routes` like so:**

```rust
// src/initializers/view_engine.rs
async fn after_routes(&self, router: AxumRouter, _ctx: &AppContext) -> Result<AxumRouter> {
#[allow(unused_mut)]
let mut tera_engine = engines::TeraView::build()?;
if std::path::Path::new(I18N_DIR).exists() {
let arc = ArcLoader::builder(&I18N_DIR, unic_langid::langid!("en-US"))
.shared_resources(Some(&[I18N_SHARED.into()]))
.customize(|bundle| bundle.set_use_isolating(false))
.build()
.map_err(|e| Error::string(&e.to_string()))?;
#[cfg(debug_assertions)]
tera_engine
.tera
.lock()
.expect("lock")
.register_function("t", FluentLoader::new(arc));

#[cfg(not(debug_assertions))]
tera_engine
.tera
.register_function("t", FluentLoader::new(arc));
info!("locales loaded");
}

Ok(router.layer(Extension(ViewEngine::from(tera_engine))))
}
```

* `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. [https://github.com/loco-rs/loco/pull/931](https://github.com/loco-rs/loco/pull/931)
* Use a single loco-rs dep for a whole project. [https://github.com/loco-rs/loco/pull/927](https://github.com/loco-rs/loco/pull/927)
* chore: fix generated testcase. [https://github.com/loco-rs/loco/pull/939](https://github.com/loco-rs/loco/pull/939)
Expand Down
57 changes: 34 additions & 23 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,15 @@ rust-version.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
default = ["auth_jwt", "cli", "cache_inmem", "with-db", "bg_redis", "bg_pg"]
default = [
"auth_jwt",
"cli",
"with-db",
"cache_inmem",
"bg_redis",
"bg_pg",
"bg_sqlt",
]
auth_jwt = ["dep:jsonwebtoken"]
cli = ["dep:clap"]
testing = ["dep:axum-test"]
Expand All @@ -37,6 +45,7 @@ storage_gcp = ["object_store/gcp"]
cache_inmem = ["dep:moka"]
bg_redis = ["dep:rusty-sidekiq", "dep:bb8"]
bg_pg = ["dep:sqlx", "dep:ulid"]
bg_sqlt = ["dep:sqlx", "dep:ulid"]

[dependencies]
loco-gen = { version = "0.12.0", path = "./loco-gen" }
Expand All @@ -48,10 +57,10 @@ colored = "2"


sea-orm = { version = "1.1.0", features = [
"sqlx-postgres", # `DATABASE_DRIVER` feature
"sqlx-sqlite",
"runtime-tokio-rustls",
"macros",
"sqlx-postgres", # `DATABASE_DRIVER` feature
"sqlx-sqlite",
"runtime-tokio-rustls",
"macros",
], optional = true }

tokio = { version = "1.33.0", default-features = false }
Expand All @@ -75,10 +84,10 @@ fs-err = "2.11.0"
tera = "1.19.1"
heck = "0.4.0"
lettre = { version = "0.11.4", default-features = false, features = [
"builder",
"hostname",
"smtp-transport",
"tokio1-rustls-tls",
"builder",
"hostname",
"smtp-transport",
"tokio1-rustls-tls",
] }
include_dir = "0.7.3"
thiserror = { workspace = true }
Expand Down Expand Up @@ -125,10 +134,12 @@ moka = { version = "0.12.7", features = ["sync"], optional = true }
tokio-cron-scheduler = { version = "0.11.0", features = ["signal"] }
english-to-cron = { version = "0.1.2" }

# bg_sqlt: sqlite workers
# bg_pg: postgres workers
sqlx = { version = "0.8.2", default-features = false, features = [
"postgres",
"chrono",
"sqlite",
], optional = true }
ulid = { version = "1", optional = true }

Expand All @@ -148,26 +159,26 @@ async-trait = { version = "0.1.74" }
axum = { version = "0.7.5", features = ["macros"] }
tower = "0.4"
tower-http = { version = "0.6.1", features = [
"trace",
"catch-panic",
"timeout",
"add-extension",
"cors",
"fs",
"set-header",
"compression-full",
"trace",
"catch-panic",
"timeout",
"add-extension",
"cors",
"fs",
"set-header",
"compression-full",
] }

[dependencies.sea-orm-migration]
optional = true
version = "1.0.0"
features = [
# Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI.
# View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime.
# e.g.
"runtime-tokio-rustls", # `ASYNC_RUNTIME` feature
"sqlx-postgres", # `DATABASE_DRIVER` feature
"sqlx-sqlite",
# Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI.
# View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime.
# e.g.
"runtime-tokio-rustls", # `ASYNC_RUNTIME` feature
"sqlx-postgres", # `DATABASE_DRIVER` feature
"sqlx-sqlite",
]

[package.metadata.docs.rs]
Expand Down
5 changes: 5 additions & 0 deletions docs-site/content/docs/getting-started/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,10 @@ Instead of coding the model and controller by hand, we're going to create a **co
$ cargo loco generate scaffold comment content:text article:references --api
```
<div class="infobox">
The special <code>references:&lt;table&gt;</code> is also available. For when you want to have a different name for your column.
</div>
If you peek into the new migration, you'll discover a new database relation in the articles table:
```rust
Expand All @@ -653,6 +657,7 @@ If you peek into the new migration, you'll discover a new database relation in t
..
```
Now, lets modify our API in the following way:
1. Comments can be added through a shallow route: `POST comments/`
Expand Down
6 changes: 3 additions & 3 deletions docs-site/content/docs/getting-started/tour/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ We have a base SaaS app with user authentication generated for us. Let's make it

<div class="infobox">

You can choose between generating an `api`, `html` or `htmx` scaffold using the required `-k` flag.
You can choose between generating an `api`, `html` or `htmx` scaffold using the respective `-api`, `--html`, and `--htmx` flags.
</div>

```sh
Expand Down Expand Up @@ -142,9 +142,9 @@ listening on port 5150

<div class="infobox">

Depending on which `-k` option you chose, the steps for creating a scaffolded resource will change. With the `api` flag or the `htmx` flag you can use the below example. But with the `html` flag, it is recommended you do the post creation steps in your browser.
Depending on which scaffold template option you chose (`-api`, `--html`, `--htmx`), the steps for creating a scaffolded resource will change. With the `--api` flag or the `--htmx` flag you can use the below example. But with the `--html` flag, it is recommended you do the post creation steps in your browser.

If you want to use `curl` to test the `html` scaffold, you will need to send your requests with the Content-Type `application/x-www-form-urlencoded` and the body as `title=Your+Title&content=Your+Content` by default. This can be changed to allow `application/json` as a `Content-Type` in the code if desired.
If you want to use `curl` to test the `--html` scaffold, you will need to send your requests with the Content-Type `application/x-www-form-urlencoded` and the body as `title=Your+Title&content=Your+Content` by default. This can be changed to allow `application/json` as a `Content-Type` in the code if desired.

</div>

Expand Down
15 changes: 13 additions & 2 deletions docs-site/content/docs/processing/workers.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Loco provides the following options for background jobs:

* Redis backed (powered by `sidekiq-rs`)
* Postgres backed (own implementation)
* SQLite backed (own implementation)
* Tokio-async based (same-process, evented thread based background jobs)


Expand Down Expand Up @@ -57,11 +58,21 @@ Or a Postgres based queue backend:
```yaml
queue:
kind: Postgres
# Redis connection URI
# Postgres Queue connection URI
uri: "{{ get_env(name="PGQ_URL", default="postgres://localhost:5432/mydb") }}"
dangerously_flush: false
```
Or a SQLite based queue backend:
```yaml
queue:
kind: Sqlite
# SQLite Queue connection URI
uri: "{{ get_env(name="SQLTQ_URL", default="sqlite://loco_development.sqlite?mode=rwc") }}"
dangerously_flush: false
```
## Running the worker process
You can run in two ways, depending on which setting you chose for background workers:
Expand Down Expand Up @@ -164,7 +175,7 @@ The worker generator creates a worker file associated with your app and generate

In your `config/<environment>.yaml` you can specify the worker mode. BackgroundAsync and BackgroundQueue will process jobs in a non-blocking manner, while ForegroundBlocking will process jobs in a blocking manner.

The main difference between BackgroundAsync and BackgroundQueue is that the latter will use Redis to store the jobs, while the former does not require Redis and will use async within the same process.
The main difference between BackgroundAsync and BackgroundQueue is that the latter will use Redis/Postgres/SQLite to store the jobs, while the former does not require Redis/Postgres/SQLite and will use async in memory within the same process.

```yaml
# Worker Configuration
Expand Down
6 changes: 6 additions & 0 deletions docs-site/content/docs/resources/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ Try [cargo watch](https://crates.io/crates/cargo-watch):
$ cargo-watch -x check -s 'cargo loco start'
```

Or [bacon](https://github.com/Canop/bacon)

```
$ bacon run
```

</details>
<br/>
<details>
Expand Down
17 changes: 10 additions & 7 deletions docs-site/content/docs/the-app/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ When a model is added via migration, the following default fields are provided:
- `created_at` (ts!): This is a timestamp indicating when your model was created.
- `updated_at` (ts!): This is a timestamp indicating when your model was updated.

These fields are ignored if you provide them in your migration command. In addition, `create_at` and `update_at` fields are also ignored if provided.
These fields are ignored if you provide them in your migration command.

For schema data types, you can use the following mapping to understand the schema:

Expand Down Expand Up @@ -173,6 +173,8 @@ For schema data types, you can use the following mapping to understand the schem

Using `user:references` uses the special `references` type, which will create a relationship between a `post` and a `user`, adding a `user_id` reference field to the `posts` table.

Using `aproved_by:references:users` uses the special `references:<table>` type, which will create a relationship between a `post` and a `user`, adding a `aproved_by` reference field to the `posts` table.

You can generate an empty model:

```
Expand Down Expand Up @@ -228,20 +230,21 @@ cargo loco db down 2

### Verbs, singular and plural

* **references**: use **singular** for the table name, and a `:references` type. `user:references` (references `Users`), `vote:references` (references `Votes`)
* **column names**: anything you like. Prefer `snake_case`
* **references**: use **singular** for the table name, and a `:references` type. `user:references` (references `Users`), `vote:references` (references `Votes`). `:references:<table>` is also available `departing_train:references:trains` (references `Trains`).
* **column names**: anything you like. Prefer `snake_case`.
* **table names**: **plural, snake case**. `users`, `draft_posts`.
* **migration names**: anything that can be a file name, prefer snake case. `create_table_users`, `add_vote_id_to_movies`
* **model names**: generated automatically for you. Usually the generated name is pascal case, plural. `Users`, `UsersVotes`
* **migration names**: anything that can be a file name, prefer snake case. `create_table_users`, `add_vote_id_to_movies`.
* **model names**: generated automatically for you. Usually the generated name is pascal case, plural. `Users`, `UsersVotes`.

Here are some examples showcasing the naming conventions:

```sh
$ cargo loco generate model movies long_title:string user:references
$ cargo loco generate model movies long_title:string added_by:references:users director:references
```

* model name in plural: `movies`
* reference user is in singular: `user:references`
* refecence director is in singular: `director:references`
* reference added_by is in singular, the referenced model is a model and is plural: `added_by:references:users`
* column name in snake case: `long_title:string`

### Naming migrations
Expand Down
17 changes: 6 additions & 11 deletions docs-site/static/styles/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -618,33 +618,28 @@ a.active {

@media (min-width: 640px) {
.container {
max-width: 640px;
max-width: calc(640px - 1rem);
}
}

@media (min-width: 768px) {
.container {
max-width: 768px;
max-width: calc(768px - 2rem);
}
}

@media (min-width: 1024px) {
.container {
max-width: 1024px;
max-width: calc(1024px - 6rem);
}
}

@media (min-width: 1280px) {
.container {
max-width: 1280px;
max-width: calc(1280px - 8rem);
}
}

@media (min-width: 1536px) {
.container {
max-width: 1536px;
}
}

.prose {
color: var(--tw-prose-body);
Expand Down Expand Up @@ -1005,7 +1000,7 @@ a.active {
--tw-prose-body: var(--foreground);
--tw-prose-headings: var(--foreground);
--tw-prose-lead: #4b5563;
--tw-prose-links: #111827;
--tw-prose-links: var(--foreground);
--tw-prose-bold: #111827;
--tw-prose-counters: #6b7280;
--tw-prose-bullets: #d1d5db;
Expand All @@ -1015,7 +1010,7 @@ a.active {
--tw-prose-captions: #6b7280;
--tw-prose-kbd: #111827;
--tw-prose-kbd-shadows: 17 24 39;
--tw-prose-code: #111827;
--tw-prose-code: var(--foreground);
--tw-prose-pre-code: #e5e7eb;
--tw-prose-pre-bg: #1f2937;
--tw-prose-th-borders: #d1d5db;
Expand Down
2 changes: 1 addition & 1 deletion docs-site/templates/docs/page.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
{% block content %}
<div role="document">
<div class="bg-redrust text-background dark:bg-zinc-900">
<div class="container xl:max-w-[80rem] xl:mx-auto">
<div class="container">
<aside class="w-full">
{{ macros_sidebar::docs_sidebar(current_section=current_section) }}
</aside>
Expand Down
2 changes: 1 addition & 1 deletion docs-site/templates/macros/header.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% macro header(current_section) %}
<header
class=" sticky top-0 z-50 w-full border-border/40 backdrop-blur bg-background">
<div class="container relative flex h-14 md:grid md:grid-cols-[240px_minmax(0,1fr)] xl:max-w-[80rem] xl:mx-auto">
<div class="container relative flex h-14 md:grid md:grid-cols-[240px_minmax(0,1fr)]">
<div class="mr-4 hidden sm:flex">
<a class="flex mr-4 items-center space-x-2" href="/">
<img src="/icon.svg" width="30px" />
Expand Down
1 change: 1 addition & 0 deletions examples/demo/Cargo.lock

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

Loading

0 comments on commit 24e952b

Please sign in to comment.