Skip to content

Commit 99f447e

Browse files
committed
add the actual extract command
1 parent 540975b commit 99f447e

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

cli/templateextract.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package cli
2+
3+
import (
4+
"archive/tar"
5+
"bytes"
6+
"fmt"
7+
"io"
8+
"os"
9+
"path/filepath"
10+
11+
"github.com/spf13/cobra"
12+
"golang.org/x/xerrors"
13+
14+
"github.com/coder/coder/cli/cliui"
15+
)
16+
17+
func tarBytesToTree(templateName string, raw []byte) error {
18+
err := os.Mkdir(templateName, 0700)
19+
20+
archiveReader := tar.NewReader(bytes.NewReader(raw))
21+
hdr, err := archiveReader.Next()
22+
for err != io.EOF {
23+
if hdr == nil { // some blog post indicated this could happen sometimes
24+
continue
25+
}
26+
filename := filepath.FromSlash(fmt.Sprintf("%s/%s", templateName, hdr.Name))
27+
switch hdr.Typeflag {
28+
case tar.TypeDir:
29+
err = os.Mkdir(filename, 0700)
30+
if err != nil {
31+
return xerrors.Errorf("exporting archived directory: %w", err)
32+
}
33+
case tar.TypeReg:
34+
f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0600)
35+
if err != nil {
36+
return xerrors.Errorf("unable to create archived file: %w", err)
37+
}
38+
fmt.Println("created file " + filename)
39+
40+
_, err = io.Copy(f, archiveReader)
41+
if err != nil {
42+
f.Close() // is this necessary?
43+
return xerrors.Errorf("error writing archive file: %w", err)
44+
}
45+
f.Close()
46+
}
47+
48+
hdr, err = archiveReader.Next()
49+
}
50+
return nil
51+
}
52+
53+
func templateExport() *cobra.Command {
54+
cmd := &cobra.Command{
55+
Use: "export <name>",
56+
Short: "Create a subdirectory named <name> and download the current template contents into it.",
57+
Args: cobra.ExactArgs(1),
58+
RunE: func(cmd *cobra.Command, args []string) error {
59+
var (
60+
templateName = args[0]
61+
)
62+
63+
raw, err := fetchTemplateArchiveBytes(cmd, templateName)
64+
if err != nil {
65+
return err
66+
}
67+
68+
// Stat the destination to ensure nothing exists already.
69+
stat, err := os.Stat(templateName)
70+
if stat != nil {
71+
return xerrors.Errorf("template file/directory already exists: %w", err)
72+
}
73+
fmt.Println("err = ", err)
74+
fmt.Println("templateName = ", templateName)
75+
76+
return tarBytesToTree(templateName, raw)
77+
},
78+
}
79+
80+
cliui.AllowSkipPrompt(cmd)
81+
82+
return cmd
83+
}

0 commit comments

Comments
 (0)