Gem Hell and other newbie annoyance

Hi I’m new to the Middleman universe, and also to Ruby/Gem/Bundle in general. I chose to build my static web projects in Middleman because of generally good feedbacks on the web, and the belief that this is the most mature framework of its kind.

In the past one week since I started, I have encountered a huge number of road blocks. I would like to highlight what they were.

  1. Firstly, I have no idea how complex the Ruby/Gem/Bundle environment can become. On my Ubuntu system I install Ruby2.1 with apt-get, and usually we only need to ensure the latest version of everything. On Ruby I am constantly encountering version incompatibility, error messages saying “You have activated 4.2 but you need 4.1”, and generally opaque error and warning messages.

I am also rather confused that Bundle Exec is sometimes required to prefix the Middleman build command to fix errors. It would have been better for the Middleman command to automatically pick the current working directory’s Gemfile or vendor directory; this way the user only need to keep track of one variable, his current directory, to execute the correct project.

  1. Second, I wonder why Middleman 4 and 3 are so different? It seems a huge number of errors can crop up just upgrading? Worse is poorly explained error messages and deprecation declarations that do not point exactly at the source (but a cascade of errors pointing everywhere).

  2. The number of moving parts are too many. There is no explanation of what all these are – Sprockets, Tilt, Sass, Slim, Haml, ActiveSupport etc — and many plugins are version-locked — Middleman-Blog, Middleman-Deploy, etc.

  3. The documentation of the main Middleman is insufficient, it leaves a lot of gaps in the handling of variables (the difference between yaml data, @variable, :local, frontmatter etc). Plugins are not explained even though they introduce many magic words and assumptions into the design of the web project.

  4. When an error occurs in a source file, like HAML template, the error line is incorrect by undercounting the front matter.

  5. I am surprised at how many Middleman templates hosted on Github could no longer build properly. I cloned six and only one could build without error.

  6. The file config.rb is a huge roadblock. Is it configuration? or is it executable code? For non-Ruby user it is not obvious, and we tend to assume the former. So head-scratching to find out there is a sequence to how the activate lines should be written.

I am now stuck in an error that Middleman is ignoring the Proxy command. No reason. The source code is cloned from someone’s current Middleman site. I assume I have misconfigured something, but for the life of me I cannot understand what.

I appreciate MM is a complex and rapidly developing codebase but I think right now it has evolved into too much complexity, and rapidly becoming unusable by a non-Ruby expert.

In case someone is actually going to make some fixes to the documentation, I would like to provide a detailed example:

  1. First I go to the Middleman website http://middlemanapp.com and click on Documentation. (Three hours of reading about how this work — nope, still no clue)
  2. Then I click on Project Template to find a project to clone. I picked Middleman_Starter.
  3. From the github, I cloned it to my computer. The README says just Bundle install, then Middleman build. Sounds easy
  4. (Skip over approximately 3 hours to get Ruby, Bundle, and Middleman installed properly…)
  5. Middleman build — returns errors

a.
WARN: Unresolved specs during Gem::Specification.reset:
rack (< 2.0, >= 1.0, >= 1.0.0, >= 1.4.5)
json (>= 1.7.7, >= 1.8.0, ~> 1.7)
WARN: Clearing out unresolved specs.

What does this mean? But appears to still continue

