github.com/c3pm-labs/c3pm@v0.3.0/ctpm/init.go (about) 1 package ctpm 2 3 import ( 4 "bufio" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "strings" 10 "text/template" 11 12 "github.com/mitchellh/go-spdx" 13 14 "github.com/c3pm-labs/c3pm/config" 15 ) 16 17 type InitOptions struct { 18 NoTemplate bool 19 } 20 21 var InitDefaultOptions = InitOptions{ 22 NoTemplate: false, 23 } 24 25 func Init(pc *config.ProjectConfig, opt InitOptions) error { 26 err := os.MkdirAll(pc.ProjectRoot, os.ModePerm) // umask will take care of permissions 27 if err != nil { 28 return err 29 } 30 if pc.Manifest.License != "UNLICENSED" { 31 err = generateLicenseFile(pc) 32 if err != nil { 33 return err 34 } 35 } 36 if !opt.NoTemplate { 37 err = generateReadMe(pc) 38 if err != nil { 39 return err 40 } 41 if pc.Manifest.Type == "executable" { 42 err := saveExecutableTemplate(pc) 43 if err != nil { 44 return err 45 } 46 } else { 47 err := saveLibraryTemplate(pc) 48 if err != nil { 49 return err 50 } 51 } 52 } 53 54 return pc.Save() 55 } 56 57 const execTemplate = `#include <iostream> 58 59 int main() { 60 std::cout << "Hello c3pm!" << std::endl; 61 return 0; 62 }` 63 const includeTemplate = `#pragma once 64 65 void hello();` 66 const libTemplate = `#include <iostream> 67 #include "{{.Name}}.hpp" 68 69 void hello() { 70 std::cout << "Hello c3pm!" << std::endl; 71 }` 72 const readMeTemplate = `# {{.Name}} 73 74 A new C++ project. 75 76 ## Getting Started 77 78 This project is a starting point for a C++ project. 79 80 A few helpful commands to get you started if this is your first time using c3pm: 81 82 ### Building your project 83 ` + "```" + `shell 84 $ ctpm build 85 ` + "```" + ` 86 87 ### Add a package 88 ` + "```" + `shell 89 $ ctpm add <package> 90 ` + "```" + ` 91 92 ### Publishing your project 93 ` + "```" + `shell 94 $ ctpm publish 95 ` + "```" + ` 96 97 For help getting started with c3pm, view our 98 [online documentation](https://docs.c3pm.io/), which offers tutorials, samples and 99 a list of all available commands. 100 ` 101 102 func generateReadMe(pc *config.ProjectConfig) error { 103 t := template.Must(template.New("readMeTemplate").Parse(readMeTemplate)) 104 f, err := os.Create(filepath.Join(pc.ProjectRoot, "README.md")) 105 if err != nil { 106 return err 107 } 108 return t.ExecuteTemplate(f, "readMeTemplate", pc.Manifest) 109 } 110 111 func generateLicenseFile(pc *config.ProjectConfig) error { 112 lic, err := spdx.License(pc.Manifest.License) 113 if err != nil { 114 return err 115 } 116 if len(lic.Text) == 0 { 117 return fmt.Errorf("generate %s", lic.Name) 118 } 119 return ioutil.WriteFile(filepath.Join(pc.ProjectRoot, "LICENSE"), []byte(lic.Text), 0644) 120 } 121 122 func yesOrNo(label string) string { 123 choices := "y/n" 124 125 r := bufio.NewReader(os.Stdin) 126 var s string 127 128 _, err := fmt.Fprintf(os.Stderr, "%s (%s) ", label, choices) 129 if err != nil { 130 return "" 131 } 132 s, _ = r.ReadString('\n') 133 s = strings.TrimSpace(s) 134 if s == "" { 135 return "n" 136 } 137 s = strings.ToLower(s) 138 return s 139 } 140 141 func overrideDirectory(label string, path string) bool { 142 answer := "" 143 if _, err := os.Stat(path); !os.IsNotExist(err) { 144 answer = yesOrNo(label) 145 } 146 if answer == "n" || answer == "no" { 147 return false 148 } 149 if answer == "y" || answer == "yes" { 150 if err := os.RemoveAll(path); err != nil { 151 return false 152 } 153 } 154 if err := os.Mkdir(path, os.ModePerm); err != nil { 155 return false 156 } 157 return true 158 } 159 160 func saveExecutableTemplate(pc *config.ProjectConfig) error { 161 if status := overrideDirectory( 162 "You already have a src directory, do you want to override it?", 163 filepath.Join(pc.ProjectRoot, "src")); status { 164 return ioutil.WriteFile(filepath.Join(pc.ProjectRoot, "src", "main.cpp"), []byte(execTemplate), 0644) 165 } 166 return nil 167 } 168 169 func saveLibraryTemplate(pc *config.ProjectConfig) error { 170 t := template.Must(template.New("libTemplate").Parse(libTemplate)) 171 var f *os.File = nil 172 var err error = nil 173 if status := overrideDirectory( 174 "You already have a src directory, do you want to override it?", 175 filepath.Join(pc.ProjectRoot, "src")); status { 176 f, err = os.Create(filepath.Join(pc.ProjectRoot, "src", pc.Manifest.Name+".cpp")) 177 if err != nil { 178 return err 179 } 180 defer f.Close() 181 182 if err := t.ExecuteTemplate(f, "libTemplate", pc.Manifest); err != nil { 183 return err 184 } 185 } 186 187 if status := overrideDirectory( 188 "You already have a include directory, do you want to override it?", 189 filepath.Join(pc.ProjectRoot, "include")); status { 190 f, err = os.Create(filepath.Join(pc.ProjectRoot, "include", pc.Manifest.Name+".hpp")) 191 if err != nil { 192 return err 193 } 194 defer f.Close() 195 196 _, err = f.Write([]byte(includeTemplate)) 197 } 198 return err 199 }