fcshd 0.3.1 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
data/Makefile CHANGED
@@ -1,6 +1,12 @@
1
+ version=$(shell ruby -r lib/fcshd/version -e 'print FCSHD::VERSION')
2
+
3
+ default: install
4
+
1
5
  build:
2
6
  gem build fcshd.gemspec
7
+ install: build
8
+ sudo gem install fcshd-${version}.gem
9
+ push: build
10
+ gem push fcshd-${version}.gem
3
11
  clean:
4
12
  rm *.gem
5
- push: build
6
- gem push fcshd-$(shell ruby -r lib/fcshd/version -e 'print FCSHD::VERSION').gem
data/bin/fcshc CHANGED
@@ -16,82 +16,159 @@ def die(message)
16
16
  exit 1
17
17
  end
18
18
 
19
- $source_directories = []
20
- $library_filenames = []
19
+ $output_file = nil
20
+ $source_files = []
21
+ $library_files = []
22
+ $directories = []
23
+ $production = false
21
24
  $extra_arguments = []
25
+ $verbose = false
26
+ $dry_run = false
22
27
 
23
28
  OptionParser.new do |parser|
24
- parser.banner = "Usage: fcshc MAIN [SRCDIR|LIB]... -o OUTPUT"
29
+ parser.banner = <<EOF
30
+ Usage: fcshc MAIN.[as|mxml] [SRCDIR|SWCDIR|SWC]... [-o OUTPUT.swf]
31
+ fcshc -o OUTPUT.swc [SRCDIR|SWCDIR|SWC]...
25
32
 
26
- parser.on("-o", "--output FILENAME", "Write SWF to FILENAME") do |value|
27
- $output_filename = File.expand_path(value)
33
+ To compile an SWF, name the main application source file, then any
34
+ additional source directories, SWC directories, or SWC files.
35
+
36
+ To compile an SWC using `compc', you must provide the `-o' option, and
37
+ then at least one source directory, SWC directory, or SWC file.
38
+
39
+ To pass extra arguments, use e.g. `-X -include-file -X NAME -X FILE'.
40
+
41
+ EOF
42
+
43
+ parser.on("-o", "--output OUTPUT.[swf|swc]", "Name of the resulting binary") do |value|
44
+ $output_file = File.expand_path(value)
28
45
  end
29
46
 
30
- parser.on("-3", "Use -compatibility-version=3") do |value|
31
- $extra_arguments << "-compatibility-version=3"
47
+ parser.on("-X", "--extra-argument ARGUMENT", "Pass ARGUMENT to the compiler") do |value|
48
+ $extra_arguments << value
32
49
  end
33
50
 
34
- parser.on("--no-flex", "Remove all runtime shared libraries (RSLs)") do
51
+ parser.on("-p", "--production", "Leave out debugging metadata") do
52
+ $production = true
53
+ end
54
+
55
+ parser.on("--static-rsls", "Use static linking for RSLs") do
56
+ $extra_arguments << "-static-link-runtime-shared-libraries=true"
57
+ end
58
+
59
+ parser.on("--no-rsls", "Remove all runtime shared libraries") do
35
60
  $extra_arguments << "-runtime-shared-library-path="
36
61
  end
37
62
 
63
+ parser.separator ""
64
+
65
+ parser.on("-3", "--flex-3", "Use -compatibility-version=3") do |value|
66
+ $extra_arguments << "-compatibility-version=3"
67
+ end
68
+
38
69
  parser.on("--halo", "Use the Halo theme") do
39
70
  die "must set $FLEX_HOME to use --halo option" if not FlexHome.known?
40
71
  $extra_arguments << "-theme=#{FlexHome.halo_swc}"
41
72
  end
42
73
 
43
- parser.on("-X EXTRA-ARGUMENT", "Pass EXTRA-ARGUMENT to mxmlc (multiple allowed)") do |value|
44
- $extra_arguments << value
74
+ parser.separator ""
75
+
76
+ parser.on("-n", "--dry-run", "Only print the compiler command") do
77
+ $dry_run = true
45
78
  end
46
79
 
47
- parser.on("-v", "--verbose", "Print mxmlc command line") do
80
+ parser.on("--verbose", "Also print the compiler command") do
48
81
  $verbose = true
49
82
  end
83
+
84
+ parser.on("-v", "--version", "Show `fcshc #{FCSHD::VERSION}'") do
85
+ puts "fcshc #{FCSHD::VERSION}"
86
+ exit
87
+ end
88
+
89
+ parser.on("-h", "--help", "Show this message") do
90
+ puts parser
91
+ exit
92
+ end
93
+
94
+ parser.separator ""
95
+ parser.separator "TL;DR: $ fcshc src/my_app.mxml"
50
96
  end.parse!
