I was trying to understand how Rails’ asset pipeline works internally, so I had
a quick code reading, annotating with bullet points each important step, then I
thought about sharing it, may be helpful to others.
Note that this is for Rails 3.2.8, all links point to 3.2.8 tagged code.
Sprockets integration with Rails 4.x is extracted to the
sprockets-rails gem.
Rails sets the default asset paths, setting config.assets.paths
(here). config.assets.paths is the array that’s gonna be
appended to the Sprockets environment load path.
Rails sets the default accepted assets paths (rules in fact), setting
config.assets.precompile (here).
config.assets.precompile is the array that stores all rules that will be
used to judge whether a asset is to be compiled or not.
[ User can configure in config/application.rb or
config/environments/<env>.rb more rules to add to
config.assets.precompile ]
Rails instantiates and configures a Sprockets environment via railties using
the configuration above (here)
Rails will postpone configuring the Sprockets environment paths because other
gems could add more paths to the config.assets.paths. Instead, it runs a
Sprockets::Bootstrap after Rails is initialized
(here)
Sprockets::Bootstrap will then append config.assets.paths to the
sprockets env paths (here)
Now assets are configured, assets will be compiled when rake
assets:precompile is called, which will in turn instantiate a
Sprockets::StaticCompiler (provided by action_pack, not sprockets itself)
instance and run (here)
The compiler iterates over every single path inside the load paths,
recursively, and tests each entry against the rules defined in
config.assets.precompile, if any returns positively, it then compiles the
asset and writes to the target directory (all that is here)
This repository was sitting on my GitHub account for a while and I didn’t
really announced anything related to it, partially because I had to polish it
and because at that time I was already late to the party, but as the saying
goes: “better late than never”.
Such a long disclaimer to introduce a repository, right? It’s nothing really.
We know the Ruby (mostly Rails) community has periodical dramas, this was about
yet another one.
This one happened quite some time ago (it’s from March 2012), and it involved
bikesheding (doesn’t all of them somehow involve bikesheding?) about what a
Ruby predicate (a method ending in “?”) should return. Not a freaking big deal,
is it? I am of the opinion that clear code is priority and for the sake of
clarity, returning boolean values on predicates is always good practice. A
rails core member doesn’t think so and states that because truthy values are
truthy, it’s ok to return them on predicates, even if this value is completetly
counter-intuitive like the number zero. Yeah, you can try it:
Today is very common to see social sharing buttons right beside to some content.
Most common ones are Facebook’s
Like, Twitter’s
Tweet and Google’s
+1. They are virtually
everywhere, even on their own documentation pages. Product owners and managers
love them. Common people use them a lot. So they are, in fact, unavoidable. They
are so omnipresent that some even think they are annoying enough to make
browser extensions to block them.
So, in the end, everyone is writing code because of them.
Of course, I was one of them too.
As a content consumer, I do not hate them. They make my life easier by putting
me one click away from telling the whole world what I like and why (ok, that’s
sarcastic). But they actually do help.
As a developer, I do hate them. They suck. They are some little freaking wild
embedded pieces of code that you cannot expect to control. Not on edge cases,
specially those your PO or manager put you into (when they want you to make the
buttons dance with perfect lip-sync to Lady Gaga’s latest hit). I hate them
when they don’t have every possible option to customize their style,
positioning or behavior. And lastly I hate when you use them in a page with 10
items that I want the user to be able to share, and they perform
two hundred requests.
Now, no one likes hundreds of requests. Not my mom, you, your ISP or your cheap
10 buck wireless router (even it not being totally aware of his own existence).
So a really smart thing to do is do not perform hundreds of requests. Right?
Q: You cutie, but how? A: Ok, here is a story that will explain all things: in the
early 2000’s, IBM pioneered something called on-demand computing… no, I’m just
kidding. What you do is: don’t show them bugger buttons. It’s simple.
Q: But kid wants to share my content with his friends! A: You display a handle that will trigger the actual rendering of the
buttons, on-demand.
Attaboy! There is my IT jargon shining on my blog post. Inside a
pointless Questions & meaningless Answers
list. Double score, yes.
Now, you want code, I know. Then take it!
So, after all that shitstorm of non optimized code entangled by all that
commenting, you and me will agree, there’s one question that will be left
forever unanswered:
Sadly, we’re saying good bye to the awesome
toto blog engine and we are moving to, the
more awesome still, Octopress. The reason is that while
toto is simple and efficient, it takes too much time to get some things done,
like syntax highlighting of source code and besides I eventually get it done
writing some really simple and elegant stuff (using Rack middlewares and
pygments), also learning many things in the process, I think I didn’t actually
want to spend my time doing that, because I’d rather spend it writing actual
content (which is much more difficult for us).
Octopress has also some third party plugins (sidebar is filled with those) and
the most important is possibility to create our own custom plugins, so we
decided to give it a try.
Of course this layout isn’t the original, but we’ll eventually get it ported to
Octopress, or even come up with something new. But for now it is what it is.
Nonetheless, nothing better than to start fresh with a fresh new year. Happy
new year to everyone!
The holy grail of encoding, if you didn’t know it before, just follow the link
on the title and read about it. Every other thing in universe uses it to
perform encoding conversion.
This one is my favorite, it will rename files and make them “safe” (this pretty
much depends on the filesystem you’re using. You put a unicode char in a
filename on a FAT32 partition and the universe collapses in a singularity).
It supports sequences of filters that you can create and pass the filenames
through. Very handy.
convmv also renames files, but deals specifically with encoding, so it’s more
powerful and supports a wide range of encodings, very good too.
recode
I couldn’t find its home page, Debian package is “recode”
“recode converts files between character sets and usages.” It supports
sequences like detox, is powerful but a little cumbersome. Note that it
converts file contents, not filenames.
Yesterday I was playing with my bash prompt and for a long-explanation reason,
I ended up needing to strip non-printing sequences from a string (the actual
reason is that I was up to learn and do some advanced bash scripting. I didn’t
need all the complex stuff before). From section PROMPTING of bash(1) man
page, non-printing escape sequences are:
\[ begin a sequence of non-printing characters, which could
be used to embed a terminal control sequence into the
prompt
\] end a sequence of non-printing characters
So it seems pretty easy to match those, isn’t? If done with Ruby, it would be
simply:
but bash’s regexp has no greediness modifiers (like the question mark in Ruby
or PCRE) to be used in the “inside part” of the pattern (the “anything” between
\[ and \]). The usual trick to workaround this is to use a negated pattern of
the right end of the enclosing pattern:
This works with patterns that use single characters to enclose the content, but
what I want is to replace patterns matching content enclosed by pairs of 2
chars, so I would need to use the negation operator !(...). But boy… have I
tried to make it work? Hell, for hours. It’s completely counter-intuitive.
This won’t work:
12
text="aaa<<skipme>>bbb<<skipmetoo>>ccc"echo"${text//<<!(>>)>>/}"# "aaaccc", since /!(>>)/ matches all the "skipme ... skipmetoo" part
so here’s my deal: screw with it. A nice alternate solution seems obvious now:
replace all double-char enclosing sequences with a (very easily distinctive)
single char, then use the solution above.
1234567
# Char 0x06 is the non-printable "ACK".# What are the odds this char will happen inside a string?# You need to use as $var because the regexp won't accept "\x06" in the patternch=`echo -e '\x06'`text="aaa<<skipme>>bbb<<skipmetoo>>ccc"tmp="${text//@(<<|>>)/$ch}"echo"${tmp//${ch}*([^${ch}])${ch}}"# "aaabbbccc"
… and it works. I wrapped it up and added some more stripping utils:
Now let me continue learning bizarre topics and finish my
shell prompt.
Debian openssl package now ships without SSL2
support,
but it was only in experimental/unstable until 1.0.0d was migrated to
testing
that things got messed up for me, since I use testing and Ruby (both 1.8.7 and
1.9.2) have problems (1 and 2)
compiling against a nossl2’ed OpenSSL lib.
While these problems are not fixed (the fix is in trunk, but not backported to
1.8 or 1.9 branches), I fetched the patches from the actual
fix, formatted them and compiled the
rubies with them.
And you can compile Ruby either applying them manually over the source tree
with level 1 (patch -p1 < ruby187.patch) or if you use
rvm (which is very likely), you can use custom
patches when installing rubies. It is explained in rvm’s docs at
https://rvm.beginrescueend.com/rubies/patching/. It is simple as doing:
Quick post. Just a (loosely gathered) compilation of JavaScript resources
(framework collections, libraries, documentation, etc) that I ran into this
weekend.
First Things First
Beware of w3schools. Here’s a very good explanation at w3fools.com.
Just solved a few “obscure” problems and I’m posting them.
Dependencies
Optional (but you would really like to install them) dependencies are:
OpenSSL (Debian-based package: libssl-dev)
readline (Debian-based package: libreadline5-dev [ruby1.8] | libreadline6-dev [ruby1.9]. For Ruby1.8, you must install readline 5, otherwise you’ll get a damn slow prompt)
zlib (Debian-based package: zlib1g-dev)
Here are a few compeling motives on why you’d really like to get them:
No SSL means no ‘net/https’ and no HTTPs for ‘open-uri’
No readline means you can’t hit ‘up arrow’ on IRB and get the previous command (no command history)
No zlib means you can’t install a gem
Long story short, install ‘em. And get the right versions.
If you are using rubber gem to deploy to
Amazon’s EC2 infra-structure and also using
whenever to manage cron jobs, you’ll
probably find yourself thinking how to integrate both.
I myself too was wondering about this. The obvious first try was to add
whenever’s capistrano tasks to config/deploy.rb by following its
recommendation (see
the “Capistrano integration” section). Long story short, it didn’t work. When I
deployed with cap deploy, whenever would actually write to crontab, but
only to be replaced by rubber’s own version later, as we can see in this log:
Last line shows when rubber transforms and runs the common crontab config and
overwrites whenever’s cron jobs.
So, a second, and more successful, try was to avoid capistrano’s regular
recipes and instead add a whenever crontab config to rubber.
One could “quick-and-dirty”-ly add the expected whenever output to
config/rubber/common/crontab file, but a better approach is to create a
config for the db role to install whenever output to crontab:
One note on the above is to pay attention to keep the @additive
configuration so the crontab is appended with this section rather than
overwritten. If you check the config/rubber/common/crontab file, it hasn’t
this entry and effectively overwrites the previous crontab.
And that was it. One cap deploy and the crontab was filled with rubber’s
jobs and whenever’s too.