fix: journal:fix-headings runs from the application CLI
The command opens the database with lookupDB, as journal:image-variants does: without a published database it opens database.dsn, and without a DSN it names SUMMER_DATABASE__DSN.
This commit is contained in:
@@ -529,7 +529,7 @@ The export and import commands write JSON files (one per post slug), matching th
|
||||
| `journal:export-posts` | `--path` (default `journal-export`), `--dry-run` | Writes one JSON file per post, including non-default-locale translations, with a progress bar over the posts. Attachments are omitted. Ends with `Exported N posts to: <path>`. |
|
||||
| `journal:import-posts` | `--path` (default `journal-export`), `--force`, `--dry-run` | Creates posts from those files, one line per post; while the H1 setting is on, H1 headings are stored as H2 and the count is printed. Existing slugs are skipped unless `--force` updates them. Ends with `Results: N created, N updated, N skipped, N failed`. |
|
||||
| `journal:image-variants` | `--all` | Writes the thumbnails and WebP copies of featured images at `golem15.journal.image_widths` that are missing (with `--all`, checks every featured image) and prints `Checked N featured images, wrote N variants, skipped N.`, or `Every featured image has its variants.` |
|
||||
| `journal:fix-headings` | `--apply`, `--dry-run` (the default) | Converts H1 to H2 in stored post content (every locale) and category pillar text while the H1 setting is on, firing a record event per changed post and category. Prints `Would convert N H1 headings in N posts and N categories. Run with --apply to save.`, `Converted N H1 headings in N posts and N categories.` or `No H1 headings found in post or category content.`; refuses with exit code 1 while the setting is off. |
|
||||
| `journal:fix-headings` | `--apply`, `--dry-run` (the default) | Converts H1 to H2 in stored post content (every locale) and category pillar text while the H1 setting is on, firing a record event per changed post and category. Prints `Would convert N H1 headings in N posts and N categories. Run with --apply to save.`, `Converted N H1 headings in N posts and N categories.` or `No H1 headings found in post or category content.`; refuses with exit code 1 while the setting is off. Runs from the application CLI like `journal:image-variants`: without a published database it opens `database.dsn` (`SUMMER_DATABASE__DSN`). |
|
||||
| `journal:reindex` | `--fresh` | Syncs every post into the search index in batches of 200: published posts are upserted, the others removed. `--fresh` first drops the collection and recreates it from the schema. Refuses, sending nothing, when the engine is not configured or `search_use_typesense` is off. Ends with `Reindexed: N synced, N removed, N failed` and exits non-zero on any failure. |
|
||||
|
||||
```sh
|
||||
|
||||
@@ -2,7 +2,6 @@ package console
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.golem15.com/golem15/sm-journal-plugin/classes"
|
||||
@@ -13,8 +12,10 @@ import (
|
||||
// FixHeadings is journal:fix-headings: it converts H1 to H2 in stored
|
||||
// Journal rich text (post content in every locale and category pillar text)
|
||||
// while the Journal H1 setting is on. It is a dry run unless --apply is
|
||||
// given; with the setting off it refuses with exit code 1. Its output (UI-SPEC
|
||||
// C27 with the P33-54 wording, English only):
|
||||
// given; with the setting off it refuses with exit code 1. It runs from the
|
||||
// generated application CLI: without a published database it opens
|
||||
// database.dsn (lookupDB) and, without one, names SUMMER_DATABASE__DSN. Its
|
||||
// output (UI-SPEC C27 with the P33-54 wording, English only):
|
||||
//
|
||||
// - dry run: "Would convert :count H1 headings in :posts posts and :categories categories. Run with --apply to save."
|
||||
// - applied: "Converted :count H1 headings in :posts posts and :categories categories."
|
||||
@@ -47,10 +48,11 @@ journal_fix_headings runs the same conversion.`,
|
||||
{Command: "journal:fix-headings --apply", Description: "Convert them and save"},
|
||||
},
|
||||
Run: func(ctx context.Context, in bonfire.Input, out bonfire.Output) error {
|
||||
db := mustDB(app)
|
||||
if db == nil {
|
||||
return errors.New("journal: database is not configured")
|
||||
db, done, err := lookupDB(ctx, app)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer done()
|
||||
if !classes.EffectiveH1ToH2(ctx, db, appConfig(app)) {
|
||||
out.Error(classes.H1ConversionOffText)
|
||||
return bonfire.Reported(classes.ErrH1ConversionOff)
|
||||
|
||||
@@ -97,3 +97,50 @@ func TestImageVariantsCommandCLI(t *testing.T) {
|
||||
t.Fatalf("the CLI's WebP %s is not in the bucket: %v", variants[1].WebPKey, err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestFixHeadingsCommandCLI pins L1 WR-01 (D-50): journal:fix-headings in
|
||||
// the generated CLI, where no database is published: without a DSN it
|
||||
// names the setting, with one it opens database.dsn and prints the dry run.
|
||||
func TestFixHeadingsCommandCLI(t *testing.T) {
|
||||
if testShort() {
|
||||
t.Skip("Postgres")
|
||||
}
|
||||
env := newPostsEnv(t)
|
||||
var name string
|
||||
if err := env.gdb.Raw(`SELECT current_database()`).Scan(&name).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
u, err := url.Parse(adminDSN)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
u.Path = "/" + name
|
||||
post := models.Post{Title: "Cli heading", Slug: "cli-heading", Content: "<h1>A</h1><p>x</p>", ContentHTML: "<h1>A</h1><p>x</p>"}
|
||||
if err := env.gdb.Create(&post).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
run := func(environ ...string) (int, string) {
|
||||
t.Helper()
|
||||
cfg, err := compass.Open(compass.Options{Dir: t.TempDir(), Environ: append([]string{"SUMMER_ENV=development"}, environ...)})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
app := backpack.New(cfg)
|
||||
var buf strings.Builder
|
||||
root, err := bonfire.NewRootIO("summer", []bonfire.Command{console.FixHeadings(app)}, strings.NewReader(""), &buf, &buf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return bonfire.Execute(context.Background(), root, []string{"journal:fix-headings"}), buf.String()
|
||||
}
|
||||
if code, out := run(); code == 0 || !strings.Contains(out, "database is not configured (set SUMMER_DATABASE__DSN)") {
|
||||
t.Fatalf("without a DSN: %d\n%s", code, out)
|
||||
}
|
||||
code, out := run("SUMMER_DATABASE__DSN="+u.String(), "SUMMER_APP__KEY="+base64.StdEncoding.EncodeToString(bytes.Repeat([]byte("k"), 32)))
|
||||
if code != 0 || !strings.Contains(out, "Would convert 1 H1 headings in 1 posts and 0 categories. Run with --apply to save.") {
|
||||
t.Fatalf("journal:fix-headings from the CLI: %d\n%s", code, out)
|
||||
}
|
||||
if p := storedPost(t, env, post.ID); p.Content != "<h1>A</h1><p>x</p>" {
|
||||
t.Fatalf("the dry run wrote %q", p.Content)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user