51
97
 
98
+ $extra_arguments << "-debug" unless $production
99
+
52
100
  for name in ARGV
53
101
  if not File.exists? name
54
102
  die "no such file or directory: #{name}"
55
103
  elsif File.directory? name
56
- $source_directories << File.expand_path(name)
104
+ $directories << File.expand_path(name)
57
105
  elsif %w(.as .mxml).include? File.extname(name)
58
- die "multiple source files not allowed" if $source_filename
59
- $source_filename = File.expand_path(name)
106
+ $source_files << File.expand_path(name)
60
107
  elsif %w(.swc).include? File.extname(name)
61
- $library_filenames << File.expand_path(name)
108
+ $library_files << File.expand_path(name)
62
109
  else
63
110
  die "don't know what to do with file: #{name}"
64
111
  end
65
112
  end
66
113
 
67
- if $source_filename == nil
68
- die "missing source file to compile"
69
- end
114
+ $compiling_swc = $output_file && $output_file.end_with?(".swc")
70
115
 
71
- if $source_directories == []
72
- $source_directories << File.dirname($source_filename)
73
- end
116
+ if $compiling_swc
117
+ if [$source_files, $directories, $library_files] == [[], [], []]
118
+ die "must include at least one source file, directory, or SWC"
119
+ end
120
+
121
+ $fcshd_arguments = ["compc"]
122
+
123
+ for file in $source_files
124
+ $fcshd_arguments << "-include-sources+=#{file}"
125
+ end
126
+
127
+ for directory in $directories
128
+ $fcshd_arguments << "-include-sources+=#{directory}"
129
+ end
130
+ else
131
+ case $source_files.size
132
+ when 0: die "missing main application source file"
133
+ when 1: $source_file = $source_files.first
134
+ else die "multiple source files not allowed when compiling SWF"
135
+ end
136
+
137
+ if $directories.empty?
138
+ $directories << File.dirname($source_file)
139
+ end
74
140
 
75
- if $output_filename == nil
76
- $source_filename.sub(/\.(as|mxml)$/, ".swf").tap do |filename|
77
- local_filename = File.basename(filename)
78
- $output_filename = File.expand_path(local_filename)
141
+ if $output_file == nil
142
+ $source_file.sub(/\.(as|mxml)$/, ".swf").tap do |x|
143
+ $output_file = File.expand_path(File.basename(x))
144
+ end
79
145
  end
146
+
147
+ $fcshd_arguments = ["mxmlc", "#$source_file"]
80
148
  end
81
149
 
82
- $fcshd_arguments = ["mxmlc #$source_filename -output=#$output_filename"]
150
+ $fcshd_arguments << "-output=#$output_file"
83
151
 
84
- for directory in $source_directories
152
+ for directory in $directories
85
153
  $fcshd_arguments << "-compiler.source-path+=#{directory}"
86
154
  $fcshd_arguments << "-compiler.library-path+=#{directory}"
87
155
  end
88
156
 
89
- for filename in $library_filenames
90
- $fcshd_arguments << "-compiler.library-path+=#{filename}"
157
+ for file in $library_files
158
+ $fcshd_arguments << "-compiler.library-path+=#{file}"
91
159
  end
92
160
 
93
161
  $fcshd_arguments.concat($extra_arguments)
94
162
 
163
+ basedir = File.join(File.expand_path("."), "")
164
+ fcshd_command = $fcshd_arguments.join(" ")
165
+
166
+ if $verbose || $dry_run
167
+ warn fcshd_command.gsub(basedir, "")
168
+ end
169
+
170
+ exit if $dry_run
171
+
95
172
  begin
