Created
July 24, 2014 17:15
-
-
Save rubysolo/d0c03cc4d5d62cfb0070 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "errors" | |
import "fmt" | |
import "io" | |
import "io/ioutil" | |
import "log" | |
import "os" | |
import "path/filepath" | |
import "strings" | |
func main() { | |
testFile, err := detectExercism() | |
if (err != nil) { | |
log.Fatal(err) | |
} | |
fmt.Println("Found " + testFile + ", let the leinifying commence!") | |
exerciseName := strings.Replace(testFile, "_test.clj", "", -1) | |
fmt.Println("Exercise name: " + exerciseName) | |
transformTestFile(testFile, exerciseName) | |
createProjectFile(exerciseName) | |
createSrcFile(exerciseName) | |
} | |
func detectExercism() (f string, err error) { | |
files, _ := filepath.Glob("*_test.clj") | |
if len(files) == 0 { | |
return "", errors.New("Could not find an exercism clojure test (*_test.clj) in current directory.") | |
} | |
return files[0], nil | |
} | |
func transformTestFile(fileName string, exerciseName string) { | |
bytes, err := ioutil.ReadFile(fileName) | |
if (err != nil) { | |
log.Fatal(err) | |
} | |
content := string(bytes[:]) | |
// extract ns form boundaries | |
_, nsBoundEnd := formBounds(content, 0) | |
// extract load file form boundaries | |
_, lfBoundEnd := formBounds(content, nsBoundEnd+1) | |
// remove ns and load-file forms | |
content = content[lfBoundEnd+1:] | |
// insert new ns form | |
nsForm := "(ns " + exerciseName + "-test\n" + | |
" (:require [clojure.test :refer :all]\n" + | |
" [" + exerciseName + " :refer :all]))\n\n" | |
content = nsForm + strings.Replace(content, "(run-tests)", "", -1) | |
if os.MkdirAll("test", 0777) != nil { | |
log.Fatal("could not create 'test' directory!") | |
} | |
fileOut, err := os.Create(strings.Join([]string{"test", fileName}, "/")) | |
if (err != nil) { | |
log.Fatal("could not create 'test/" + fileName + "'!") | |
} | |
defer fileOut.Close() | |
fmt.Println("writing 'test/" + fileName + "'...") | |
io.WriteString(fileOut, content) | |
} | |
// find the start and end character index of the next lisp form in string | |
// at or after index, handling nested forms | |
func formBounds(s string, index int) (startIndex int, endIndex int) { | |
stack := 0 | |
startIndex = -1 | |
endIndex = -1 | |
for i,c := range s { | |
if i >= index { | |
switch c { | |
case '(': | |
if (startIndex == -1) { | |
startIndex = i | |
} | |
stack++ | |
case ')': | |
stack-- | |
if (stack == 0) { | |
endIndex = i | |
break | |
} | |
} | |
} | |
if (endIndex > 0) { | |
break | |
} | |
} | |
return startIndex, endIndex+1 | |
} | |
func createProjectFile(exerciseName string) { | |
fileOut, err := os.Create("project.clj") | |
if (err != nil) { | |
log.Fatal("could not create 'project.clj'!") | |
} | |
defer fileOut.Close() | |
clojureVersion := os.Getenv("CLOJURE_VERSION") | |
if (clojureVersion == "") { | |
message := "*** It looks like you haven't specified your clojure version.\n" + | |
" I'll default it to 1.6.0; if you want something different,\n" + | |
" set the CLOJURE_VERSION environment variable" | |
fmt.Println(message) | |
clojureVersion = "1.6.0" | |
} | |
content := "(defproject " + exerciseName + " \"1.0.0\"\n" + | |
" :dependencies [[org.clojure/clojure \"" + clojureVersion + "\"]])\n" | |
fmt.Println("writing 'project.clj'...") | |
io.WriteString(fileOut, content) | |
} | |
func createSrcFile(exerciseName string) { | |
if os.MkdirAll("src", 0777) != nil { | |
log.Fatal("could not create 'src' directory!") | |
} | |
fileName := exerciseName + ".clj" | |
fileOut, err := os.Create(strings.Join([]string{"src", fileName}, "/")) | |
if (err != nil) { | |
log.Fatal("could not create 'src/" + fileName + "'!") | |
} | |
defer fileOut.Close() | |
fmt.Println("writing 'src/" + fileName + "'...") | |
io.WriteString(fileOut, "(ns " + exerciseName + ")") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment