Fixing an issue with output parameters that are of type IntPtr
[castle.git] / Experiments / Generator / src / app / GeneratorBase.boo
blob52fa83b48e9201c472d02355327f06b6b774775d
1 namespace Generator
3 import System
4 import System.IO
5 import System.Reflection
6 import Generator.Extentions
8 abstract class GeneratorBase:
9 [Property(Argv)] _argv as (string)
10 [Property(ScriptPath)] _scriptPath as string
11 [Property(TemplatesPath)] _templatesPath as string
13 [Option('replace', 'r', 'Overwrite existing files')]
14 _overwiteAll as bool = false
15 [Option('force', 'f', 'Force overwrite of files that look the same')]
16 _force as bool
17 [Option('silent', 's', 'Display not output')]
18 _silent as bool
19 [Option('debug', 'd', 'Set debug mode')]
20 _debug as bool
22 _parser as ArgumentParser
24 def constructor():
25 _scriptPath = Path.Combine(ScriptBasePath, GeneratorName)
26 _templatesPath = "${ScriptPath}/Templates"
27 _parser = ArgumentParser(self)
29 # This method is called when the generator is created
30 # it can be used to initialize arguments
31 virtual def Init(argv as (string)):
32 _argv = _parser.SetArguments(argv)
34 # Main method to run the generator
35 abstract def Run():
36 pass
38 virtual def Usage() as string:
39 return _parser.GetUsage()
41 virtual def Help() as string:
42 return 'No help yet, maybe tomorrow!'
44 #region Template properties
45 GeneratorName as string:
46 get:
47 n = GetType().Name
48 return n.Substring(0, n.Length - 'generator'.Length)
50 ScriptBasePath as string:
51 get:
52 return GeneratorFactory.Instance.ScriptBasePath
53 #endregion
55 #region Template processing methods
56 def Process(template as string, tofile as string):
57 Process(template, tofile, false)
59 def Process(template as string, tofile as string, keep as bool):
60 cleanToFile = tofile.ToPath()
61 t = Template(Path.Combine(_templatesPath, template.ToPath()))
62 result = t.Process(CollectVariables())
63 file = FileInfo(cleanToFile)
65 if file.Exists:
66 if keep:
67 Log('exists', cleanToFile)
68 return
70 if _force:
71 Log('replace', cleanToFile)
72 elif file.Length == result.Length:
73 Log('same', cleanToFile)
74 return
75 else:
76 if LogAndAskForOverwrite(cleanToFile):
77 Log('replace', cleanToFile)
78 else:
79 return
80 else:
81 Log('create', cleanToFile)
83 using w = StreamWriter(cleanToFile):
84 w.Write(result)
86 def Copy(file as string, topath as string):
87 cleanFile = Path.Combine(_templatesPath, file.ToPath())
88 cleanToPath = topath.ToPath()
89 cleanToFile = Path.Combine(cleanToPath, FileInfo(cleanFile).Name)
91 if File.Exists(cleanToFile):
92 if _force or LogAndAskForOverwrite(cleanToFile):
93 Log('replace', cleanToFile)
94 else:
95 return
96 else:
97 Log('create', cleanToFile)
99 File.Copy(cleanFile, cleanToFile, true)
101 def CopyDir(dir as string, topath as string):
102 MkDir(topath)
103 source = Path.Combine(_templatesPath, dir.ToPath())
104 for file in Directory.GetFiles(source):
105 name = FileInfo(file).Name
106 Copy(file, topath) if not name.StartsWith('.')
107 for dir in Directory.GetDirectories(source):
108 name = DirectoryInfo(dir).Name
109 CopyDir(dir, Path.Combine(topath, name)) if not name.StartsWith('.')
111 def MkDir(path as string):
112 cleanPath = path.ToPath()
113 if Directory.Exists(cleanPath):
114 Log('exists', cleanPath)
115 else:
116 Log('create', cleanPath)
117 Directory.CreateDirectory(cleanPath)
118 #endregion
120 #region Helper methods
121 virtual def PrintUsage():
122 print "usage: generate ${GeneratorName} ${Usage()}"
123 print
124 print _parser.GetHelp()
125 print
126 print Help()
128 protected def Log(action as string, path as string):
129 if not _silent:
130 print action.PadLeft(10), path
132 protected def Debug(msg as string):
133 if _debug and not _silent:
134 print msg
136 private def CollectVariables() as Hash:
137 props = {}
138 for p as PropertyInfo in GetType().GetProperties():
139 props.Add(p.Name, p.GetValue(self, null))
140 return props
142 private def LogAndAskForOverwrite(path as string) as bool:
143 return true if _overwiteAll
145 question = "${'exists'.PadLeft(10)} ${path} Overwrite? [Ynaq] "
146 answer = prompt(question).ToLower()
147 if answer == 'y' or answer == '':
148 return true
149 elif answer == 'a':
150 _overwiteAll = true
151 return true
152 elif answer == 'q':
153 Environment.Exit(0)
154 return false
155 #endregion