96
173
  host, port = "localhost", FCSHD::Server::PORT
97
174
  socket = TCPSocket.new(host, port)
@@ -99,10 +176,6 @@ rescue Errno::ECONNREFUSED
99
176
  die "could not connect to fcshd at #{host}:#{port}"
100
177
  end
101
178
 
102
- basedir = File.join(File.expand_path("."), "")
103
-
104
- fcshd_command = $fcshd_arguments.join(" ")
105
- warn fcshd_command.gsub(basedir, "") if $verbose
106
179
  socket.puts fcshd_command
107
180
 
108
181
  compiler_output = ""
@@ -115,7 +188,6 @@ socket.each_line do |line|
115
188
  end
116
189
  end
117
190
 
118
- output = FCSHD::CompilerOutput[compiler_output, basedir]
119
- output.write! FCSHD::CompilerOutputWriter.new(STDOUT, basedir)
120
-
121
- exit 1 if not output.succeeded?
191
+ transcript = FCSHD::Transcript[compiler_output]
192
+ STDOUT.write transcript.to_s(basedir)
193
+ exit 1 if not transcript.succeeded?
data/bin/fcshd CHANGED
@@ -8,6 +8,11 @@ rescue LoadError
8
8
  require "fcshd"
9
9
  end
10
10
 
11
+ if ARGV == ["-v"] || ARGV == ["--version"]
12
+ puts "fcshd #{FCSHD::VERSION}"
13
+ exit
14
+ end
15
+
11
16
  logger = FCSHD::Logger.new(STDERR)
12
17
 
13
18
  logger.die <<"^D" if not FCSHD::FlexHome.known?
@@ -26,6 +31,7 @@ begin
26
31
  FCSHD::Server.new(FCSHD::Server::PORT, compiler, logger).run!
27
32
  logger.log "Now listening to port #{FCSHD_PORT}."
28
33
  rescue Interrupt
34
+ logger.log ""
29
35
  logger.log "Exiting."
30
36
  rescue Exception => error
31
37
  logger.error "Could not listen to port #{FCSHD_PORT}: #{error}"
@@ -51,7 +51,7 @@ module FCSHD
51
51
  end
52
52
 
53
53
  def compile_new!
54
- @frontend.puts "fcshd: compiling from scratch"
54
+ @frontend.puts "fcshd: Compiling from scratch"
55
55
  @frontend.flush
56
56
  send_fcsh_command! @command
57
57
  parse_compilation_output!
