// CompileHTML handles copy of assets, compression, and calling the Frala plugin func CompileHTML() error { var compileError error // Define compileError as an error if codeutilsShared.IsDir("src/html") { // If src/html is a valid directory copyError := codeutilsShared.CopyDirectory("src/html", "tests/design") // Copy the directory and its contents if copyError == nil { // If there was no issues copying the src/html or the index.html var htmlFiles []string // Define htmlFiles as an array of strings that'll coorespond with file names htmlFiles, compileError = codeutilsShared.GetFilesContains("tests/design", ".html") // Get all the HTML files from tests/design, setting any error to htmlFilesReadError if compileError == nil { // If there was no issue getting .html files in tests/design if projectConfig.HTML.EnableFrala { // If we are using Frala FralaParser("tests/design", htmlFiles) // Parse all the HTML in tests/design with Frala, this will also automatically compress the content os.RemoveAll("tests/design/fragments") // Ensure leftover fragments directory is removed } else { CompressHTML("tests/design", htmlFiles) // Compress all the HTML files in the root of tests/design without parsing through Frala } } } else { // If there was an issue copying the HTML compileError = copyError // Assign compileError to the copyError } } else { // If the src/html folder doesn't exist compileError = errors.New("html" + dirDoesNotExistInSrc) } return compileError }
// CompileGo analyzes the Go configuration and determine what binaries need to be compiled and from what source func CompileGo() error { var compileError error if codeutilsShared.ExecutableExists("go") { // If the go executable exists if codeutilsShared.IsDir("src/go") || projectConfig.Go.CompileFromRoot { // If the src/go directory exists or we're compiling from root if len(projectConfig.Go.Branches) == 0 { // If there aren't branches projectConfig.Go.Branches["root"] = codeutilsShared.GoBranchOptions{ // Add a "root" branch BinaryName: lowercaseProjectName, // Set BinaryName to lowercaseProjectName SourcesToInclude: []string{"src/go"}, // Compile all the things! } } for goBranchName, goBranchOptions := range projectConfig.Go.Branches { // For each Go branch option in Branches fmt.Println("Compiling branch " + goBranchName) GoBranchCompiler(goBranchOptions) // Compile the Branch } } else { // If the src/go directory does not exist compileError = errors.New("go " + dirDoesNotExistInSrc) } } else { // If go is not installed compileError = errors.New("go" + executableNotInstalled) } return compileError }
// CompileLESS compiles individual branches of LESS (each branch having ability to pass custom options) func CompileLESS() error { var compileError error if codeutilsShared.ExecutableExists("lessc") { // If the lessc executable exists if codeutilsShared.IsDir("src/less") { // If the src/less directory exists if len(projectConfig.LESS.Branches) == 0 { // If there aren't branches projectConfig.LESS.Branches["root"] = codeutilsShared.LESSBranchOptions{ // Add a "root" branch FileName: lowercaseProjectName + ".css", // Set Filename to lowercaseProjectName.css UseGlob: true, } } for lessBranchName, lessBranchOptions := range projectConfig.LESS.Branches { // For each Go branch option in Branches fmt.Println("Compiling branch " + lessBranchName) LESSBranchCompiler(lessBranchOptions) // Compile the Branch } } else { // If the src/go directory does not exist compileError = errors.New("less" + dirDoesNotExistInSrc) } } else { // If lessc executable doesn't exist compileError = errors.New("lessc" + executableNotInstalled) } return compileError }
// CompressHTML compresses the HTML files provided func CompressHTML(directory string, files []string) error { var compressError error htmlMinifierFlags := []string{ // Oh god I am so sorry for all the flags "--case-sensitive", // Ensure case sensitivity for custom HTML tags "--collapse-whitespace", // Collapse any whitespace "--remove-comments", // Remove comments "--remove-comments-from-cdata", // Same as above but from CDATA "--remove-redundant-attributes", // Fix your damn HTML, no need for redundancies "--remove-script-type-attributes", // Remove script type attribute "--remove-style-link-type-attributes", // Remove style and link tag type attribute } if codeutilsShared.ExecutableExists("html-minifier") { // If the minifier exists if codeutilsShared.IsDir(directory) { // If the directory provided indeed exists if len(files) != 0 { // If there was files passed replacer := regexp.MustCompile(`"{{?\s?(type=")?\s(\w+)?\s(src="[^>]+)`) // Search for instances of messed up quoting due to html-minifier for _, file := range files { // For each file in files fmt.Println("Compressing " + file + " in " + directory) file = directory + "/" + file // Prepend the directory fileSpecificFlags := htmlMinifierFlags // Assign fileSpecificFlags flags as initially the same as htmlMinifierFlags fileSpecificFlags = append(fileSpecificFlags, []string{file}...) // Specify file to minify compressedFileContent := codeutilsShared.ExecCommand("html-minifier", fileSpecificFlags, false) // Run the html-minifier fixedContent := replacer.ReplaceAllString(compressedFileContent, `"{{ $1$2" $3 }}"`) // $1 is type, $2 is the type value, $3 is src+lang codeutilsShared.WriteOrUpdateFile(file, []byte(fixedContent), 0755) // Update the file contents } } else { // If there was no files passed fmt.Println("No files provided.") } } else { // If the directory provided is not, in fact, a directory fmt.Println(directory + " is not a directory.") } } else { // If the minifier does not exist compressError = errors.New("html-minifier" + executableNotInstalled) } return compressError }
// CompileTypeScript compiles Typescript into Javascript and ensure JavaScript is minified and optimized func CompileTypeScript() error { var compileError error if codeutilsShared.ExecutableExists("tsc") { // If the tsc executable exists if codeutilsShared.IsDir("src/typescript") { // If src/typescript is a valid directory if !strings.HasPrefix(projectConfig.TypeScript.Target, "ES") { // If it either an empty string or does not begin with ES projectConfig.TypeScript.Target = "ES5" // Default to ES5 } typescriptFileName, _ := codeutilsShared.FindClosestFile("src/typescript/" + lowercaseProjectName + ".ts") // Define typescriptFileName as the closest file name to the one we're providing baseFileName := strings.Replace(filepath.Base(typescriptFileName), ".ts", "", -1) // Set baseFileName to typescript file name but with .ts removed typescriptCompileFlags := []string{ // Define typescriptCompileFlags as the following options "--declaration", // Create a declaration file "--forceConsistentCasingInFileNames", // Enforce consistency in file names "--noFallthroughCasesInSwitch", // Disallow fallthrough cases in switches "--noImplicitReturns", // Disallow implicit returns "--outFile", "build/" + baseFileName + ".js", // Output a single JS file in the build dir "--removeComments", // Remove comments "--target", projectConfig.TypeScript.Target, // Set the target typescriptFileName, // Append the .ts name } commandOutput := codeutilsShared.ExecCommand("tsc", typescriptCompileFlags, false) // Call execCommand and get its commandOutput if !strings.Contains(commandOutput, "error TS") { // If tsc did not report any errors if projectConfig.TypeScript.MinifyContent { // If we should minify the content minifyFailure := MinifyJavaScript() // Call the minification func, set any error to minifyFailure if minifyFailure == nil { // If there was no error minifying minifyFileName := baseFileName + ".min.js" if projectConfig.TypeScript.UseLibreJSHeader && (projectConfig.TypeScript.LibreJSLicense != "") { // If we should use the LibreJSHeader and the license value is set var finalMinifiedContent string // Define finalMinifiedContent as the content we get from AddLicense finalMinifiedContent, compileError = librejsgopher.AddLicense(projectConfig.TypeScript.LibreJSLicense, "build/"+minifyFileName, true) // Add the requested license to the JS file, return content if (compileError == nil) && projectConfig.TypeScript.UniqueHash { // If there was no issue adding the license and we should be using a unique hash uniqueFileName := baseFileName + "-" + codeutilsShared.Sha512Sum(finalMinifiedContent, 1)[0:12] + ".min.js" // Append first 12 characters of hash os.Rename("build/"+minifyFileName, "build/"+uniqueFileName) // Move the file to one with a unique file name minifyFileName = uniqueFileName // Change minifyFileName to uniqueName } } if projectConfig.UsesTests { // If we are using tests compileError = codeutilsShared.CopyFile("build/"+baseFileName+".js", "tests/design/js/"+baseFileName+".js") // Copy over the non-minified JS to the test js folder compileError = codeutilsShared.CopyFile("build/"+minifyFileName, "tests/design/js/"+minifyFileName) // Copy over the minified JS from build to the test js folder } } else { // If there was an error minifying compileError = minifyFailure // Set compileError to the minifyFailure } } } else { // If tsc did report errors compileError = errors.New(commandOutput) // Set compileError to the commandOutput } } else { // If src/typescript is not a valid directory compileError = errors.New("typescript" + dirDoesNotExistInSrc) } } else { // If the typescript compiler is not installed on this system compileError = errors.New("tsc" + executableNotInstalled) } return compileError }