required file not seen on heroku in jekyll blog - ruby

This is my dir structure
.
├── _layouts
│   └── default.html
├── _posts
├── _site
│   ├── config.ru
│   ├── devart.rb
│   └── index.html
├── config.ru
├── devart.rb
└── index.html
My config.ru
require 'devart.rb'
run Sinatra::Application
When I push this to heroku in the log files I see this error saying devart file is not found during the require. What the heck am I doing wrong??
<internal:lib/rubygems/custom_require>:29:in `require': no such file to load -- devart (LoadError)

Ruby 1.9.2 no longer has current dir in loadpath. So changed to
require './devart.rb'
to get it to work.

Related

Install Ruby gem with Native Extension

I am creating a new gem that uses FFI to create a ruby binding to webview C library
The gem structure is as follows:
.
├── ...
├── Rakefile
├── ext
│   └── webview
│   ├── extconf.rb
│   ├── webview.cc
│   └── webview.h
├── lib
│   ├── webview
│   │   └── version.rb
│   ├── webview.rb
│   └── webview.so
├── ...
└── webview.gemspec
The Rakefile is as follows:
require "bundler/gem_tasks"
require "rubocop/rake_task"
require "rake/extensiontask"
RuboCop::RakeTask.new
task default: :rubocop
Rake::ExtensionTask.new "webview"
The Gemspec is as follows:
# frozen_string_literal: true
require_relative "lib/webview/version"
Gem::Specification.new do |spec|
...
# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
spec.files = Dir.chdir(File.expand_path(__dir__)) do
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
end
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
spec.extensions = ["ext/webview/extconf.rb"]
# Uncomment to register a new dependency of your gem
spec.add_dependency "ffi"
spec.add_dependency "rake-compiler"
end
When I run rake compile it compiles the library and adds webview.so to the lib/ dir.
But when I run rake install:local the webview.so is not in place!
What's wrong?
I needed to add the ext folder to git using git add ext/ this way git ls-files was able to capture it and includes the file in the installation process.
Also, I followed the convention of rubygems by moving webview.rb into lib/webview/ and created a webview.rb in lib/ that contains only:
require_relative "webview/webview"
Also, I added this block to Rake::ExtensionTask in Rakefile:
Rake::ExtensionTask.new "webview" do |ext|
ext.lib_dir = "lib/webview"
end
in order to move the shared object inside lib/webview/
Last thing, I did is to call ffi_lib with absolute path not relative path like this:
ffi_lib File.dirname(__FILE__) + '/webview.so'
And Voila! it works

What is the recommended folder structure for a Ruby command-line app with tests?

I'm new to the Ruby development ecosystem and learning Rails in my spare time. However, I would like to build a command-line app from scratch with unit tests as a part of my learning.
What is the recommended structure for a Ruby command-line project? The one I came up with is
/test
- person_test.rb
/src
- person.rb
main.rb
Gemfile
Gemfile.lock
Thanks
Unit Tests for Gems
If you're using MiniTest or similar, the expected place within gem foo would be foo/test. If you're using RSpec or minitest/spec, then you'd use foo/spec instead.
When you generate a new gem skeleton with Bundler it provides the following defaults:
$ bundle gem foo; tree foo
foo
├── Gemfile
├── README.md
├── Rakefile
├── bin
│   ├── console
│   └── setup
├── foo.gemspec
├── lib
│   ├── foo
│   │   └── version.rb
│   └── foo.rb
└── spec
├── foo_spec.rb
└── spec_helper.rb
4 directories, 10 files
The default Rakefile is set up to run RSpec, but you can certainly implement the Rakefile's default task and your tests any way you'd like.

Manually testing a Ruby CLI

I'm building a CLI gem with Ruby using Thor. I run rake install which runs rake build then the task to install the gem locally. However when I try to run it in the commandline, it cannot locate the command. The gem is called smokestack so theoretically I should be able to run it in terminal once it's installed.
Structure:
├── CODE_OF_CONDUCT.md
├── Gemfile
├── Gemfile.lock
├── LICENSE.txt
├── README.md
├── Rakefile
├── bin
│   ├── console
│   ├── setup
│   └── smokestack
├── lib
│   ├── smokestack
│   │   ├── build.rb
│   │   ├── cli.rb
│   │   └── version.rb
│   └── smokestack.rb
├── pkg
│   └── smokestack-0.1.0.gem
├── smokestack.gemspec
└── test
├── build_test.rb
├── smokestack_test.rb
└── test_helper.rb
bin/smokestack:
#!/usr/bin/env ruby -wU
require 'smokestack'
Smokestack::Cli.start(ARGV)
You can see in the tree the pkg folder from when I ran rake install.
Here's the result when I run that:
smokestack 0.1.0 built to pkg/smokestack-0.1.0.gem.
smokestack (0.1.0) installed.
I then run smokestack in my terminal and get the error: zsh: command not found: smokestack
I've also tried gem install --local ~/path/to/gem/pkg/gem.gem
Result:
Successfully installed smokestack-0.1.0
Parsing documentation for smokestack-0.1.0
Done installing documentation for smokestack after 0 seconds
1 gem installed
This results in the same 'command not found error'.
Question How am I supposed to run this CLI locally to test it out during development?
It ideally interacts with the current project it's in, so just running bundle exec bin/smokestack inside of it's own directory won't yield the results I need properly. It should be a system CLI anyway right?
Here is the repo for additional context if necessary.
There were a couple things going wrong with this. First, bundle moved executable out of /bin to /exe. See [this article(http://bundler.io/blog/2015/03/20/moving-bins-to-exe.html) for reference.
I moved bin/smokestack to exe/smokestack.
You also have to make sure and stage your files, cause the .gemspec files gets the gem files list by running git ls-files. Now that all that is done, everything appears to be working.

Testing Jekyll plugin with Cucumber

I am developing a plugin for Jekyll and want to use Cucumber and Aruba to test it. My plugin is currently just adding a command to Jekyll like it specifies here: https://jekyllrb.com/docs/plugins/#commands I'm bundling this as a gem.
This is the structure of my gem folder:
├── Gemfile
├── Gemfile.lock
├── LICENSE.txt
├── README.md
├── Rakefile
├── bin
│   ├── console
│   └── setup
├── features
│   ├── hello_world.feature
│   ├── step_definitions.rb
│   └── support
│   └── env.rb
├── hello_world.gemspec
├── lib
│   ├── hello_world
│   │   └── version.rb
│   └── hello_world.rb
├── pkg
│   └── hello_world-0.1.0.gem
└── spec
├── hello_world_spec.rb
└── spec_helper.rb
This is my lib/hello_world.rb file:
require "hello_world/version"
require "jekyll"
module Jekyll
module Commands
class Hello < Command
class << self
def init_with_program(prog)
prog.command(:hello) do |c|
c.action do |args, options|
Jekyll.logger.info "Hello world!"
end
end
end
end
end
end
end
Here is my features/hello_world.feature file:
Feature: Hello world
As a hacker who likes to blog
I want to have a custom Jekyll command
Scenario: Show Hello world
When I run `jekyll hello`
Then the output should contain "Hello world!"
And the exit status should be 0
However this is what I get:
$ cucumber
Feature: Hello world
As a hacker who likes to blog
I want to have a custom Jekyll command
Scenario: Show Hello world # features/hello_world.feature:6
When I run `jekyll hello` # aruba-0.14.2/lib/aruba/cucumber/command.rb:13
Then the output should contain "Hello world!" # aruba-0.14.2/lib/aruba/cucumber/command.rb:159
expected "fatal: 'jekyll hello' could not be found. You may need to install the jekyll-hello gem or a related gem to be able to use this subcommand. " to string includes: "hello world" (RSpec::Expectations::ExpectationNotMetError)
features/hello_world.feature:8:in `Then the output should contain "Hello world!"'
And the exit status should be 0 # aruba-0.14.2/lib/aruba/cucumber/command.rb:277
Failing Scenarios:
cucumber features/hello_world.feature:6 # Scenario: Help show a helpful message
1 scenario (1 failed)
3 steps (1 failed, 1 skipped, 1 passed)
I believe that the issue must have something to do with the way Jekyll plugins are required: https://jekyllrb.com/docs/plugins/#installing-a-plugin They are supposed to be required in the :jekyll_plugins group of the Gemfile.
In my Gemfile I have tried just referencing just the gemspec and trying to include the gemspec into the :jekyll_plugins group like this and neither option has worked:
source 'https://rubygems.org'
gemspec :group => :jekyll_plugins
I have also tried building my gem, installing it locally and then using it in a test Jekyll build (including via the :jekyll_plugins group in the Gemfile) and it works correctly.
How can I get my plugin's command to "register" correctly with Jekyll so that it is available for my Cucumber test?
One way to achieve this would by defining a step-definition that creates a fixture site with the proper Gemfile
Feature: Hello world
As a hacker who likes to blog
I want to have a custom Jekyll command
Scenario: Show Hello world
Given I have a fixture site
When I run `jekyll hello`
Then the output should contain "Hello world!"
And the exit status should be 0
In the above, executing the Given step is supposed to create a fixture site with a Gemfile that points to your plugin and a basic jekyll-config file. (Edit your step_definitions.rb file to do so)
# Gemfile
gem "jekyll", "~> 3.6"
group :jekyll_plugins do
# point to the location of your plugin's gemspec, relative to this file
gem "hello_world", :path => "path/to/repo root"
end

