Skip to content

Commit e028d24

Browse files
Default pgroll pull to write in YAML format and add a --json flag (#810)
Make `pgroll pull` default to pulling migrations in YAML format, rather than JSON. Add a `--json` flag to the `pull` command to allow users to output migrations in JSON format instead of YAML. We want to default to YAML as the output format, but provide an option for users to choose JSON if they prefer it. This is useful for users who may want to integrate the output with other tools or systems that work better with JSON.
1 parent f1c7805 commit e028d24

File tree

4 files changed

+59
-21
lines changed

4 files changed

+59
-21
lines changed

cli-definition.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@
102102
"use": "pull <target directory>",
103103
"example": "",
104104
"flags": [
105+
{
106+
"name": "json",
107+
"shorthand": "j",
108+
"description": "output each migration in JSON format instead of YAML",
109+
"default": "false"
110+
},
105111
{
106112
"name": "with-prefixes",
107113
"shorthand": "p",

cmd/pull.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ import (
1414
func pullCmd() *cobra.Command {
1515
opts := map[string]string{
1616
"p": "prefix each migration filename with its position in the schema history",
17+
"j": "output each migration in JSON format instead of YAML",
1718
}
18-
var withPrefixes bool
19+
var withPrefixes, useJSON bool
1920

2021
pullCmd := &cobra.Command{
2122
Use: "pull <target directory>",
@@ -51,7 +52,7 @@ func pullCmd() *cobra.Command {
5152
if withPrefixes {
5253
prefix = fmt.Sprintf("%04d", i+1) + "_"
5354
}
54-
err := mig.WriteToFile(targetDir, prefix)
55+
err := mig.WriteToFile(targetDir, prefix, useJSON)
5556
if err != nil {
5657
return fmt.Errorf("failed to write migration %q: %w", mig.Migration.Name, err)
5758
}
@@ -61,6 +62,7 @@ func pullCmd() *cobra.Command {
6162
}
6263

6364
pullCmd.Flags().BoolVarP(&withPrefixes, "with-prefixes", "p", false, opts["p"])
65+
pullCmd.Flags().BoolVarP(&useJSON, "json", "j", false, opts["j"])
6466

6567
return pullCmd
6668
}

docs/cli/pull.mdx

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Pull
3-
description: Pull the complete schema history of applied migrations from the target database and write the migrations to disk.
3+
description: Pull migrations from the target database into a local migrations directory
44
---
55

66
## Command
@@ -11,17 +11,17 @@ Assuming that all [example migrations](https://github.com/xataio/pgroll/tree/mai
1111
$ pgroll pull migrations/
1212
```
1313

14-
will write the complete schema history as `.json` files to the `migrations/` directory:
14+
will write the complete schema history as `.yaml` files to the `migrations/` directory:
1515

1616
```
1717
$ ls migrations/
1818
19-
01_create_tables.json
20-
02_create_another_table.json
21-
03_add_column_to_products.json
22-
04_rename_table.json
23-
05_sql.json
24-
06_add_column_to_sql_table.json
19+
01_create_tables.yaml
20+
02_create_another_table.yaml
21+
03_add_column_to_products.yaml
22+
04_rename_table.yaml
23+
05_sql.yaml
24+
06_add_column_to_sql_table.yaml
2525
...
2626
```
2727

@@ -30,15 +30,19 @@ The command takes an optional `--with-prefixes` flag which will write each filen
3030
```
3131
$ ls migrations/
3232
33-
0001_01_create_tables.json
34-
0002_02_create_another_table.json
35-
0003_03_add_column_to_products.json
36-
0004_04_rename_table.json
37-
0005_05_sql.json
38-
0006_06_add_column_to_sql_table.json
33+
0001_01_create_tables.yaml
34+
0002_02_create_another_table.yaml
35+
0003_03_add_column_to_products.yaml
36+
0004_04_rename_table.yaml
37+
0005_05_sql.yaml
38+
0006_06_add_column_to_sql_table.yaml
3939
...
4040
```
4141

4242
The `--with-prefixes` flag ensures that files are sorted lexicographically by their time of application.
4343

44-
If the directory specified as the required argument to `pgroll pull` does not exist, `pgroll pull` will create it.
44+
Use the `--json` flag to pull migrations in JSON format rather than YAML.
45+
46+
If the target directory given to `pgroll pull` does not exist, `pgroll pull` will create it.
47+
48+
If the target directory is empty, `pgroll pull` will pull all migrations from the target database. If the target directory contains migration files, `pgroll pull` will pull only those migrations that don't already exist in the directory.

pkg/state/history.go

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ import (
66
"context"
77
"encoding/json"
88
"fmt"
9+
"io"
910
"os"
1011
"path/filepath"
1112
"time"
1213

1314
"github.com/lib/pq"
15+
"sigs.k8s.io/yaml"
1416

1517
"github.com/xataio/pgroll/pkg/migrations"
1618
)
@@ -63,14 +65,20 @@ func (s *State) SchemaHistory(ctx context.Context, schema string) ([]Migration,
6365
}
6466

6567
// WriteToFile writes the migration to a file in `targetDir`, prefixing the
66-
// filename with `prefix`.
67-
func (m *Migration) WriteToFile(targetDir, prefix string) error {
68+
// filename with `prefix`. The output format defaults to YAML, but can
69+
// be changed to JSON by setting `useJSON` to true.
70+
func (m *Migration) WriteToFile(targetDir, prefix string, useJSON bool) error {
6871
err := os.MkdirAll(targetDir, 0o755)
6972
if err != nil {
7073
return err
7174
}
7275

73-
fileName := fmt.Sprintf("%s%s.json", prefix, m.Migration.Name)
76+
suffix := "yaml"
77+
if useJSON {
78+
suffix = "json"
79+
}
80+
81+
fileName := fmt.Sprintf("%s%s.%s", prefix, m.Migration.Name, suffix)
7482
filePath := filepath.Join(targetDir, fileName)
7583

7684
file, err := os.Create(filePath)
@@ -79,8 +87,26 @@ func (m *Migration) WriteToFile(targetDir, prefix string) error {
7987
}
8088
defer file.Close()
8189

82-
encoder := json.NewEncoder(file)
90+
if useJSON {
91+
return m.writeAsJSON(file)
92+
} else {
93+
return m.writeAsYAML(file)
94+
}
95+
}
96+
97+
func (m *Migration) writeAsJSON(w io.Writer) error {
98+
encoder := json.NewEncoder(w)
8399
encoder.SetIndent("", " ")
84100

85101
return encoder.Encode(m.Migration)
86102
}
103+
104+
func (m *Migration) writeAsYAML(w io.Writer) error {
105+
yml, err := yaml.Marshal(m.Migration)
106+
if err != nil {
107+
return err
108+
}
109+
110+
_, err = w.Write(yml)
111+
return err
112+
}

0 commit comments

Comments
 (0)