data/lib/fcshd/problem.rb CHANGED
@@ -1,153 +1,7 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  module FCSHD
4
- class Problem < Struct.new(:source_location, :raw_mxmlc_message)
5
- ERROR_PREFIX = /^\s*Error: /
6
-
7
- def mxmlc_message
8
- raw_mxmlc_message.sub(ERROR_PREFIX, "")
9
- end
10
-
11
- def error?
12
- raw_mxmlc_message =~ ERROR_PREFIX
13
- end
14
-
15
- def quote(string)
16
- "‘#{string}’"
17
- end
18
-
19
- def message
20
- case raw = raw_message
21
- when String then raw
22
- when Array then raw * "\n"
23
- else fail
24
- end
25
- end
26
-
27
- def raw_message
28
- case mxmlc_message
29
-
30
- when "Unable to resolve MXML language version. Please specify the language namespace on the root document tag."
31
- then
32
- <<"^D"
33
- missing MXML version
34
- → xmlns:fx="library://ns.adobe.com/mxml/2009"
35
- → xmlns="library://ns.adobe.com/flex/spark"
36
- → xmlns:mx="library://ns.adobe.com/flex/mx" (Flex 3 compatibility)
37
- → xmlns="http://www.adobe.com/2006/mxml" (Flex 3)
38
- ^D
39
-
40
- when /^Incorrect number of arguments. Expected (\d+)\.$/
41
- then "expected #$1 arguments"
42
-
43
- when /^(?:Access of possibly undefined property|Call to a possibly undefined method) (.+) through a reference with static type (.+)\.$/
44
- then "#{quote $1} undeclared in #$2"
45
-
46
- when /^Attempted access of inaccessible property (.+) through a reference with static type (.+)\.$/
47
- then "#{quote $1} inaccessible in #$2"
48
-
49
- when
50
- /^Could not resolve <(.+)> to a component implementation.$/,
51
- /^Call to a possibly undefined method (.+).$/,
52
- /^Access of undefined property (.+).$/,
53
- /^The definition of base class (.+) was not found.$/,
54
- /^Type was not found or was not a compile-time constant: (.+)\.$/
55
- then
56
- ["#{quote $1} undeclared"].tap do |result|
57
- FlexHome.find_component($1).tap do |package|
58
- result << "→ import #{package}.*" if package
59
- end
60
- end
61
-
62
- when /^Definition (.+) could not be found\.$/
63
- then "#{quote $1} not found"
64
-
65
- when
66
- /^Implicit coercion of a value of type (.+) to an unrelated type (.+)\.$/,
67
-
68
- /^Implicit coercion of a value with static type (.+) to a possibly unrelated type (.+)\./
69
-
70
- then
71
- actual, expected = $1, $2
72
- expected_base = expected.sub(/.+:/, "")
73
- actual_base = actual.sub(/.+:/, "")
74
- if actual_base != expected_base
75
- "expected #{expected_base} (got #{actual_base})"
76
- else
77
- "expected #{expected} (got #{actual})"
78
- end
79
-
80
- when "Method marked override must override another method."
81
- then "overriding nonexistent method"
82
-
83
- when "Overriding a function that is not marked for override."
84
- then ["unmarked override", "→ add override keyword"]
85
-
86
- when "Incompatible override."
87
- then "incompatible override"
88
-
89
- when /^Ambiguous reference to (.+)\.$/
90
- then "#{quote $1} is ambiguous"
91
-
92
- when /^A conflict exists with definition (.+) in namespace internal\.$/
93
- then "#{quote $1} is conflicting"
94
-
95
- when
96
- /^Warning: parameter '(.+)' has no type declaration\.$/,
97
- /^Warning: return value for function '(.+)' has no type declaration\.$/
98
- then
99
- case $1
100
- when "anonymous" then "anonymous function"
101
- else quote $1
102
- end + " missing type declaration"
103
-
104
- when /^A file found in a source-path must have the same package structure '(.*)', as the definition's package, '(.*)'\.$/
105
- then "package should be #{quote $1}"
106
-
107
- when /^Comparison between a value with static type (.+) and a possibly unrelated type (.+)\.$/
108
- then "comparing #$1 to #$2"
109
-
110
- when "Illegal assignment to a variable specified as constant."
111
- then "modifying constant"
112
-
113
- when "Function does not have a body."
114
- then "missing function body"
115
-
116
- when "Return type of a setter definition must be unspecified or void."
117
- then "setter must return void"
118
-
119
- when "Function does not return a value."
120
- then "missing return statement"
121
-
122
- when "Syntax error: expecting identifier before rightparen."
123
- then "#{quote ")"} unexpected"
124
-
125
- when
126
- /^The (.+) attribute can only be used inside a package\./,
127
- /^The (.+) attribute may be used only on class property definitions\./
128
- then
129
- "#{quote $1} unexpected"
130
-
131
- else
132
- mxmlc_message
133
- end
134
- end
135
-
136
- def formatted_message_lines
137
- lines = message.lines.entries
138
- if error?
139
- first = <<"^D"
140
- error: #{lines[0].chomp}
141
- ^D
142
- rest = lines[1..-1].map do |line|
143
- <<"^D"
144
- #{line.chomp}
145
- ^D
146
- end
147
- [first] + rest
148
- else
149
- lines
150
- end
2
+ class Problem < Struct.new(:location, :message)
3
+ def to_s(basedir)
4
+ "#{location.to_s(basedir)}: #{message}"
151
5
  end
152
6
  end
153
7
  end
data/lib/fcshd/server.rb CHANGED
@@ -21,10 +21,10 @@ module FCSHD
21
21
  class Client < Struct.new(:socket, :compiler)
22
22
  def run!
23
23
  case command = socket.gets