Creating Ruby Gem

I'm learning ruby and I wanted to test how to create gem file. I have followings installed in my machine.
ruby 1.9.3p362 (2012-12-25 revision 38607) [x86_64-linux]
Bundler version 1.2.3
rake, version 10.0.3
I created a gem using bundle gem hello_gem. I added following sample code to hello_gem.rb
module HelloGem
class Base
def self.hello
puts "Hello Ruby Gem #{HelloGem::VERSION}"
end
end
end
My folder structure is like follows.
├── Gemfile
├── Gemfile.lock
├── hello_gem.gemspec
├── lib
│   ├── hello_gem
│   │   └── version.rb
│   └── hello_gem.rb
├── LICENSE.txt
├── Rakefile
├── README.md
Then I created the gem using rake install. Then I started irb and I can execute following.
1.9.3-p362 :001 > require 'hello_gem'
=> true
1.9.3-p362 :002 > HelloGem::Base.hello
Hello Ruby Gem 0.0.1
=> nil
1.9.3-p362 :003 >
Problem comes when I wanted to move code to lib folder. I created lib/hello_gem/base.rb and added the above code there. And in the hello_gem.rb I just used require "hello_gem/base". Now my project look like follows.
├── Gemfile
├── Gemfile.lock
├── hello_gem.gemspec
├── lib
│   ├── hello_gem
│   │   ├── base.rb
│   │   └── version.rb
│   └── hello_gem.rb
├── LICENSE.txt
├── Rakefile
├── README.md
When I build the gem using rake install and use irb to test following error happened.
1.9.3-p362 :001 > require 'hello_gem'
LoadError: cannot load such file -- hello_gem/base
from /home/sandarenu/.rvm/rubies/ruby-1.9.3-p362/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from /home/sandarenu/.rvm/rubies/ruby-1.9.3-p362/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from /home/sandarenu/.rvm/gems/ruby-1.9.3-p362/gems/hello_gem-0.0.1/lib/hello_gem.rb:2:in `<top (required)>'
from /home/sandarenu/.rvm/rubies/ruby-1.9.3-p362/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:60:in `require'
from /home/sandarenu/.rvm/rubies/ruby-1.9.3-p362/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:60:in `rescue in require'
from /home/sandarenu/.rvm/rubies/ruby-1.9.3-p362/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:35:in `require'
from (irb):1
from /home/sandarenu/.rvm/rubies/ruby-1.9.3-p362/bin/irb:16:in `<main>'
1.9.3-p362 :002 >
I can't find a way to fix this issue. It would be a great help if somebody can tell me what I'm doing wrong here.
Thanks in advance.
The .gemspec created by bundle gem uses Git to determine which files to include in the gem; it contains the line:
gem.files = `git ls-files`.split($/)
In order for it to add your hello_gem/base.rb you need to add it to the Git repository. Since the original setup works for you I assume you have Git installed, so you just need to run:
git add lib/hello_gem/base.rb
You don’t actually need to commit the file for git ls-files to pick it up and add it to the gem, so this should be enough to get it to work.

Resources