Skip to content

Commit d02e788

Browse files
authored
Merge pull request #202 from dahlia/correct_source_map_url
Correct source map url (relative to sourcemap file)
2 parents 29bb9c1 + 143ab28 commit d02e788

File tree

5 files changed

+73
-56
lines changed

5 files changed

+73
-56
lines changed

.travis.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
language: python
2+
dist: trusty
23
python:
3-
- pypy
4-
- pypy3
4+
- pypy-5.4.1
55
- 2.7
66
- 3.4
77
- 3.5

pysass.cpp

+13-8
Original file line numberDiff line numberDiff line change
@@ -560,27 +560,32 @@ PySass_compile_filename(PyObject *self, PyObject *args) {
560560
Sass_Output_Style output_style;
561561
int source_comments, error_status, precision;
562562
PyObject *source_map_filename, *custom_functions, *custom_importers,
563-
*result;
563+
*result, *output_filename_hint;
564564

565565
if (!PyArg_ParseTuple(args,
566-
PySass_IF_PY3("yiiyiOOO", "siisiOOO"),
566+
PySass_IF_PY3("yiiyiOOOO", "siisiOOOO"),
567567
&filename, &output_style, &source_comments,
568568
&include_paths, &precision,
569569
&source_map_filename, &custom_functions,
570-
&custom_importers)) {
570+
&custom_importers, &output_filename_hint)) {
571571
return NULL;
572572
}
573573

574574
context = sass_make_file_context(filename);
575575
options = sass_file_context_get_options(context);
576576

