Skip to content

Commit 39e26e9

Browse files
committed
Merge pull request #1470 from mgreter/feature/error-on-multiple-imports
Implement error when multiple imports are found
2 parents 3b4f462 + fc6ce56 commit 39e26e9

File tree

7 files changed

+67
-32
lines changed

7 files changed

+67
-32
lines changed

src/context.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -248,17 +248,29 @@ namespace Sass {
248248

249249
// Add a new import file to the context
250250
// This has some previous directory context
251-
std::string Context::add_file(const std::string& base, const std::string& file)
251+
std::string Context::add_file(const std::string& base, const std::string& file, ParserState pstate)
252252
{
253253
using namespace File;
254254
std::string path(make_canonical_path(file));
255255
std::string base_file(join_paths(base, path));
256-
std::string resolved(resolve_file(base_file));
257256
if (style_sheets.count(base_file)) return base_file;
258-
if (char* contents = read_file(resolved)) {
259-
add_source(base_file, resolved, contents);
260-
style_sheets[base_file] = 0;
261-
return base_file;
257+
std::vector<Sass_Queued> resolved(resolve_file(base, path));
258+
if (resolved.size() > 1) {
259+
std::stringstream msg_stream;
260+
msg_stream << "It's not clear which file to import for ";
261+
msg_stream << "'@import \"" << file << "\"'." << "\n";
262+
msg_stream << "Candidates:" << "\n";
263+
for (size_t i = 0, L = resolved.size(); i < L; ++i)
264+
{ msg_stream << " " << resolved[i].load_path << "\n"; }
265+
msg_stream << "Please delete or rename all but one of these files." << "\n";
266+
error(msg_stream.str(), pstate);
267+
}
268+
if (resolved.size()) {
269+
if (char* contents = read_file(resolved[0].abs_path)) {
270+
add_source(base_file, resolved[0].abs_path, contents);
271+
style_sheets[base_file] = 0;
272+
return base_file;
273+
}
262274
}
263275
// now go the regular code path
264276
return add_file(path);

src/context.hpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,12 @@
1616
#include "subset_map.hpp"
1717
#include "output.hpp"
1818
#include "plugins.hpp"
19+
#include "file.hpp"
1920
#include "sass_functions.h"
2021

2122
struct Sass_Function;
2223

2324
namespace Sass {
24-
struct Sass_Queued {
25-
std::string abs_path;
26-
std::string load_path;
27-
const char* source;
28-
public:
29-
Sass_Queued(const std::string& load_path, const std::string& abs_path, const char* source);
30-
};
3125

3226
class Context {
3327
public:
@@ -117,7 +111,7 @@ namespace Sass {
117111
void add_source(std::string, std::string, char*);
118112

119113
std::string add_file(const std::string& file);
120-
std::string add_file(const std::string& base, const std::string& file);
114+
std::string add_file(const std::string& base, const std::string& file, ParserState pstate);
121115

122116

123117
// allow to optionally overwrite the input path

src/file.cpp

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -244,33 +244,39 @@ namespace Sass {
244244
// (2) underscore + given
245245
// (3) underscore + given + extension
246246
// (4) given + extension
247-
std::string resolve_file(const std::string& filename)
247+
std::vector<Sass_Queued> resolve_file(const std::string& root, const std::string& file)
248248
{
249+
std::string filename = join_paths(root, file);
249250
// supported extensions
250251
const std::vector<std::string> exts = {
251252
".scss", ".sass", ".css"
252253
};
253254
// split the filename
254-
std::string base(dir_name(filename));
255-
std::string name(base_name(filename));
255+
std::string base(dir_name(file));
256+
std::string name(base_name(file));
257+
std::vector<Sass_Queued> resolved;
256258
// create full path (maybe relative)
257-
std::string path(join_paths(base, name));
258-
if (file_exists(path)) return path;
259+
std::string rel_path(join_paths(base, name));
260+
std::string abs_path(join_paths(root, rel_path));
261+
if (file_exists(abs_path)) resolved.push_back(Sass_Queued(rel_path, abs_path, 0));
259262
// next test variation with underscore
260-
path = join_paths(base, "_" + name);
261-
if (file_exists(path)) return path;
263+
rel_path = join_paths(base, "_" + name);
264+
abs_path = join_paths(root, rel_path);
265+
if (file_exists(abs_path)) resolved.push_back(Sass_Queued(rel_path, abs_path, 0));
262266
// next test exts plus underscore
263267
for(auto ext : exts) {
264-
path = join_paths(base, "_" + name + ext);
265-
if (file_exists(path)) return path;
268+
rel_path = join_paths(base, "_" + name + ext);
269+
abs_path = join_paths(root, rel_path);
270+
if (file_exists(abs_path)) resolved.push_back(Sass_Queued(rel_path, abs_path, 0));
266271
}
267272
// next test plain name with exts
268273
for(auto ext : exts) {
269-
path = join_paths(base, name + ext);
270-
if (file_exists(path)) return path;
274+
rel_path = join_paths(base, name + ext);
275+
abs_path = join_paths(root, rel_path);
276+
if (file_exists(abs_path)) resolved.push_back(Sass_Queued(rel_path, abs_path, 0));
271277
}
272278
// nothing found
273-
return std::string("");
279+
return resolved;
274280
}
275281

276282
// helper function to resolve a filename
@@ -279,9 +285,8 @@ namespace Sass {
279285
// search in every include path for a match
280286
for (size_t i = 0, S = paths.size(); i < S; ++i)
281287
{
282-
std::string path(join_paths(paths[i], file));
283-
std::string resolved(resolve_file(path));
284-
if (resolved != "") return resolved;
288+
std::vector<Sass_Queued> resolved(resolve_file(paths[i], file));
289+
if (resolved.size()) return resolved[0].abs_path;
285290
}
286291
// nothing found
287292
return std::string("");

src/file.hpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,17 @@
55
#include <vector>
66

77
namespace Sass {
8+
89
class Context;
10+
11+
struct Sass_Queued {
12+
std::string abs_path;
13+
std::string load_path;
14+
const char* source;
15+
public:
16+
Sass_Queued(const std::string& load_path, const std::string& abs_path, const char* source);
17+
};
18+
919
namespace File {
1020

1121
// return the current directory
@@ -41,7 +51,7 @@ namespace Sass {
4151
std::string resolve_relative_path(const std::string& path, const std::string& base, const std::string& cwd = ".");
4252

4353
// try to find/resolve the filename
44-
std::string resolve_file(const std::string& file);
54+
std::vector<Sass_Queued> resolve_file(const std::string& root, const std::string& file);
4555

4656
// helper function to resolve a filename
4757
std::string find_file(const std::string& file, const std::vector<std::string> paths);

src/parser.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ namespace Sass {
304304
}
305305
else {
306306
std::string current_dir = File::dir_name(path);
307-
std::string resolved(ctx.add_file(current_dir, unquoted));
307+
std::string resolved(ctx.add_file(current_dir, unquoted, *this));
308308
if (resolved.empty()) error("file to import not found or unreadable: " + unquoted + "\nCurrent dir: " + current_dir, pstate);
309309
imp->files().push_back(resolved);
310310
}

src/sass_context.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,20 @@ extern "C" {
325325
c_ctx->source_map_string = 0;
326326
json_delete(json_err);
327327
}
328+
catch (const char* e) {
329+
std::stringstream msg_stream;
330+
JsonNode* json_err = json_mkobject();
331+
msg_stream << "Error: " << e << std::endl;
332+
json_append_member(json_err, "status", json_mknumber(4));
333+
json_append_member(json_err, "message", json_mkstring(e));
334+
c_ctx->error_json = json_stringify(json_err, " ");;
335+
c_ctx->error_message = sass_strdup(msg_stream.str().c_str());
336+
c_ctx->error_text = sass_strdup(e);
337+
c_ctx->error_status = 4;
338+
c_ctx->output_string = 0;
339+
c_ctx->source_map_string = 0;
340+
json_delete(json_err);
341+
}
328342
catch (...) {
329343
std::stringstream msg_stream;
330344
JsonNode* json_err = json_mkobject();

src/sass_values.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ extern "C" {
7575
struct Sass_Map map;
7676
struct Sass_Null null;
7777
struct Sass_Error error;
78-
struct Sass_Warning warning;
78+
struct Sass_Warning warning;
7979
};
8080

8181
struct Sass_MapPair {

0 commit comments

Comments
 (0)