sass / libsass

A C/C++ implementation of a Sass compiler
https://sass-lang.com/libsass
Other
4.33k stars 462 forks source link

Sass Compatibility Strategy? #282

Closed chriseppstein closed 10 years ago

chriseppstein commented 10 years ago

With the upcoming release of Sass 3.3, I think it's important for libsass to think carefully about what the compatibility strategy will be going forward.

AFAICT, there's no documentation on what Sass features are supported and which ones are not. Is the 3.2 syntax fully implemented? If not, what's missing? If 3.3 features start to be added before all of 3.2 is present, how can people reliably depend on a specific release to work with their project?

I'd like to get https://github.com/hcatlin/sass-spec integrated into the Sass development process so that as we add new features and fix bugs to Sass, other implementations can be tested for conformance. As I understand it, the biggest issue for sass-spec has been that there are non-semantic differences like whitespace, selector ordering from extended selectors, etc.

In Sass 3.3 we added a new feature detection function. So, in theory, going forward, as long as a 3.3+ sass file parses, the user can work around this issue by branching on the feature's presence.

I also think that sass-spec needs to have attractive html-based output that can clearly report what's passing and what's failing.

Here's what I think users need to know:

  1. Presence or absence of Major Sass features by Sass version.
  2. For each major feature, there should be numerous tests around each of the important aspects of that feature.
  3. For each major feature how buggy is it and what are the known issues and whether they can be worked around. E.g. failure to parse is a bigger deal than a runtime difference when it comes to libraries that want to support several implementations since they can work around runtime differences in their code.

I wanted to kick off this conversation and hope that people could comment on what I've suggested, what I might be missing, and in hopes that we can divvy up some of the labor. Getting libsass interoperable with Sass is a major goal for me in 2014.

chriseppstein commented 10 years ago

CC: @nex3 @hcatlin @akhleung @ericam @snugug @bdkjones

mirisuzanne commented 10 years ago

Yes, please. I don't have anything to add off-hand. If there's any way to help without knowing C or Ruby, I'm happy to help out.

Snugug commented 10 years ago

I'm in a similar position to @ericam. We could probably help by writing generic tests and with the final website?

bdkjones commented 10 years ago

I'm fluent in C, but I've been hesitant to actually crank out any code for libsass for one main reason:

I simply haven't had time to sit down and really look at the code to figure out how everything is structured, what style conventions everyone is using, etc. Plus, the existing code has very few comments in it to help --- I'd really have to go line-by-line to see what's up. That's certainly doable, but it's a lot more intensive than reading a quick comment above a function that says, "This function does X and returns Y." Adding those comments in the future would really help new developers get up to speed on the codebase much faster. (Those comments are also all over Ruby Sass.)

I also think a contribution guide could be useful. Put down some conventions regarding code style:

if (noSpaces) {
   doSomething();
}

vs.

if ( noSpaces )
{
    doSomething();
}

And so forth. I also agree with integrating sass-spec. I think there should be a page that shows that spec in a long list and each point that's not yet implemented/compatible in libsass should be red. It would certainly help focus efforts on the most important issues.

bdkjones commented 10 years ago

That said, I AM about to ship a major update to one of my apps in a few weeks, so I should have a lot more free time on my hands in a month or so. I'll try to get up to speed so I can help out.

chriseppstein commented 10 years ago

@ericam @Snugug I think you can both help a lot with testing and sass-spec tools. No ruby or C/C++ knowledge should be needed for that once we have the infrastructure in place.

HamptonMakes commented 10 years ago

My goal (soon) is to make sass-spec spit out feature compliance reports, etc. Like, something you could put on a website.

Half the sass-spec code was written by a junior ruby developer. I've moved a lot of that code into better classes, but as far as I am concerned, ALL of it could be rewritten. I'm happy to have help building a bad ass test suite.

I'm arranging my life to be able to concentrate on this more over the year.

On Friday, February 7, 2014, Chris Eppstein notifications@github.com wrote:

@ericam https://github.com/ericam @Snugug https://github.com/Snugug I think you can both help a lot with testing and sass-spec tools. No ruby or C/C++ knowledge should be needed for that once we have the infrastructure in place.

Reply to this email directly or view it on GitHubhttps://github.com/hcatlin/libsass/issues/282#issuecomment-34482555 .

akhleung commented 10 years ago

@chriseppstein Thanks for opening this discussion; getting LibSass caught up with the Ruby Sass implementation and community is also one of my goals for this year, and I definitely need support from the more established players. What follows are some issues that have been on my mind in recent months (and if any of them stem from misconceptions or lack of research on my part, then please set me straight!).