24
- when /^mxmlc /
24
+ when /^(mxmlc|compc) /
25
25
  compiler.compile! command, socket
26
26
  else
27
- sockets.puts "fcshd: unrecognized command: #{command}"
27
+ socket.puts "fcshd: unrecognized command: #{command}"
28
28
  end
29
29
  rescue Errno::EPIPE
30
30
  logger.log "Broken pipe."
@@ -1,27 +1,15 @@
1
1
  module FCSHD
2
- class SourceLocation < Struct.new \
3
- :filename, :line_number, :column_number, :basedir
4
-
5
- def to_s
6
- relative_filename.tap do |result|
7
- result << ":#{line_number}" if line_number
8
- end
2
+ class SourceLocation < Struct.new(:filename, :line_number)
3
+ def to_s(basedir=nil)
4
+ "#{relative_filename(basedir)}:#{line_number || 0}"
9
5
  end
10
6
 
11
- def relative_filename
7
+ def relative_filename(basedir)
12
8
  if basedir
13
9
  filename.sub(/^#{Regexp.quote(basedir)}/, "")
14
10
  else
15
11
  filename
16
12
  end
17
13
  end
18
-
19
- def with_basedir(new_basedir)
20
- dup.tap { |result| result.basedir = new_basedir }
21
- end
22
-
23
- def without_column_number
24
- dup.tap { |result| result.column_number = nil }
25
- end
26
14
  end
27
15
  end
@@ -0,0 +1,154 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module FCSHD
4
+ class Transcript; end
5
+ class Transcript::Item < Struct.new(:location, :mxmlc_message)
6
+ def to_s(basedir)
7
+ problems.map { |problem| problem.to_s(basedir) }.join("\n")
8
+ end
9
+
10
+ def problems
11
+ get_problems(parsed_message)
12
+ end
13
+
14
+ private
15
+
16
+ def get_problems(item)
17
+ case item
18
+ when String
19
+ get_problems_at(location, item)
20
+ when Array
21
+ if item.first.is_a? SourceLocation
22
+ get_problems_at(item[0], item[1])
23
+ else
24
+ item.map { |item| get_problems(item) }.flatten(1)
25
+ end
26
+ else fail
27
+ end
28
+ end
29
+
30
+ def get_problems_at(location, message)
31
+ message.split("\n").map do |message|
32
+ Problem[location, message]
33
+ end
34
+ end
35
+
36
+ def parsed_message
37
+ case FCSHD.trim(mxmlc_message).sub(/^Error: /, "")
38
+ when "Unable to resolve MXML language version. Please specify the language namespace on the root document tag.": <<EOF
39
+ error: missing MXML version
40
+ error: hint: xmlns:fx="library://ns.adobe.com/mxml/2009"
41
+ error: hint: xmlns="library://ns.adobe.com/flex/spark"
42
+ error: hint: xmlns:mx="library://ns.adobe.com/flex/mx" (Flex 4)
43
+ error: hint: xmlns="http://www.adobe.com/2006/mxml" (Flex 3)
44
+ EOF
45
+ when /^Incorrect number of arguments. Expected (\d+)\.$/: <<EOF
46
+ error: expected #$1 arguments
47
+ EOF
48
+ when
49
+ /^Access of possibly undefined property (.+) through a reference with static type (.+)\.$/,
50
+ /^Call to a possibly undefined method (.+) through a reference with static type (.+)\.$/,
51
+ /^Cannot resolve attribute '(.+)' for component type (.+)\.$/
52
+ then <<EOF
53
+ error: #{quote $1} undeclared in #{name $2}
54
+ EOF
55
+ when /^Attempted access of inaccessible property (.+) through a reference with static type (.+)\.$/: <<EOF
56
+ error: #{quote $1} inaccessible in #{name $2}
57
+ EOF
58
+ when
59
+ /^Could not resolve <(.+)> to a component implementation\.$/,
60
+ /^Call to a possibly undefined method (.+)\.$/,
61
+ /^Access of undefined property (.+)\.$/,
62
+ /^The definition of base class (.+) was not found\.$/,
63
+ /^Type was not found or was not a compile-time constant: (.+)\.$/
64
+ then
65
+ [<<EOF].tap do |result|
66
+ error: #{quote $1} undeclared
67
+ EOF
68
+ FlexHome.find_component($1).tap do |package|
69
+ result << <<EOF if package
70
+ error: hint: import #{package}.#$1
71
+ EOF
72
+ end
73
+ end
74
+ when /^Definition (.+) could not be found\.$/: <<EOF
75
+ error: #{quote $1} not found
76
+ EOF
77
+ when /^Implicit coercion of a value of type (.+) to an unrelated type (.+)\.$/, /^Implicit coercion of a value with static type (.+) to a possibly unrelated type (.+)\./
78
+ actual, expected = $1, $2
79
+ expected_local = expected.sub(/.+:/, "")
80
+ actual_local = actual.sub(/.+:/, "")
81
+ actual_local != expected_local ? <<EOF : <<EOF
82
+ error: expected #{expected_local} (got #{actual_local})
83
+ EOF
84
+ error: expected #{expected} (got #{actual})
85
+ EOF
86
+ when "Method marked override must override another method.": <<EOF
87
+ error: overriding nonexistent method
88
+ EOF
89
+ when "Overriding a function that is not marked for override.": <<EOF
90
+ error: unmarked override
91
+ EOF
92
+ when "Incompatible override.": <<EOF
93
+ error: incompatible override
94
+ EOF
95
+ when /^Ambiguous reference to (.+)\.$/: <<EOF
96
+ error: #{quote $1} is ambiguous
97
+ EOF
98
+ when /^Can not resolve a multiname reference unambiguously. (\S+) \(from ([^)]+)\) and (\S+) \(from ([^)]+)\) are available\.$/
99
+ then
100
+ [<<EOF, [SourceLocation[$2], <<EOF], [SourceLocation[$4], <<EOF]]
101
+ error: #{quote name $1} conflicts with #{quote name $3}
102
+ EOF
103
+ error: conflicting definition
104
+ EOF
105
+ error: conflicting definition
106
+ EOF
107
+ when /^A conflict exists with definition (.+) in namespace internal\.$/: <<EOF
108
+ error: #{quote $1} conflicts with an internal name
109
+ EOF
110
+ when
111
+ /^Warning: parameter '(.+)' has no type declaration\.$/,
112
+ /^Warning: return value for function '(.+)' has no type declaration\.$/
113
+ then
114
+ who = $1 == "anonymous" ? "anonymous function" : quote($1)
115
+ <<EOF
116
+ error: #{who} missing type declaration
117
+ EOF
118
+ when /^A file found in a source-path must have the same package structure '(.*)', as the definition's package, '(.*)'\.$/: <<EOF
119
+ error: package should be #{quote $1}
120
+ EOF
121
+ when /^Comparison between a value with static type (.+) and a possibly unrelated type (.+)\.$/: <<EOF
122
+ error: comparing #$1 to #$2
123
+ EOF
124
+ when "Illegal assignment to a variable specified as constant.": <<EOF
125
+ error: modifying constant
126
+ EOF
127
+ when "Function does not have a body.": <<EOF
128
+ error: missing function body"
129
+ EOF
130
+ when "Return type of a setter definition must be unspecified or void.": <<EOF
131
+ error: setter must return void"
132
+ EOF
133
+ when "Function does not return a value.": <<EOF
134
+ error: missing return statement"
135
+ EOF
136
+ when "Syntax error: expecting identifier before rightparen.": <<EOF
137
+ error: #{quote ")"} unexpected"
138
+ EOF
139
+ when
140
+ /^The (.+) attribute can only be used inside a package\./,
141
+ /^The (.+) attribute may be used only on class property definitions\./
142
+ then
143
+ <<EOF
144
+ error: #{quote $1} unexpected
145
+ EOF
146
+ else
147
+ mxmlc_message
148
+ end
149
+ end
150
+
151
+ def quote(string) "‘#{string}’" end
152
+ def name(string) string.sub! ":", "." end
153
+ end
154
+ end
@@ -0,0 +1,65 @@
1
+ module FCSHD
2
+ class Transcript; end
3
+ class Transcript::Parser < Struct.new(:lines)
4
+ def parse!
5
+ Transcript.new.tap do |result|
6
+ @result = result
7
+ parse_line! until lines.empty?
8
+ end
9
+ end
10
+
11
+ attr_reader :result
12
+
13
+ def parse_line!
14
+ take_line! do |line|
15
+ case FCSHD.trim(line)
16
+ when / \((\d+) bytes\)$/
17
+ result.succeeded = true
18
+
19
+ when "Nothing has changed since the last compile. Skip..."
20
+ result.n_compiled_files = 0
21
+
22
+ when /^Files changed: (\d+) Files affected: (\d+)$/
23
+ result.n_compiled_files = $1.to_i + $2.to_i
24
+
25
+ when /^(\/.+?)(?:\((\d+)\))?: (?:col: \d+ )?(.+)$/
26
+ result << Transcript::Item[SourceLocation[$1, $2.to_i], $3]
27
+ skip_indented_lines! # Ignore the "diagram" of the problem.
28
+
29
+ when /^Required RSLs:$/
30
+ skip_indented_lines! # Does anybody care about this?
31
+
32
+ when /^(Recompile|Reason): /
33
+ when /^Loading configuration file /
34
+
35
+ else
36
+ # Let unrecognized lines pass through verbatim.
37
+ if line.start_with? "fcshd: "
38
+ result << line
39
+ else
40
+ # XXX: What about when we support compc?
41
+ result << "mxmlc: #{line}"
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ def take_line!
48
+ yield skip_line!
49
+ end
50
+
51
+ def skip_line!
52
+ current_line
53
+ ensure
54
+ lines.shift
55
+ end
56
+
57
+ def current_line
58
+ lines.first.chomp
59
+ end
60
+
61
+ def skip_indented_lines!
62
+ skip_line! until lines.empty? or current_line =~ /^\S/
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,35 @@
1
+ module FCSHD
2
+ class Transcript
3
+ def self.[] text
4
+ Parser.new(text.split("\n")).parse!
5
+ end
6
+
7
+ def initialize
8
+ @items = []
9
+ end
10
+
11
+ def << item
12
+ @items << item
13
+ end
14
+
15
+ attr_accessor :n_compiled_files
16
+
17
+ def succeeded= value; @succeeded = value; end
18
+ def succeeded?; @succeeded; end
19
+
20
+ def to_s(basedir)
21
+ @items.map do |item|
22
+ case item
23
+ when Item
24
+ item.to_s(basedir)
25
+ else
26
+ item.to_s
27
+ end
28
+ end.join("\n")
29
+ end
30
+
31
+ def nothing_to_do?
32
+ n_compiled_files == 0
33
+ end
34
+ end
35
+ end
data/lib/fcshd/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  unless defined? FCSHD::VERSION
2
2
  module FCSHD