b.
DEPRECATION WARNING on line 87 of /var/lib/gems/2.1.0/gems/compass-core-1.0.3/stylesheets/compass/css3/_deprecated-support.scss: #{} interpolation near operators will be simplified
in a future version of Sass. To preserve the current behavior, use quotes:
unquote(’"$moz-"#{$experimental-support-for-mozilla} “$webkit-”#{$experimental-support-for-webkit} “$opera-”#{$experimental-support-for-opera} “$microsoft-”#{$experimental-support-for-microsoft} “$khtml-”#{$experimental-support-for-khtml}’)
You can use the sass-convert command to automatically fix most cases.

Another warning? Something is deprecated? Does it break a working project? If not
just ignore for now.

c.
Request: /index.html
error build/index.html
layouts/layout.haml:6: syntax error, unexpected ‘:’, expecting =>
…ntent: ‘ie=edge’, “http-equiv”:‘x-ua-compatible’)}>\n <ti…
… ^
layouts/layout.haml:6: syntax error, unexpected ‘)’, expecting tSTRING_DEND
…“http-equiv”:‘x-ua-compatible’)}>\n \n #{_ham…
… ^
layouts/layout.haml:6: syntax error, unexpected $undefined
…ua-compatible’)}>\n \n #{_hamlout.adjust_tabs…
… ^
layouts/layout.haml:10: syntax error, unexpected ‘}’, expecting tSTRING_DEND
));}\n \n <!-- / st…
^
layouts/layout.haml:10: syntax error, unexpected tIDENTIFIER, expecting tSTRING_DEND
…/title>\n \n #{_hamlout.adjust_t…
… ^
layouts/layout.haml:10: syntax error, unexpected $undefined, expecting keyword_do_LAMBDA or tLAMBEG
…e>\n \n #{_hamlout.adjust_tabs(-…
… ^
layouts/layout.haml:13: syntax error, unexpected ‘}’, expecting tSTRING_DEND
));}\n <link#{_hamlout.attribu…
^
layouts/layout.haml:16: syntax error, unexpected ‘}’, expecting tSTRING_DEND
…ress.com’, property: ‘og:url’)}>\n <meta#{
… ^
layouts/layout.haml:17: syntax error, unexpected ‘}’, expecting tSTRING_DEND
…website’, property: ‘og:type’)}>\n <meta#{
… ^
layouts/layout.haml:18: syntax error, unexpected ‘}’, expecting tSTRING_DEND
… Title’, property: ‘og:title’)}>\n <meta#{
… ^
layouts/layout.haml:19: syntax error, unexpected ‘}’, expecting tSTRING_DEND
…’, property: ‘og:description’)}>\n <meta#{
… ^
layouts/layout.haml:20: syntax error, unexpected ‘}’, expecting tSTRING_DEND
…er.png’, property: ‘og:image’)}>\n <!-- / twitter card da…
… ^
layouts/layout.haml:29: syntax error, unexpected tIDENTIFIER, expecting tSTRING_DEND
…ns.txt’)}>\n \n <link#{
… ^
layouts/layout.haml:29: syntax error, unexpected $undefined, expecting keyword_do_LAMBDA or tLAMBEG
…t’)}>\n \n <link#{
… ^
layouts/layout.haml:32: syntax error, unexpected ‘}’, expecting tSTRING_DEND
…el:‘icon’, href:‘favicon.png’)}>\n <!–[if IE]>\n <l…
… ^
layouts/layout.haml:32: syntax error, unexpected ‘]’, expecting keyword_then or ‘;’ or ‘\n’
…avicon.png’)}>\n <!–[if IE]>\n <link rel=“shortcut…
… ^
layouts/layout.haml:32: syntax error, unexpected tIDENTIFIER, expecting keyword_do or ‘{’ or ‘(’
… <!–[if IE]>\n <link rel=“shortcut icon” href=”/fa…
… ^
layouts/layout.haml:47: syntax error, unexpected ‘,’, expecting tSTRING_DEND
));}\n \n\n", -2, false);;_erbout
^
/var/lib/gems/2.1.0/gems/haml-4.0.7/lib/haml/engine.rb:131:in rescue in render' /var/lib/gems/2.1.0/gems/haml-4.0.7/lib/haml/engine.rb:128:in render’
/var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/renderers/haml.rb:35:in evaluate' /var/lib/gems/2.1.0/gems/tilt-1.4.1/lib/tilt/template.rb:103:in render’
/var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/renderers/haml.rb:9:in render' /var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/file_renderer.rb:79:in render’
/var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/method_reference.rb:43:in send_to' /var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/call_with.rb:76:in call_with’
/var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/method_handler.rb:138:in block in redefine_method' /var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/template_renderer.rb:146:in block in render’
/var/lib/gems/2.1.0/gems/activesupport-4.2.5.1/lib/active_support/notifications.rb:166:in instrument' /var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/util.rb:21:in instrument’
/var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/template_renderer.rb:143:in render' /var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/method_reference.rb:43:in send_to’
/var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/call_with.rb:76:in call_with' /var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/method_handler.rb:138:in block in redefine_method’
/var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/sitemap/resource.rb:144:in render' /var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/method_reference.rb:43:in send_to’
/var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/call_with.rb:76:in call_with' /var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/method_handler.rb:138:in block in redefine_method’
/var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/rack.rb:111:in process_request' /var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/rack.rb:65:in block in call’
/var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/rack.rb:64:in catch' /var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/rack.rb:64:in call’
/var/lib/gems/2.1.0/gems/rack-1.6.4/lib/rack/urlmap.rb:66:in block in call' /var/lib/gems/2.1.0/gems/rack-1.6.4/lib/rack/urlmap.rb:50:in each’
/var/lib/gems/2.1.0/gems/rack-1.6.4/lib/rack/urlmap.rb:50:in call' /var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/extensions/minify_javascript.rb:52:in call’
/var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/extensions/minify_css.rb:60:in call' /var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/core_extensions/inline_url_rewriter.rb:61:in call’
/var/lib/gems/2.1.0/gems/rack-1.6.4/lib/rack/head.rb:13:in call' /var/lib/gems/2.1.0/gems/rack-1.6.4/lib/rack/lint.rb:49:in _call’
/var/lib/gems/2.1.0/gems/rack-1.6.4/lib/rack/lint.rb:37:in call' /var/lib/gems/2.1.0/gems/rack-1.6.4/lib/rack/builder.rb:153:in call’
/var/lib/gems/2.1.0/gems/rack-1.6.4/lib/rack/mock.rb:74:in request' /var/lib/gems/2.1.0/gems/rack-1.6.4/lib/rack/mock.rb:56:in get’
/var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/builder.rb:224:in block in output_resource' /var/lib/gems/2.1.0/gems/activesupport-4.2.5.1/lib/active_support/notifications.rb:166:in instrument’
/var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/util.rb:21:in instrument' /var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/builder.rb:217:in output_resource’
/var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/method_reference.rb:43:in send_to' /var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/call_with.rb:76:in call_with’
/var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/method_handler.rb:138:in block in redefine_method' /var/lib/gems/2.1.0/gems/parallel-1.6.2/lib/parallel.rb:408:in call’
/var/lib/gems/2.1.0/gems/parallel-1.6.2/lib/parallel.rb:408:in call_with_index' /var/lib/gems/2.1.0/gems/parallel-1.6.2/lib/parallel.rb:379:in process_incoming_jobs’
/var/lib/gems/2.1.0/gems/parallel-1.6.2/lib/parallel.rb:361:in block in worker' /var/lib/gems/2.1.0/gems/parallel-1.6.2/lib/parallel.rb:354:in fork’
/var/lib/gems/2.1.0/gems/parallel-1.6.2/lib/parallel.rb:354:in worker' /var/lib/gems/2.1.0/gems/parallel-1.6.2/lib/parallel.rb:345:in block in create_workers’
/var/lib/gems/2.1.0/gems/parallel-1.6.2/lib/parallel.rb:344:in each' /var/lib/gems/2.1.0/gems/parallel-1.6.2/lib/parallel.rb:344:in create_workers’
/var/lib/gems/2.1.0/gems/parallel-1.6.2/lib/parallel.rb:301:in work_in_processes' /var/lib/gems/2.1.0/gems/parallel-1.6.2/lib/parallel.rb:232:in map’
/var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/builder.rb:129:in output_resources' /var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/method_reference.rb:43:in send_to’
/var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/call_with.rb:76:in call_with' /var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/method_handler.rb:138:in block in redefine_method’
/var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/builder.rb:123:in output_files' /var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/method_reference.rb:43:in send_to’
/var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/call_with.rb:76:in call_with' /var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/method_handler.rb:138:in block in redefine_method’
/var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/builder.rb:71:in block in run!' /var/lib/gems/2.1.0/gems/activesupport-4.2.5.1/lib/active_support/notifications.rb:166:in instrument’
/var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/util.rb:21:in instrument' /var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/builder.rb:70:in run!’
/var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/method_reference.rb:43:in send_to' /var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/call_with.rb:76:in call_with’
/var/lib/gems/2.1.0/gems/contracts-0.12.0/lib/contracts/method_handler.rb:138:in block in redefine_method' /var/lib/gems/2.1.0/gems/middleman-cli-4.1.1/lib/middleman-cli/build.rb:75:in block in build’
/var/lib/gems/2.1.0/gems/activesupport-4.2.5.1/lib/active_support/notifications.rb:166:in instrument' /var/lib/gems/2.1.0/gems/middleman-core-4.1.1/lib/middleman-core/util.rb:21:in instrument’
/var/lib/gems/2.1.0/gems/middleman-cli-4.1.1/lib/middleman-cli/build.rb:74:in build' /var/lib/gems/2.1.0/gems/thor-0.19.1/lib/thor/command.rb:27:in run’
/var/lib/gems/2.1.0/gems/thor-0.19.1/lib/thor/invocation.rb:126:in invoke_command' /var/lib/gems/2.1.0/gems/thor-0.19.1/lib/thor/invocation.rb:133:in block in invoke_all’
/var/lib/gems/2.1.0/gems/thor-0.19.1/lib/thor/invocation.rb:133:in each' /var/lib/gems/2.1.0/gems/thor-0.19.1/lib/thor/invocation.rb:133:in map’
/var/lib/gems/2.1.0/gems/thor-0.19.1/lib/thor/invocation.rb:133:in invoke_all' /var/lib/gems/2.1.0/gems/thor-0.19.1/lib/thor/group.rb:232:in dispatch’
/var/lib/gems/2.1.0/gems/thor-0.19.1/lib/thor/invocation.rb:115:in invoke' /var/lib/gems/2.1.0/gems/thor-0.19.1/lib/thor.rb:40:in block in register’
/var/lib/gems/2.1.0/gems/thor-0.19.1/lib/thor/command.rb:27:in run' /var/lib/gems/2.1.0/gems/thor-0.19.1/lib/thor/invocation.rb:126:in invoke_command’
/var/lib/gems/2.1.0/gems/thor-0.19.1/lib/thor.rb:359:in dispatch' /var/lib/gems/2.1.0/gems/thor-0.19.1/lib/thor/base.rb:440:in start’
/var/lib/gems/2.1.0/gems/middleman-core-3.4.1/bin/middleman:18:in <top (required)>' /usr/local/bin/middleman:23:in load’
/usr/local/bin/middleman:23:in `’

That’s a lot of errors from one file? I can understand it has something to
do with “layouts/layout.haml:6:”

The offending line is:
%meta{content: ‘ie=edge’, “http-equiv”:‘x-ua-compatible’}

(Skip another 3 hours reading about HAML and how it parses, and the d
difference between Ruby 1.8 and Ruby 1.9 hash. Remember I don’t know
any Ruby …)

Finally I changed the line to this:

%meta{content: 'ie=edge', "http-equiv"=>'x-ua-compatible'}
  1. Middleman Build – ok no error.

So one day spent to build a toy project, just to understand how to set up
a working Middleman environment. Had to learn Ruby, Gem, and HAML as well.

I wonder how someone who is just a content developer and not a programmer is going to cope.

Another example of the unclear documentation: –

After reading about Proxy as a “fake” page template generator, I wrote my test example:

data.venues.each do |i|
proxy “/place-#{i.id}”, “place-template”,
:locals=>{:place=>i}, :ignore=>true
end

Build OK.

I decide to move place-template.haml into a subdirectory “proxy”.
replace “place-template” to “/proxy/place-template”

Still build OK.

Decide to change directory name to “_proxy” (in our team this is our
standard naming).

Build fails.

So there is a hidden undocumented issue about underscores in filename.

How is a sitebuilder going to find out except by trial and error.

Sorry to hear about your frustrations. However, when any developer first dives into a language, they’ll run into stumbling blocks. Give it time to wrap your head around it. Bundler is actually great. I think NPM (JavaScript) and Composer (PHP) are far worse at resolving dependency issues.

  • Underscores by ruby convention are used for partials or “snippets”, basically pieces of a whole. Anything prefixed with an underscore is generally not built in production. This also applies to CSS and JS assets as used in sprockets.
  • The dependency errors you’re getting are a good thing about ruby. Bundler does a great job of trying to reconcile dependency issues.

It sounds like you’re really new to Ruby. I suggest, getting a ruby version manager. The 1.8 vs 1.9 issue you’re describing is probably tougher to debug because it’s ancient history on a tech timescale. Ruby is on 2.3 now.

Read up on Bundler and how it works, esp. the difference between install and update and updating single vs all gems.

This is not meant to be a guide to answer all your questions above, just something to get you started. Middleman is brilliant. Get the hang of Ruby and you’ll love it.

1 Like