feat(vault): initialize fresh instances with public example notes
This commit is contained in:
1 parent
9ee7402c8e
commit
10fd6d8efb
24 files changed
+438
-14
No files matched your search
@@ -0,0 +1,34 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"rawmark/deploy"
|
||||
"rawmark/internal/auth"
|
||||
"rawmark/internal/store"
|
||||
"rawmark/internal/vault"
|
||||
)
|
||||
|
||||
// Keep bootstrap state out of user preferences so resetting settings cannot restore deleted examples.
|
||||
const examplesSetting = "bootstrap.examples"
|
||||
|
||||
func initializeExamples(v *vault.Vault, st *store.Store) error {
|
||||
_, done, err := st.Setting(examplesSetting)
|
||||
if err != nil || done {
|
||||
return err
|
||||
}
|
||||
setUp, err := auth.New(st).IsSetUp()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !setUp {
|
||||
examples, err := fs.Sub(deploy.Examples, "data/vault")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := v.SeedExamples(examples); err != nil {
|
||||
return fmt.Errorf("初始化示例笔记失败: %w", err)
|
||||
}
|
||||
}
|
||||
return st.SetSetting(examplesSetting, "1")
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"rawmark/deploy"
|
||||
"rawmark/internal/auth"
|
||||
"rawmark/internal/store"
|
||||
"rawmark/internal/vault"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestInitializeExamplesOnlyOnce(t *testing.T) {
|
||||
data := t.TempDir()
|
||||
v, err := vault.Open(filepath.Join(data, "vault"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
st, err := store.Open(filepath.Join(data, "rawmark.db"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := initializeExamples(v, st); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if ready, err := auth.New(st).IsSetUp(); err != nil || ready {
|
||||
t.Fatalf("examples must not initialize credentials: %v, %v", ready, err)
|
||||
}
|
||||
count := 0
|
||||
if err := fs.WalkDir(deploy.Examples, "data/vault", func(name string, entry fs.DirEntry, walkErr error) error {
|
||||
if walkErr != nil {
|
||||
return walkErr
|
||||
}
|
||||
if entry.IsDir() {
|
||||
return nil
|
||||
}
|
||||
if filepath.Ext(name) != ".md" {
|
||||
t.Fatalf("unexpected template file: %s", name)
|
||||
}
|
||||
count++
|
||||
rel, err := filepath.Rel("data/vault", name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := os.Stat(filepath.Join(v.Root(), rel)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if count != 7 {
|
||||
t.Fatalf("expected seven public sample notes, got %d", count)
|
||||
}
|
||||
// Deletion before password setup, settings reset, and process restart must not restore examples.
|
||||
entries, err := os.ReadDir(v.Root())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, entry := range entries {
|
||||
if entry.Name() != ".rawmark" {
|
||||
if err := os.RemoveAll(filepath.Join(v.Root(), entry.Name())); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := st.ResetPreferences(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := st.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
st, err = store.Open(filepath.Join(data, "rawmark.db"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer st.Close()
|
||||
if err := initializeExamples(v, st); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
entries, err = os.ReadDir(v.Root())
|
||||
if err != nil || len(entries) != 1 || entries[0].Name() != ".rawmark" {
|
||||
t.Fatalf("deleted examples were restored: %v, %v", entries, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitializeExamplesSkipsInitializedEmptyInstance(t *testing.T) {
|
||||
data := t.TempDir()
|
||||
v, err := vault.Open(filepath.Join(data, "vault"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
st, err := store.Open(filepath.Join(data, "rawmark.db"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer st.Close()
|
||||
if err := auth.New(st).Setup("synthetic-test-password"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := initializeExamples(v, st); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
entries, err := os.ReadDir(v.Root())
|
||||
if err != nil || len(entries) != 1 || entries[0].Name() != ".rawmark" {
|
||||
t.Fatalf("examples were added to an existing account: %v, %v", entries, err)
|
||||
}
|
||||
}
|
||||
@@ -129,6 +129,9 @@ func serve(parent context.Context, addr, dataDir, vaultDir, version string, font
|
||||
return false, err
|
||||
}
|
||||
defer st.Close()
|
||||
if err := initializeExamples(v, st); err != nil {
|
||||
return false, err
|
||||
}
|
||||
idx, err := search.Open(filepath.Join(dataDir, "index.db"), v)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
||||
Reference in new issue
Block a user