577577
if (PyBytes_Check(source_map_filename)) {
578-
size_t source_map_file_len = PyBytes_GET_SIZE(source_map_filename);
579-
if (source_map_file_len) {
580-
char *source_map_file = sass_copy_c_string(
581-
PyBytes_AS_STRING(source_map_filename)
578+
if (PyBytes_GET_SIZE(source_map_filename)) {
579+
sass_option_set_source_map_file(
580+
options, PyBytes_AS_STRING(source_map_filename)
581+
);
582+
}
583+
}
584+
if (PyBytes_Check(output_filename_hint)) {
585+
if (PyBytes_GET_SIZE(output_filename_hint)) {
586+
sass_option_set_output_path(
587+
options, PyBytes_AS_STRING(output_filename_hint)
582588
);
583-
sass_option_set_source_map_file(options, source_map_file);
584589
}
585590
}
586591
sass_option_set_output_style(options, output_style);

sass.py

+28-25
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ def compile_dirname(
239239
input_filename = input_filename.encode(fs_encoding)
240240
s, v, _ = _sass.compile_filename(
241241
input_filename, output_style, source_comments, include_paths,
242-
precision, None, custom_functions, importers
242+
precision, None, custom_functions, importers, None,
243243
)
244244
if s:
245245
v = v.decode('UTF-8')
@@ -539,30 +539,32 @@ def my_importer(path):
539539
raise TypeError('source_comments must be bool, not ' +
540540
repr(source_comments))
541541
fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
542-
source_map_filename = kwargs.pop('source_map_filename', None)
543-
if not (source_map_filename is None or
544-
isinstance(source_map_filename, string_types)):
545-
raise TypeError('source_map_filename must be a string, not ' +
546-
repr(source_map_filename))
547-
elif isinstance(source_map_filename, text_type):
548-
source_map_filename = source_map_filename.encode(fs_encoding)
549-
if not ('filename' in modes or source_map_filename is None):
550-
raise CompileError('source_map_filename is only available with '
551-
'filename= keyword argument since it has to be '
552-
'aware of it')
553-
try:
554-
include_paths = kwargs.pop('include_paths') or b''
555-
except KeyError:
556-
include_paths = b''
557-
else:
558-
if isinstance(include_paths, collections.Sequence):
559-
include_paths = os.pathsep.join(include_paths)
560-
elif not isinstance(include_paths, string_types):
561-
raise TypeError('include_paths must be a sequence of strings, or '
562-
'a colon-separated (or semicolon-separated if '
563-
'Windows) string, not ' + repr(include_paths))
564-
if isinstance(include_paths, text_type):
565-
include_paths = include_paths.encode(fs_encoding)
542+
543+
def _get_file_arg(key):
544+
ret = kwargs.pop(key, None)
545+
if ret is not None and not isinstance(ret, string_types):
546+
raise TypeError('{} must be a string, not {!r}'.format(key, ret))
547+
elif isinstance(ret, text_type):
548+
ret = ret.encode(fs_encoding)
549+
if ret and 'filename' not in modes:
550+
raise CompileError(
551+
'{} is only available with filename= keyword argument since '
552+
'has to be aware of it'.format(key)
553+
)
554+
return ret
555+
556+
source_map_filename = _get_file_arg('source_map_filename')
557+
output_filename_hint = _get_file_arg('output_filename_hint')
558+
559+
include_paths = kwargs.pop('include_paths', b'') or b''
560+
if isinstance(include_paths, collections.Sequence):
561+
include_paths = os.pathsep.join(include_paths)
562+
elif not isinstance(include_paths, string_types):
563+
raise TypeError('include_paths must be a sequence of strings, or '
564+
'a colon-separated (or semicolon-separated if '
565+
'Windows) string, not ' + repr(include_paths))
566+
if isinstance(include_paths, text_type):
567+
include_paths = include_paths.encode(fs_encoding)
566568

567569
custom_functions = kwargs.pop('custom_functions', ())
568570
if isinstance(custom_functions, collections.Mapping):
@@ -614,6 +616,7 @@ def my_importer(path):
614616
s, v, source_map = _sass.compile_filename(
615617
filename, output_style, source_comments, include_paths, precision,
616618
source_map_filename, custom_functions, importers,
619+
output_filename_hint,
617620
)
618621
if s:
619622
v = v.decode('utf-8')

sassc.py

+1
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ def main(argv=sys.argv, stdout=sys.stdout, stderr=sys.stderr):
153153
output_style=options.style,
154154
source_comments=options.source_comments,
155155
source_map_filename=source_map_filename,
156+
output_filename_hint=args[1],
156157
include_paths=options.include_paths,
157158
precision=options.precision
158159
)

sasstests.py

+29-21
Original file line numberDiff line numberDiff line change
@@ -773,27 +773,6 @@ def test_sassc_source_map_without_css_filename(self):
773773
'actual error message is: ' + repr(err)
774774
assert self.out.getvalue() == ''
775775

776-
def test_sassc_sourcemap(self):
777-
with tempdir() as tmp_dir:
778-
src_dir = os.path.join(tmp_dir, 'test')
779-
shutil.copytree('test', src_dir)
780-
src_filename = os.path.join(src_dir, 'a.scss')
781-
out_filename = os.path.join(tmp_dir, 'a.scss.css')
782-
exit_code = sassc.main(
783-
['sassc', '-m', src_filename, out_filename],
784-
self.out, self.err
785-
)
786-
assert exit_code == 0
787-
assert self.err.getvalue() == ''
788-
assert self.out.getvalue() == ''
789-
with open(out_filename) as f:
790-
assert A_EXPECTED_CSS_WITH_MAP == f.read().strip()
791-
with open(out_filename + '.map') as f:
792-
self.assert_source_map_equal(
793-
dict(A_EXPECTED_MAP, sources=None),
794-
dict(json.load(f), sources=None)
795-
)
796-
797776

798777
@contextlib.contextmanager
799778
def tempdir():
@@ -1399,3 +1378,32 @@ def test_stack_trace_formatting():
13991378
def test_source_comments():
14001379
out = sass.compile(string='a{color: red}', source_comments=True)
14011380
assert out == '/* line 1, stdin */\na {\n color: red; }\n'
1381+
1382+
1383+
def test_sassc_sourcemap(tmpdir):
1384+
src_file = tmpdir.join('src').ensure_dir().join('a.scss')
1385+
out_file = tmpdir.join('a.scss.css')
1386+
out_map_file = tmpdir.join('a.scss.css.map')
1387+
1388+
src_file.write('.c { font-size: 5px + 5px; }')
1389+
1390+
exit_code = sassc.main([
1391+
'sassc', '-m', src_file.strpath, out_file.strpath,
1392+
])
1393+
assert exit_code == 0
1394+
1395+
contents = out_file.read()
1396+
assert contents == (
1397+
'.c {\n'
1398+
' font-size: 10px; }\n'
1399+
'\n'
1400+
'/*# sourceMappingURL=a.scss.css.map */'
1401+
)
1402+
source_map_json = json.loads(out_map_file.read())
1403+
assert source_map_json == {
1404+
'sources': ['src/a.scss'],
1405+
'version': 3,
1406+
'names': [],
1407+
'file': 'a.scss.css',
1408+
'mappings': 'AAAA,AAAA,EAAE,CAAC;EAAE,SAAS,EAAE,IAAS,GAAI',
1409+
}

0 commit comments

Comments
 (0)