1// Copyright 2018 The CUE Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cmd
16
17import (
18	"github.com/spf13/cobra"
19
20	"cuelang.org/go/internal/encoding"
21	"cuelang.org/go/internal/filetypes"
22)
23
24// newExportCmd creates and export command
25func newExportCmd(c *Command) *cobra.Command {
26	cmd := &cobra.Command{
27		Use:   "export",
28		Short: "output data in a standard format",
29		Long: `export evaluates the configuration found in the current
30directory and prints the emit value to stdout.
31
32Examples:
33Evaluated and emit
34
35	# a single file
36	cue export config.cue
37
38	# multiple files: these are combined at the top-level. Order doesn't matter.
39	cue export file1.cue foo/file2.cue
40
41	# all files within the "mypkg" package: this includes all files in the
42	# current directory and its ancestor directories that are marked with the
43	# same package.
44	cue export -p cloud
45
46	# the -p flag can be omitted if the directory only contains files for
47	# the "mypkg" package.
48	cue export
49
50Emit value:
51For CUE files, the generated configuration is derived from the top-level
52single expression, the emit value. For example, the file
53
54	// config.cue
55	arg1: 1
56	arg2: "my string"
57
58	{
59		a: arg1
60		b: arg2
61	}
62
63yields the following JSON:
64
65	{
66		"arg1": 1,
67		"a": 1,
68		"arg2": "my string",
69		"b": "my string"
70	}
71
72In absence of arguments, the current directory is loaded as a package instance.
73A package instance for a directory contains all files in the directory and its
74ancestor directories, up to the module root, belonging to the same package.
75If the package is not explicitly defined by the '-p' flag, it must be uniquely
76defined by the files in the current directory.
77
78
79Formats
80The following formats are recognized:
81
82json    output as JSON
83               Outputs any CUE value.
84
85text    output as raw text
86                The evaluated value must be of type string.
87
88yaml    output as YAML
89                Outputs any CUE value.
90`,
91
92		RunE: mkRunE(c, runExport),
93	}
94
95	addOutFlags(cmd.Flags(), true)
96	addOrphanFlags(cmd.Flags())
97	addInjectionFlags(cmd.Flags(), false)
98
99	cmd.Flags().Bool(string(flagEscape), false, "use HTML escaping")
100	cmd.Flags().StringArrayP(string(flagExpression), "e", nil, "export this expression only")
101
102	return cmd
103}
104
105func runExport(cmd *Command, args []string) error {
106	b, err := parseArgs(cmd, args, &config{outMode: filetypes.Export})
107	exitOnErr(cmd, err, true)
108
109	enc, err := encoding.NewEncoder(b.outFile, b.encConfig)
110	exitOnErr(cmd, err, true)
111	defer enc.Close()
112
113	iter := b.instances()
114	defer iter.close()
115	for iter.scan() {
116		v := iter.value()
117		err = enc.Encode(v)
118		exitOnErr(cmd, err, true)
119	}
120	exitOnErr(cmd, iter.err(), true)
121	return nil
122}
123