Overall, I'm not a heavy user of Sass/CSS (i.e., I make ovens, but I don't bake!), so my approach to LibSass has tended to be very tactical. I would like to participate in the broader issues as the year goes on, but for the short term, I do need to balance that against the sheer volume of work that's required to fix bugs, implement missing features, and get the codebase better organized. So, having said that, I'd also like to encourage everyone to chime in with suggestions and comments, and I hope I'll have some useful ideas to respond with.

Probably the biggest difficulty I've had in re-implementing Sass is that, as a language, it doesn't seem to have a comprehensive or precise specification written up anywhere (not counting the reference implementation itself, of course). This had led to numerous mistaken assumptions and misconceptions on my part regarding how Sass works, particularly for subtle edge-casey things (E.g., what happens when you nest media queries? The sass-lang docs say that they'll be combined with and. But it's actually more complicated than that, depending on how the media types match up! Also, in what order are nested combinations of media queries and rulesets rendered? Et cetera.). Granted, maybe I could have averted all this if I had simply done a line-by-line port of the reference implementation, but ... well, I'm sure you're familiar with Larry Wall's remark about the laziness, impatience, and hubris of programmers....

Anyway, to address the specific points that @chriseppstein mentioned in his post:

General feature compatibility -- @hcatlin and I definitely want to make some kind of comprehensive grid, but does Sass itself have such a thing? I've glanced at the changelogs, but it would be helpful if all that information was tabulated somewhere (and if it isn't, then I'm guessing that I just volunteered for the task?). Also, it's sometimes hard for me to decide what's a discrete feature, versus what's a fundamental property of the language (E.g., is nesting a feature, or is it so fundamental and pervasive that there's no point in listing it? What about nestable media queries? Variables? Interpolation? Arithmetic? Etc.). On top of that, the fact that SCSS is a superset of CSS, which is itself evolving to include Sass-like features, makes things even fuzzier for me (e.g., nested media queries were once a Sass-only thing, but now they're "normal" in CSS3). It would be very helpful if some kind of official feature table were available for recent Sass versions.

Feature prioritization and versioning -- I've been thinking that the simplest thing would be to make LibSass version numbers follow the Ruby Sass version numbers, and our goal would be complete feature parity between matched versions (obviously we're not there yet; we'd have to declare a target (probably 3.2) and make it happen). But the downside would be issues like #278; apparently, this 3.3 feature is expected to be widespread enough such that I've been encouraged to implement it even before finishing the remaining 3.2 features. I'm open to suggestions as to how to reconcile these issues.

Sass-Spec -- Looks like @hcatlin has already commented. I'll add that he had mentioned that you have some idea about how to overcome the problem of non-semantic discrepancies (something about getting Sass to output its AST?).

Anyhoo, just wanted to get my perspective out there, and hopefully this will encourage more discussion.

mirisuzanne commented 10 years ago

In my mind, the fact that Sass is a superset of CSS should actually make any feature determination fairly straight-forward.

The core "assumed" language is CSS. Anything we add is a Sass feature, and should be documented. Nesting is a feature, and nested media-queries are a feature if we are doing something other than outputting them directly. If nested media-queries are possible in CSS, but we still do something extra with nested queries - that extra tooling is a feature.

It may be common for features to disappear as they become integrated directly in CSS, but that should be something we can handle.

chriseppstein commented 10 years ago

hard for me to decide what's a discrete feature, versus what's a fundamental property of the language

This is something I can help with :)

Sass is that, as a language, it doesn't seem to have a comprehensive or precise specification written up anywhere.

A formal specification is a lot of work. @nex3 and I have talked about making one, but it's a ton of work and offers very little benefit compared to just collaborating with the few viable implementations.

I definitely want to make some kind of comprehensive grid, but does Sass itself have such a thing? ... It would be very helpful if some kind of official feature table were available for recent Sass versions.

Not in that form. The language reference does document every feature, but the edge cases are only covered in our tests. Turning this into a properly named list of features is a task that needs to happen as part of this effort. Fortunately, @nex3 is a nazi about the CHANGELOG, so it shouldn't be hard to create a 3.2 baseline and start creating a clear list of 3.3 features based on it.

this 3.3 feature (!global) is expected to be widespread enough such that I've been encouraged to implement it even before finishing the remaining 3.2 features. I'm open to suggestions as to how to reconcile these issues.

