Skip to content

Commit c541971

Browse files
committed
Fix loading of overlapping sources in a manifest.
1 parent fcbb91c commit c541971

File tree

7 files changed

+38
-9
lines changed

7 files changed

+38
-9
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:manifest "example"
2+
:sources "src/Main*.savi" // matches both Main.savi and Main.Example.savi
3+
:sources "src/*Example.savi" // matches both Message.Example.savi and Main.Example.savi
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Example output
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
$SAVI
2+
bin/example
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:actor Main.Example
2+
:new (env Env)
3+
env.out.print(Message.Example.string)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:actor Main
2+
:new (env)
3+
Main.Example.new(env)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:module Message.Example
2+
:const string: "Example output"

src/savi/compiler/source_service.cr

+24-9
Original file line numberDiff line numberDiff line change
@@ -297,25 +297,36 @@ class Savi::Compiler::SourceService
297297
def get_sources_for_manifest(ctx, manifest : Packaging::Manifest)
298298
package = Source::Package.for_manifest(manifest)
299299

300-
manifest.sources_paths.flat_map { |sources_path, exclusions|
301-
sources = [] of Source
300+
sources = [] of Source
301+
302+
manifest.sources_paths.each { |sources_path, exclusions|
303+
glob_sources = [] of Source
302304
absolute_glob = File.join(package.path, sources_path.value)
303305
exclusion_paths = exclusions.map { |e| File.join(package.path, e.value) }
304306

305307
prior_source_size = sources.size
308+
found_at_least_one = false
306309
each_savi_file_in_glob(absolute_glob) { |name, content|
307310
# Skip this source file if it is excluded.
308311
next if exclusion_paths.any? { |e| File.match?(e, name) }
309312

310-
# Otherwise add it to the list.
313+
# Note that we found at least one source file in this glob.
314+
found_at_least_one = true
315+
316+
# Split the file path into its two parts.
311317
dirname = File.dirname(name)
312-
basename = File.basename(name)
313-
sources << Source.new(dirname, basename, content, package)
318+
filename = File.basename(name)
319+
320+
# Skip this source file if it already is included.
321+
next if sources.any? { |s| s.filename == filename && s.dirname == dirname }
322+
323+
# Otherwise add it to the list.
324+
glob_sources << Source.new(dirname, filename, content, package)
314325
}
315326

316327
ctx.error_at sources_path,
317-
"No '.savi' source files found in #{absolute_glob.inspect}" \
318-
if sources.empty?
328+
"No new '.savi' source files found in #{absolute_glob.inspect}" \
329+
unless found_at_least_one
319330

320331
# Sort the sources by case-insensitive name, so that they always get loaded
321332
# in a repeatable order regardless of platform implementation details, or
@@ -324,10 +335,14 @@ class Savi::Compiler::SourceService
324335
# Note that we sort each group (from each glob) separately,
325336
# and concatenate them in order of the globs declaration order, so that
326337
# the declaration order can be meaningful if desired.
327-
sources.sort_by!(&.filename.downcase)
338+
glob_sources.sort_by!(&.filename.downcase)
328339

329-
sources
340+
# Finally, add the glob sources to the total sources list.
341+
sources.concat(glob_sources)
330342
}
343+
344+
345+
sources
331346
end
332347

333348
# Given a directory name, load source objects for all the source files in

0 commit comments

Comments
 (0)