215 lines
6.6 KiB
Go
215 lines
6.6 KiB
Go
package main
|
|
|
|
import (
|
|
_ "embed"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
)
|
|
|
|
//go:embed templates/vue/AboutView.vue.tmpl
|
|
var aboutViewTemplate string
|
|
|
|
//go:embed templates/vue/HomeView.vue.tmpl
|
|
var homeViewTemplate string
|
|
|
|
func setupWebapp(name string) error {
|
|
fmt.Println("Setting up webapp with Vue 3, TypeScript, Vue Router, Pinia, and ESLint with Prettier")
|
|
cmd := exec.Command("npm", "create", "vue@latest", "--", "--ts", "--router", "--pinia", "--eslint-with-prettier", name)
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
return fmt.Errorf("error setting up webapp | %w", err)
|
|
}
|
|
|
|
fmt.Println("Switching to the new directory")
|
|
// cd into the new directory
|
|
err = os.Chdir(name)
|
|
if err != nil {
|
|
return fmt.Errorf("error changing directory | %w", err)
|
|
}
|
|
|
|
fmt.Println("Installing base dependencies")
|
|
// install all dependencies and format the code
|
|
cmd = exec.Command("npm", "install", "&&", "npm", "run", "format")
|
|
err = cmd.Run()
|
|
if err != nil {
|
|
return fmt.Errorf("error changing directory | %w", err)
|
|
}
|
|
|
|
// make src/assets/base.css and src/assets/main.css mostly empty files
|
|
err = os.WriteFile("src/assets/base.css", []byte(""), 0644)
|
|
if err != nil {
|
|
return fmt.Errorf("error writing base.css | %w", err)
|
|
}
|
|
err = os.WriteFile("src/assets/main.css", []byte("@import './base.css';"), 0644)
|
|
if err != nil {
|
|
return fmt.Errorf("error writing main.css | %w", err)
|
|
}
|
|
|
|
fmt.Println("Setting up Tailwind CSS")
|
|
err = setupTailwind()
|
|
if err != nil {
|
|
return fmt.Errorf("error setting up tailwind | %w", err)
|
|
}
|
|
|
|
// clean up the default example files
|
|
err = removeListOfFiles([]string{
|
|
"src/components/HelloWorld.vue",
|
|
"src/components/TheWelcome.vue",
|
|
"src/components/WelcomeItem.vue",
|
|
"src/views/AboutView.vue", // replace with new AboutView.vue
|
|
"src/components/icons/IconCommunity.vue",
|
|
"src/components/icons/IconDocumentation.vue",
|
|
"src/components/icons/IconEcosystem.vue",
|
|
"src/components/icons/IconSupport.vue",
|
|
"src/components/icons/IconTooling.vue",
|
|
"src/assets/logo.svg",
|
|
})
|
|
|
|
// create a new about view from the aboutViewTemplate
|
|
err = os.WriteFile("src/views/AboutView.vue", []byte(aboutViewTemplate), 0644)
|
|
if err != nil {
|
|
return fmt.Errorf("error writing new AboutView.vue | %w", err)
|
|
}
|
|
// create a new home view from the homeViewTemplate
|
|
err = os.WriteFile("src/views/HomeView.vue", []byte(homeViewTemplate), 0644)
|
|
if err != nil {
|
|
return fmt.Errorf("error writing new HomeView.vue | %w", err)
|
|
}
|
|
|
|
fmt.Println("Exiting the new directory")
|
|
err = os.Chdir("..")
|
|
if err != nil {
|
|
return fmt.Errorf("error changing directory | %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func setupTailwind() error {
|
|
// check that there is a vite.config.ts file and a package.json file
|
|
_, err := os.Stat("vite.config.ts")
|
|
if err != nil {
|
|
return fmt.Errorf("error checking for vite.config.ts | %w", err)
|
|
}
|
|
_, err = os.Stat("package.json")
|
|
if err != nil {
|
|
return fmt.Errorf("error checking for package.json | %w", err)
|
|
}
|
|
|
|
cmd := exec.Command("npm", "install", "tailwindcss", "@tailwindcss/vite")
|
|
err = cmd.Run()
|
|
if err != nil {
|
|
return fmt.Errorf("error installing tailwindcss | %w", err)
|
|
}
|
|
|
|
// In the vite.config.ts insert the following code after the last import statement `import tailwindcss from '@tailwindcss/vite'`
|
|
err = insertImportStatement("import tailwindcss from '@tailwindcss/vite'", "vite.config.ts")
|
|
if err != nil {
|
|
return fmt.Errorf("error inserting import statement | %w", err)
|
|
}
|
|
|
|
// In the vite.config.ts insert the following code after the last plugin usage `tailwindcss(),`
|
|
err = insertPluginUsage(" tailwindcss(),", "vite.config.ts")
|
|
if err != nil {
|
|
return fmt.Errorf("error inserting plugin usage | %w", err)
|
|
}
|
|
|
|
// in the base.css file add an @import statement for tailwind
|
|
// check that './src/assets/base.css' exists
|
|
_, err = os.Stat("./src/assets/base.css")
|
|
if err != nil {
|
|
return fmt.Errorf("error checking for base.css | %w", err)
|
|
}
|
|
err = insertAtTopLineOfFile("@import \"tailwindcss\";", "./src/assets/base.css")
|
|
if err != nil {
|
|
return fmt.Errorf("error inserting import statement | %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func insertImportStatement(importStatement string, filename string) error {
|
|
fileContent, err := os.ReadFile(fmt.Sprintf(".%c%s", os.PathSeparator, filename))
|
|
if err != nil {
|
|
return fmt.Errorf("error reading %s | %w", filename, err)
|
|
}
|
|
|
|
fileLines := strings.Split(strings.ReplaceAll(string(fileContent), "\r\n", "\n"), "\n")
|
|
lastImportIndex := -1
|
|
// finds the last import statement in the file and appends after that one
|
|
for i, line := range fileLines {
|
|
if strings.HasPrefix(line, "import") {
|
|
lastImportIndex = i
|
|
}
|
|
}
|
|
if lastImportIndex != -1 {
|
|
fileLines = append(fileLines[:lastImportIndex+1], append([]string{importStatement}, fileLines[lastImportIndex+1:]...)...)
|
|
} else {
|
|
// add the import to the top of the file
|
|
fileLines = append([]string{importStatement}, fileLines...)
|
|
}
|
|
|
|
err = os.WriteFile(filename, []byte(strings.Join(fileLines, "\n")), 0644)
|
|
if err != nil {
|
|
return fmt.Errorf("error writing vite.config.ts | %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func insertPluginUsage(pluginUsage string, filename string) error {
|
|
fileContent, err := os.ReadFile(fmt.Sprintf(".%c%s", os.PathSeparator, filename))
|
|
if err != nil {
|
|
return fmt.Errorf("error reading %s | %w", filename, err)
|
|
}
|
|
|
|
fileLines := strings.Split(strings.ReplaceAll(string(fileContent), "\r\n", "\n"), "\n")
|
|
startOfPluginsIndex := -1
|
|
// finds the `plugins: [` line in the file and appends after that one
|
|
for i, line := range fileLines {
|
|
if strings.Contains(line, "plugins: [") {
|
|
startOfPluginsIndex = i
|
|
}
|
|
}
|
|
if startOfPluginsIndex != -1 {
|
|
fileLines = append(fileLines[:startOfPluginsIndex+1], append([]string{pluginUsage}, fileLines[startOfPluginsIndex+1:]...)...)
|
|
} else {
|
|
// add the import to the top of the file
|
|
fileLines = append([]string{pluginUsage}, fileLines...)
|
|
}
|
|
|
|
err = os.WriteFile(filename, []byte(strings.Join(fileLines, "\n")), 0644)
|
|
if err != nil {
|
|
return fmt.Errorf("error writing vite.config.ts | %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func insertAtTopLineOfFile(content string, filename string) error {
|
|
fileContent, err := os.ReadFile(fmt.Sprintf(".%c%s", os.PathSeparator, filename))
|
|
if err != nil {
|
|
return fmt.Errorf("error reading %s | %w", filename, err)
|
|
}
|
|
|
|
fileLines := strings.Split(strings.ReplaceAll(string(fileContent), "\r\n", "\n"), "\n")
|
|
fileLines = append([]string{content}, fileLines...)
|
|
|
|
err = os.WriteFile(filename, []byte(strings.Join(fileLines, "\n")), 0644)
|
|
if err != nil {
|
|
return fmt.Errorf("error writing vite.config.ts | %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func removeListOfFiles(files []string) error {
|
|
|
|
for _, file := range files {
|
|
err := os.Remove(file)
|
|
if err != nil {
|
|
return fmt.Errorf("error removing %s | %w", file, err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|