3
- VERSION = "0.3.1"
3
+ VERSION = "0.5"
4
4
  end
5
5
  end
data/lib/fcshd.rb CHANGED
@@ -1,9 +1,16 @@
1
+ module FCSHD
2
+ def self.trim(string)
3
+ string.gsub(/\s+/, " ").gsub(/^ | $/, "")
4
+ end
5
+ end
6
+
1
7
  require "fcshd/compiler"
2
- require "fcshd/compiler-output"
3
- require "fcshd/compiler-output-writer"
4
8
  require "fcshd/flex-home"
5
9
  require "fcshd/logger"
6
10
  require "fcshd/problem"
7
11
  require "fcshd/server"
8
12
  require "fcshd/source-location"
13
+ require "fcshd/transcript"
14
+ require "fcshd/transcript-item"
15
+ require "fcshd/transcript-parser"
9
16
  require "fcshd/version"
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fcshd
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 1
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 3
9
- - 1
10
- version: 0.3.1
8
+ - 5
9
+ version: "0.5"
11
10
  platform: ruby
12
11
  authors:
13
12
  - Daniel Brockman
@@ -15,7 +14,7 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2011-11-02 00:00:00 Z
17
+ date: 2011-12-01 00:00:00 Z
19
18
  dependencies: []
20
19
 