I agree. This is a conundrum and it's actually what prompted me to start this thread. I don't know what the answer is. But whatever the answer that is decided, I think it should be communicated clearly so that users can know what to expect and how to manage their decision about when to upgrade. Personally, I think feature detection is the best way instead of trying to create perfect reproductions of specific releases. But I just don't know how feasible that is in a error-generating compiler (CSS itself is more forgiving by having well defined parse-error recovery rules as a future-proofing capability -- i'm told this makes a CSS Parser implementation much more complicated than it would be otherwise).

something about getting Sass to output its AST?

So I tried to build something to do this, but it turned out to be much more complicated than I expected. So what I'm thinking now is to have a pure css parser that can simply read in any sass implementation output and normalize the output back out as a string using the same pretty-printer and doing whatever simple normalization steps we feel are necessary to avoid false negatives. E.g. sorting comma-delimited selectors.

FYI: Release Velocity

Going forward ruby sass's release velocity is going to increase. We're going to start shipping every few months with fewer features in every release. I can ensure that we keep sass-spec up-to-date as we develop there, but it does create issues for libsass.

xzyfer commented 10 years ago

libsass compatibility is a hot topic internally at the moment since we've invested heavily in sass over the last 12months and build times are a big issue.

I'm looking at building a compatibility chart akin to http://html5test.com/ backing off sass-spec. I think that would a big win for consumers to wanting to asses the viability of libsass (or other implementations in the future). I'd be happy to work with @ericam and @Snugug to build this as it will require a considerable investment in sass-spec.

xzyfer commented 10 years ago

So I tried to build something to do this, but it turned out to be much more complicated than I expected. So what I'm thinking now is to have a pure css parser that can simply read in any sass implementation output and normalize the output back out as a string using the same pretty-printer and doing whatever simple normalization steps we feel are necessary to avoid false negatives. E.g. sorting comma-delimited selectors.

@chriseppstein if I'm understanding correctly, this may be close to what you're after https://github.com/reworkcss/css-parse

akhleung commented 10 years ago

Hmm ... having skimmed the Rework parser, it looks too "coarse-grained" to be able to do the sort of normalization that we'd need (for example, it matches the right-hand side of a style declaration as a single chunk of text, whereas we would need something that can break down every little subexpression).

nschonni commented 10 years ago

What about PostCSS https://github.com/ai/postcss

lydell commented 10 years ago

FYI: Both css-parse and postcss parse neither selectors nor declaration values (and some at-rule stuff). There is a WIP yet inactivate CSS value parser, though.

A little idea: What about using phantomjs and the CSS object model stuff?

nex3 commented 10 years ago

Why not use the Ruby Sass parse tree?

lbastendorff commented 10 years ago

Yui compression uses the mozilla ast tree for javascript and css decoding and encoding.

Perhaps a java tool to normalise the css is the way forward.

A while back I was working on a java wrapper round libsass and I wrote a test library that compiled code with ruby sass via jruby (for my purpose I embedded the compass gem inside the jruby jar and got that working) ;) I then compiled the sass code with libsass via my java wrapping and collected junit results.

Writing and algorithm to compare the two files without considering whitespace was ok for my simple tests.

All I proved was there is a long way ti go on compass support.

I should push what I have on git hub but I'm a perfectionist and its not perfect.

lbastendorff commented 10 years ago

Some corrections to my previous post! - Looks like I jumped the gun and got over excited while I didn't have access to a computer to check myself :(

OK, I'm looking at what Java code I have and the unit tests I refer to were comparing the libsass input/output with the examples in sass-spec. I did not compare the ruby results with the libsass ones.

But I do have Java code that can produce results from Ruby and separate Java code that can produce results from libsass. Also I do have JUnit tests that are comparing two inputs without considering whitespace.

Regarding normalisation I would definitely focus on a solution using a CSS Abstract Syntax Tree if there is one available but although the Yui compressor does use Rhino's AST engine for JavaScript compression I was wrong about it doing the same for CSS compression. It just uses string and regex...

lbastendorff commented 10 years ago

CSS Abstract Syntax Tree: https://github.com/css/gonzales

Jakobud commented 10 years ago

What's the status of 3.3 support?

HamptonMakes commented 10 years ago

@Jakobud that's a complicated question. We have most of the features with our 3.0 release that is pending. But, we do not have variable scoping yet or looping over maps.

I'm going to close this issue. It's a great discussion and one that will always be continuing. I know that Chris and Natalie and myself have been discussing this at length now. No firm decisions are made, but we are building sass-spec to be an official representation about what Sass should do.