class
compiler::WritePod
sys::Obj
compiler::CompilerSupport
compiler::CompilerStep
compiler::WritePod
1 //
2 // Copyright (c) 2006, Brian Frank and Andy Frank
3 // Licensed under the Academic Free License version 3.0
4 //
5 // History:
6 // 3 Sep 05 Brian Frank Creation
7 // 7 Oct 06 Brian Frank Port from Java to Fan
8 //
9
10 **
11 ** WritePod writes the FPod to a zip file.
12 **
13 class WritePod : CompilerStep
14 {
15
16 //////////////////////////////////////////////////////////////////////////
17 // Constructor
18 //////////////////////////////////////////////////////////////////////////
19
20 new make(Compiler compiler)
21 : super(compiler)
22 {
23 }
24
25 //////////////////////////////////////////////////////////////////////////
26 // Run
27 //////////////////////////////////////////////////////////////////////////
28
29 **
30 ** Not used, use write instead
31 **
32 override Void run() { throw UnsupportedErr.make }
33
34 **
35 ** Run the step and return pod file written
36 **
37 File write()
38 {
39 dir := compiler.input.outDir
40 fpod := compiler.fpod
41 podFile := dir + "${fpod.name}.pod".toUri
42 location = Location.makeFile(podFile)
43
44 log.message("WritePod", podFile.toStr)
45
46 // create output directory
47 dir.create
48
49 Zip zip := null
50 try
51 {
52 // open zip store
53 zip = Zip.write(podFile.out)
54
55 // write fpod data structures into zip file
56 fpod.write(zip)
57
58 // write resource files
59 compiler.resFiles.each |File f| { writeRes(zip, f) }
60
61 // if including fandoc write it out too
62 if (compiler.input.includeDoc) writeTypeDocs(zip)
63
64 // if including source write it out too
65 if (compiler.input.includeSrc) writeSrc(zip)
66 }
67 catch (CompilerErr e)
68 {
69 throw e
70 }
71 catch (Err e)
72 {
73 throw errReport(CompilerErr.make("Cannot write", location, e))
74 }
75
76 // close file
77 if (zip != null) zip.close
78 return podFile
79 }
80
81 //////////////////////////////////////////////////////////////////////////
82 // Resource
83 //////////////////////////////////////////////////////////////////////////
84
85 private Void writeRes(Zip zip, File file, Uri path := null)
86 {
87 input := compiler.input
88 if (path == null)
89 {
90 path = file.uri
91 path = path - input.homeDir.uri
92 }
93
94 try
95 {
96 out := zip.writeNext(path, file.modified)
97 file.in.pipe(out)
98 out.close
99 }
100 catch (Err e)
101 {
102 throw errReport(CompilerErr.make("Cannot write resource file '$path'", location, e))
103 }
104 }
105
106 //////////////////////////////////////////////////////////////////////////
107 // Doc
108 //////////////////////////////////////////////////////////////////////////
109
110 private Void writeTypeDocs(Zip zip)
111 {
112 compiler.types.each |TypeDef t|
113 {
114 if (!t.isSynthetic) writeTypeDoc(zip, t)
115 }
116 }
117
118 private Void writeTypeDoc(Zip zip, TypeDef t)
119 {
120 try
121 {
122 out := zip.writeNext("doc/${t.name}.apidoc".toUri)
123 writeDoc(out, t.qname, t.doc)
124 t.slotDefs.each |SlotDef s|
125 {
126 writeDoc(out, s.qname, s.doc)
127 }
128 out.close
129 }
130 catch (Err e)
131 {
132 throw errReport(CompilerErr.make("Cannot write fandoc '$t.name'", t.location, e))
133 }
134 }
135
136 **
137 ** FDoc is used to read/write a fandoc text file. The fandoc file
138 ** format is an extremely simple plan text format with left justified
139 ** type/slot qnames, followed by the fandoc content indented two spaces.
140 **
141 private static Void writeDoc(OutStream out, Str key, Str[] doc)
142 {
143 if (doc == null) return
144 out.printLine(key)
145 doc.each |Str line| { out.print(" ").printLine(line) }
146 out.printLine
147 }
148
149 //////////////////////////////////////////////////////////////////////////
150 // Src
151 //////////////////////////////////////////////////////////////////////////
152
153 private Void writeSrc(Zip zip)
154 {
155 compiler.srcFiles.each |File f|
156 {
157 writeRes(zip, f, "src/$f.name".toUri)
158 }
159 }
160
161 //////////////////////////////////////////////////////////////////////////
162 // Fields
163 //////////////////////////////////////////////////////////////////////////
164
165 private Location location
166 }
2 // Copyright (c) 2006, Brian Frank and Andy Frank
3 // Licensed under the Academic Free License version 3.0
4 //
5 // History:
6 // 3 Sep 05 Brian Frank Creation
7 // 7 Oct 06 Brian Frank Port from Java to Fan
8 //
9
10 **
11 ** WritePod writes the FPod to a zip file.
12 **
13 class WritePod : CompilerStep
14 {
15
16 //////////////////////////////////////////////////////////////////////////
17 // Constructor
18 //////////////////////////////////////////////////////////////////////////
19
20 new make(Compiler compiler)
21 : super(compiler)
22 {
23 }
24
25 //////////////////////////////////////////////////////////////////////////
26 // Run
27 //////////////////////////////////////////////////////////////////////////
28
29 **
30 ** Not used, use write instead
31 **
32 override Void run() { throw UnsupportedErr.make }
33
34 **
35 ** Run the step and return pod file written
36 **
37 File write()
38 {
39 dir := compiler.input.outDir
40 fpod := compiler.fpod
41 podFile := dir + "${fpod.name}.pod".toUri
42 location = Location.makeFile(podFile)
43
44 log.message("WritePod", podFile.toStr)
45
46 // create output directory
47 dir.create
48
49 Zip zip := null
50 try
51 {
52 // open zip store
53 zip = Zip.write(podFile.out)
54
55 // write fpod data structures into zip file
56 fpod.write(zip)
57
58 // write resource files
59 compiler.resFiles.each |File f| { writeRes(zip, f) }
60
61 // if including fandoc write it out too
62 if (compiler.input.includeDoc) writeTypeDocs(zip)
63
64 // if including source write it out too
65 if (compiler.input.includeSrc) writeSrc(zip)
66 }
67 catch (CompilerErr e)
68 {
69 throw e
70 }
71 catch (Err e)
72 {
73 throw errReport(CompilerErr.make("Cannot write", location, e))
74 }
75
76 // close file
77 if (zip != null) zip.close
78 return podFile
79 }
80
81 //////////////////////////////////////////////////////////////////////////
82 // Resource
83 //////////////////////////////////////////////////////////////////////////
84
85 private Void writeRes(Zip zip, File file, Uri path := null)
86 {
87 input := compiler.input
88 if (path == null)
89 {
90 path = file.uri
91 path = path - input.homeDir.uri
92 }
93
94 try
95 {
96 out := zip.writeNext(path, file.modified)
97 file.in.pipe(out)
98 out.close
99 }
100 catch (Err e)
101 {
102 throw errReport(CompilerErr.make("Cannot write resource file '$path'", location, e))
103 }
104 }
105
106 //////////////////////////////////////////////////////////////////////////
107 // Doc
108 //////////////////////////////////////////////////////////////////////////
109
110 private Void writeTypeDocs(Zip zip)
111 {
112 compiler.types.each |TypeDef t|
113 {
114 if (!t.isSynthetic) writeTypeDoc(zip, t)
115 }
116 }
117
118 private Void writeTypeDoc(Zip zip, TypeDef t)
119 {
120 try
121 {
122 out := zip.writeNext("doc/${t.name}.apidoc".toUri)
123 writeDoc(out, t.qname, t.doc)
124 t.slotDefs.each |SlotDef s|
125 {
126 writeDoc(out, s.qname, s.doc)
127 }
128 out.close
129 }
130 catch (Err e)
131 {
132 throw errReport(CompilerErr.make("Cannot write fandoc '$t.name'", t.location, e))
133 }
134 }
135
136 **
137 ** FDoc is used to read/write a fandoc text file. The fandoc file
138 ** format is an extremely simple plan text format with left justified
139 ** type/slot qnames, followed by the fandoc content indented two spaces.
140 **
141 private static Void writeDoc(OutStream out, Str key, Str[] doc)
142 {
143 if (doc == null) return
144 out.printLine(key)
145 doc.each |Str line| { out.print(" ").printLine(line) }
146 out.printLine
147 }
148
149 //////////////////////////////////////////////////////////////////////////
150 // Src
151 //////////////////////////////////////////////////////////////////////////
152
153 private Void writeSrc(Zip zip)
154 {
155 compiler.srcFiles.each |File f|
156 {
157 writeRes(zip, f, "src/$f.name".toUri)
158 }
159 }
160
161 //////////////////////////////////////////////////////////////////////////
162 // Fields
163 //////////////////////////////////////////////////////////////////////////
164
165 private Location location
166 }