21
20
  description: |
@@ -42,14 +41,15 @@ files:
42
41
  - bin/fcshd
43
42
  - fcshd.gemspec
44
43
  - lib/fcshd.rb
45
- - lib/fcshd/compiler-output-writer.rb
46
- - lib/fcshd/compiler-output.rb
47
44
  - lib/fcshd/compiler.rb
48
45
  - lib/fcshd/flex-home.rb
49
46
  - lib/fcshd/logger.rb
50
47
  - lib/fcshd/problem.rb
51
48
  - lib/fcshd/server.rb
52
49
  - lib/fcshd/source-location.rb
50
+ - lib/fcshd/transcript-item.rb
51
+ - lib/fcshd/transcript-parser.rb
52
+ - lib/fcshd/transcript.rb
53
53
  - lib/fcshd/version.rb
54
54
  homepage: http://github.com/dbrock/fcshd
55
55
  licenses: []
@@ -80,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
80
80
  requirements: []
81
81
 
82
82
  rubyforge_project:
83
- rubygems_version: 1.8.10
83
+ rubygems_version: 1.8.11
84
84
  signing_key:
85
85
  specification_version: 3
86
86
  summary: Usable CLI for the Adobe Flex compiler shell (fcsh)
@@ -1,19 +0,0 @@
1
- module FCSHD
2
- class CompilerOutputWriter
3
- def initialize(output, basedir)
4
- @output = output
5
- @basedir = basedir
6
- end
7
-
8
- def write_uninterpreted_line! line
9
- @output.puts line
10
- end
11
-
12
- def write_problem! problem
13
- location = problem.source_location.with_basedir(@basedir)
14
- for line in problem.formatted_message_lines do
15
- @output.puts "#{location}: #{line}"
16
- end
17
- end
18
- end
19
- end
@@ -1,91 +0,0 @@
1
- module FCSHD
2
- class CompilerOutput
3
- def self.[] text, basedir
4
- new.tap do |result|
5
- Parser.new(text.lines.entries, basedir, result).parse!
6
- end
7
- end
8
-
9
- attr_accessor :n_compiled_files
10
-
11
- def initialize
12
- @events = []
13
- end
14
-
15
- def << event
16
- @events << event
17
- end
18
-
19
- def write! writer
20
- for event in @events
21
- case event
22
- when String
23
- writer.write_uninterpreted_line! event
24
- when Problem
25
- writer.write_problem! event
26
- end
27
- end
28
- end
29
-
30
- def nothing_to_do?
31
- n_compiled_files == 0
32
- end
33
-
34
- def succeeded!
35
- @succeeded = true
36
- end
37
-
38
- def succeeded?
39
- @succeeded
40
- end
41
-
42
- class Parser < Struct.new(:lines, :basedir, :result)
43
- def parse!
44
- parse_line! until lines.empty?
45
- end
46
-
47
- def parse_line!
48
- take_line! do |line|
49
- case line
50
- when /^(Recompile|Reason): /
51
- when /^Loading configuration file /
52
- when /^(.+\.swf) \((\d+) bytes\)$/
53
- result.succeeded!
54
- when "Nothing has changed since the last compile. Skip..."
55
- result.n_compiled_files = 0
56
- when /^Files changed: (\d+) Files affected: (\d+)$/
57
- result.n_compiled_files = $1.to_i + $2.to_i
58
- when /^(\/.+?)(?:\((\d+)\))?: (?:col: (\d+) )?(.+)$/
59
- location = SourceLocation[$1, $2.to_i, $3.to_i, basedir]
60
- result << Problem[location, $4]
61
- skip_indented_lines!
62
- when /^Required RSLs:$/
63
- skip_indented_lines!
64
- when /^fcshd: /
65
- result << line
66
- else
67
- result << "mxmlc: #{line}"
68
- end
69
- end
70
- end
71
-
72
- def take_line!
73
- yield skip_line!
74
- end
75
-
76
- def skip_line!
77
- current_line
78
- ensure
79
- lines.shift
80
- end
81
-
82
- def current_line
83
- lines[0].chomp
84
- end
85
-
86
- def skip_indented_lines!
87
- skip_line! until lines.empty? or current_line =~ /^\S/
88
- end
89
- end
90
- end
91
- end