Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Major Changes][Sprockets 3 for LESS] Using versionized classes #5

Open
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

bogdanRada
Copy link

@bogdanRada bogdanRada commented Aug 25, 2016

Hello.
I recently added support for Sprockets 3 for sprockets-sass gem ( here: petebrowne/sprockets-sass#38 ) and here petebrowne/sprockets-sass#39

After some discussion in the first pull request, we decided to use versionized classes, so that would be easier to maintain compatibility with other sprockets versions, so this uses same structure,

Basically the V2 classes will be used for sprockets 2.x
V3 ...for Sprockets 3.x
and V4...for Sprockets 4.x

The Registration class will automatically require the classes based on the version of sprockets loaded.

This pull request will also DROP Ruby 1.9 and also DROP TILT DEPENDENCY*

This pull request fixes some issues:

  • The importer can now import from globbed files and from deeply nested files
  • And now LESS files can be cached, using a custom cache store.

All tests are now passing for both 2.x and 3.x , except 6 tests related to the helpers we have for assets ( Which are broken because i honestly haven';t found a way to pass arguments to this methods, besides the first argument )

 body { background: asset-path("image.jpg", @prefix: '/themes'); }

This seems to thow "Unrecognized input" when trying to parse it with the Less::Parser .
I am going to still try and fix this, but i think this is not available for our less.js version (1.6.1) which is loaded by `less.rb`` (version 2.6.0 -- the last version)

There is though LESS.js version 1.7.1, which has support for this, but the less.js repository hasn't been updated though :(

Also there are some changes done for Sprockets 4.x but that is not yet complete. It does not fully support it yet.

But wanted to get some feedback on this, and maybe we can release the changes for sprockets 3.x and fix those other issues in other pull requests.

Let me know what you think. Have a nice day :)

P.S. If you have any idea how to pass those arguments to those helpers i would really appreciate.

@lloeki
Copy link
Owner

lloeki commented Aug 29, 2016

Thank you for this, I'll try to look into it soon!

@bogdanRada
Copy link
Author

Thank You too. I have an idea how to fix the issue with the helpers ...but i am going to be out of the country for the next 3 weeks. Will continue working on that after i return. Thank You for the response and i can't wait to hear more from You :)

@bogdanRada
Copy link
Author

I added few more commits but rebased again and squashed all commits. I fixed the issue with the helpers, now all tests are passing for sprockets 2.x and 3.x . There is still some work left to be done for sprockets 4.x but that can be done in another pull request.

Please review again this pull request and let me know what you think :) Thank you very much

@bogdanRada
Copy link
Author

The tests are passing locally, on Travis they fail because travis somehow uses an older bundler version. Left a comment on this issue travis-ci/travis-ci#5831 . Hopefully someone will find a solution for travis.

@bogdanRada
Copy link
Author

bogdanRada commented Sep 28, 2016

@lloeki , can you please review this pull request again? I fixed some issues with the importer and also the function parsing. I removed also ruby 2.0 and 2.1.5 from Travis YML file since 2.0 is not maintained anymore and 2.1.5 causes issues with bundler (because Travis has a older version of travis on server)

I also tested this implementation with sprockets 3.x with a real application and works fine .

Let me know what you think. Thank you very much.

@lloeki
Copy link
Owner

lloeki commented Sep 28, 2016

I was seeing your commits pouring in, so waited for you to ping me back that you were done :-) I'll look into it soon.

@bogdanRada
Copy link
Author

bogdanRada commented Sep 28, 2016

Thanks :) , i fixed a minor issue . Replaced "compact.flatten" with "flatten.compact" in lib/sprockets/less/functions.rb. Checked other places. Should be good to go now :)

Support for Sprockets 4.x is not ready yet, but will continue on that on another pull request.

@bogdanRada bogdanRada force-pushed the feature/sprockets-3 branch 2 times, most recently from 5254e6f to 4af6a32 Compare September 28, 2016 09:04
@bogdanRada
Copy link
Author

Hello. I am just curios :) @loeki did you had any chance to look at this pull request? :)

@bogdanRada
Copy link
Author

The issue with the helpers was fixed. Had to hack it a bit though...but it works.

Let me know if something needs to Be changed or refactored or something...Thanks a lot :)

@lloeki
Copy link
Owner

lloeki commented Dec 14, 2016

Wow it'd been so long since I've promised looking at this, sorry! Thanks a lot for your continued effort on this. I have a couple things to do but I'll be looking at it afterwards.

@bogdanRada
Copy link
Author

It's been 5 months since last reply. Any chance of this getting reviewed? Please .

@lloeki
Copy link
Owner

lloeki commented May 15, 2017

Sorry, I'll have a look at it today.

.travis.yml Outdated
- 2.1.0
- 2.2.2
- 2.2.3
- 2.3.1
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have 2.4 here too?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added ruby 2.4.1 to travis

.travis.yml Outdated
- 2.1.0
- 2.2.2
- 2.2.3
- 2.3.1
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, can those be specified as major.minor so that we get the latest patch automatically? I can't recall if Travis allows this.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think Travis has that ability .


# This is needed so that on rubygems.org we can see the actual date
# of the published version due to changes in Rubygems repo over the last year(2015 - 2016)
s.date = Date.today
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have an issue here with ruby 2.4 (ruby 2.3 plows through fine):

[!] There was an error parsing `Gemfile`: 
[!] There was an error while loading `sprockets-less.gemspec`: uninitialized constant Date

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is from bundler actually and i fixed it now.

# For Sprockets 2.x , although the file and the module name exist,
# they can't be used because it will give errors about undefined methods, because this is included only on Sprockets::Base
# and in order to use them we would have to subclass it and define methods to expire cache and other methods for registration ,
# which are not needed since Sprockets already knows about that using the environment instead internally
Copy link
Owner

@lloeki lloeki May 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra space before know. Also, can you hard-wrap this comment to 79?

::Less::Parser.class_eval do
attr_reader :tree


Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove that extra line.

end

return hash
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove return keyword.

arr << { match: m, index: offset } unless m.nil?
str = str[(offset + 1)..-1]
end
arr.uniq {|hash| hash[:match] }
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add blank line before implicit return value

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, missing space after {

default_less_config[:load_paths] = default_less_config[:load_paths].concat(default_less_config[:paths]) if default_less_config[:paths].is_a?(Array)
less = default_less_config
less = merge_less_options(less.dup, @less_config) if defined?(@less_config) && @less_config.is_a?(Hash)
less
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add blank line before implicit return value

options[:load_paths] = options[:load_paths].is_a?(Array) ? options[:load_paths] : []

if (load_paths = options[:paths]) && (other_paths = other_options[:paths])
options[:load_paths] = options[:load_paths]+ other_paths + load_paths
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space around +

fetch_importer_class.fetch_all_dependencies(data, filename, less_options, css_options)
end

def merge_less_options(options, other_options)
Copy link
Owner

@lloeki lloeki May 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is side-effectful on both options and other_options? I'd have expected only options to suffer from side effects (like Hash#merge!). Maybe some dup is in order, or explain the rationale and/or behaviour in a comment.

options[:load_paths] = options[:load_paths]+ other_paths + load_paths
end
options[:load_paths] = options[:load_paths].concat(context.environment.paths)
options
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove extra spaceAdd blank line before implicit return value


def css_options
css_keys = [:compress, :optimization, :silent, :color]
Hash[less_options.to_enum.to_a.select{|k, _| css_keys.include? k}]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add blank line before implicit return value

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spaces all around block's { and }

else
css
end

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove blank line

data = Sprockets::Less::Utils.read_file_binary(filename, options)
new_data, dependencies = process_dependencies(data)

css = less_engine(new_data, less_options, css_options)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove extra space before =

end
else
css
end
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 135 exit point is easily overlooked due to too much nesting. Turn if css.nil? and if context.respond_to?(:metadata) into guard clauses that return css.

run
end


Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove extra blank line

@filename = input[:filename]
@source = input[:data]
@context = input[:environment].context_class.new(input)
run
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add blank line before implicit return value

engines = get_engines_from_attributes(context, attributes)
preprocessors = get_context_preprocessors(context, content_type)
additional_transformers = get_context_transformers(context, content_type, path)
additional_transformers.reverse + preprocessors + engines.reverse
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add blank line before implicit return value

def content_type_of_path(context, path)
attributes = context.environment.attributes_for(path)
content_type = attributes.content_type
[content_type, attributes]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add blank line before implicit return value

def filtered_processor_classes
classes = [Sprockets::Less::Utils.get_class_by_version('LessTemplate')]
classes << Tilt::LessTemplate if defined?(Tilt::LessTemplate)
classes
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add blank line before implicit return value

# Returns nil if the path is already to a partial.
def partialize_path(path)
return unless path.basename.to_s !~ /\A_/
Pathname.new path.to_s.sub(/([^\/]+)\Z/, '_\1')
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add blank line before implicit return value

relative_path = base_path.relative_path_from(root_path).join path
paths.unshift(relative_path, partialize_path(relative_path))
end
[paths, root_path]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add blank line before implicit return value


# Find base_path's root
paths, root_path = add_root_to_possible_files(context, base_path, path, paths)
[paths.compact, root_path]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add blank line before implicit return value

return found if context.asset_requirable?(found)
end
end
nil
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Enumerable#find instead of each

@bogdanRada
Copy link
Author

Travis currently is failing , there seem to be some kind of caching problem, i am still trying to figure that out. Seems strange though, for other repositories i use same configuration, but for this repository it doesn't want to work . Need to spend more time investigating this problem

context = less_options[:custom][:sprockets_context]
(pathname = resolve(context, path, base_path)) || (return nil)
context.depend_on pathname
dependencies << pathname
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add blank line after to make the structure more clear

css = find_relative(import_path, pathname, less_options, css_options)
data_to_parse.gsub!(/^\s*@import\s*['"]#{Regexp.escape(import_path)}['"]\s*;/, css)
end
end
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add blank line after to make the structure more clear

final_css
end


Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove extra blank line


def font_path(source, options = {})
if options[:from_url] || (options.is_a?(Hash) && options.keys.size > 0)
quote(sprockets_context.font_path(source, map_options(options)))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indent by 2

@environment = environment
end


Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove extra blank line

return if obj[:version] != version || obj[:sha] != sha
obj[:obj]
end

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove blank line between end

obj = environment.send(:cache_get, "less/#{key}")
return unless obj.is_a?(Hash)
return if obj[:version] != version || obj[:sha] != sha
obj[:obj]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add blank line before implicit return value

@lloeki
Copy link
Owner

lloeki commented May 15, 2017

Wow that was one hell of a review, nice piece of work, thanks a lot! I didn't find much questionable things :D Mostly that's about some style issues.

So let me know if you can find anything on the Travis front, fix the nitpicks and we can finally get this merged!

preprocessors = get_context_preprocessors(context, content_type)
additional_transformers = get_context_transformers(context, content_type, path)
postprocessors = get_context_postprocessors(context, content_type)
engines.reverse + preprocessors + additional_transformers.reverse + postprocessors
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add blank line before implicit return value

content_type, attributes = content_type_of_path(context, path)
processors = get_all_processors_for_evaluate(context, content_type, attributes, path)
filter_all_processors(processors)
evaluate_path_from_context(context, path, processors)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add blank line before implicit return value

def get_context_transformers(context, content_type, path)
available_transformers = context.environment.transformers[content_type]
additional_transformers = available_transformers.key?(syntax_mime_type) ? available_transformers[syntax_mime_type] : []
additional_transformers.is_a?(Array) ? additional_transformers : [additional_transformers]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add blank line before implicit return value

s.add_development_dependency 'test_construct', '~> 2.0'
s.add_development_dependency 'rake'
s.add_development_dependency 'appraisal', '~> 2.1', '>= 2.1'
s.add_development_dependency 'rake', '>= 10.5', '>= 10.5'
end
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add rubocop as a version-softlocked development dependency:

  s.add_development_dependency 'rubocop', '~> 0.46.0'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants