github.com/ernestokarim/closurer@v0.0.0-20130119214741-f245d086c750/gss/compile.go (about)

     1  package gss
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"os"
     7  	"os/exec"
     8  	"path"
     9  	"path/filepath"
    10  	"strings"
    11  
    12  	"github.com/ernestokarim/closurer/app"
    13  	"github.com/ernestokarim/closurer/cache"
    14  	"github.com/ernestokarim/closurer/config"
    15  )
    16  
    17  // Compiles the .gss files
    18  func Compile() error {
    19  	conf := config.Current()
    20  	target := conf.Gss.CurTarget()
    21  
    22  	// Output early if there's no GSS files.
    23  	if conf.Gss == nil {
    24  		if err := cleanRenamingMap(); err != nil {
    25  			return err
    26  		}
    27  
    28  		return nil
    29  	}
    30  
    31  	// Check if the cached version is still ok
    32  	modified := false
    33  	for _, input := range conf.Gss.Inputs {
    34  		if m, err := cache.Modified("compile", input.File); err != nil {
    35  			return err
    36  		} else if m {
    37  			modified = true
    38  			break
    39  		}
    40  	}
    41  
    42  	if !modified {
    43  		return nil
    44  	}
    45  
    46  	log.Println("Compiling GSS:", target.Name)
    47  
    48  	if err := cleanRenamingMap(); err != nil {
    49  		return err
    50  	}
    51  
    52  	// Prepare the list of non-standard functions.
    53  	funcs := []string{}
    54  	for _, f := range conf.Gss.Funcs {
    55  		funcs = append(funcs, "--allowed-non-standard-function")
    56  		funcs = append(funcs, f.Name)
    57  	}
    58  
    59  	// Prepare the renaming map args
    60  	renaming := []string{}
    61  	if target.Rename == "true" {
    62  		renaming = []string{
    63  			"--output-renaming-map-format", "CLOSURE_COMPILED",
    64  			"--rename", "CLOSURE",
    65  			"--output-renaming-map", path.Join(conf.Build, config.RENAMING_MAP_NAME),
    66  		}
    67  	}
    68  
    69  	// Prepare the defines
    70  	defines := []string{}
    71  	for _, define := range target.Defines {
    72  		defines = append(defines, "--define", define.Name)
    73  	}
    74  
    75  	// Prepare the inputs
    76  	inputs := []string{}
    77  	for _, input := range conf.Gss.Inputs {
    78  		inputs = append(inputs, input.File)
    79  	}
    80  
    81  	// Prepare the command
    82  	cmd := exec.Command(
    83  		"java",
    84  		"-jar", path.Join(conf.Gss.Compiler, "build", "closure-stylesheets.jar"),
    85  		"--output-file", filepath.Join(conf.Build, config.CSS_NAME))
    86  	cmd.Args = append(cmd.Args, funcs...)
    87  	cmd.Args = append(cmd.Args, renaming...)
    88  	cmd.Args = append(cmd.Args, inputs...)
    89  	cmd.Args = append(cmd.Args, defines...)
    90  
    91  	// Output the command if asked to
    92  	if config.OutputCmd {
    93  		fmt.Println("java", strings.Join(cmd.Args, " "))
    94  	}
    95  
    96  	// Run the compiler
    97  	output, err := cmd.CombinedOutput()
    98  	if err != nil {
    99  		if len(output) != 0 {
   100  			fmt.Println(string(output))
   101  		}
   102  
   103  		return app.Errorf("exec error: %s", err)
   104  	}
   105  
   106  	if len(output) > 0 {
   107  		log.Println("Output from GSS compiler:\n", string(output))
   108  	}
   109  
   110  	log.Println("Done compiling GSS!")
   111  
   112  	return nil
   113  }
   114  
   115  func cleanRenamingMap() error {
   116  	conf := config.Current()
   117  
   118  	// Create/Clean the renaming map file to avoid compilation errors (the JS
   119  	// compiler assumes there's a file with this name there).
   120  	f, err := os.Create(path.Join(conf.Build, config.RENAMING_MAP_NAME))
   121  	if err != nil {
   122  		return app.Error(err)
   123  	}
   124  	f.Close()
   125  
   126  	return nil
   127  }