Require Error in test for a gem - ruby

I have a project tree as below:
├── bin
├── fpgrowth-ruby-0.0.1.gem
├── fpgrowth-ruby.gemspec
├── Gemfile
├── Gemfile.lock
├── lib
│   ├── fpgrowth
│   │   ├── fptree
│   │   │   ├── builder
│   │   │   │   ├── first_pass.rb
│   │   │   │   └── second_pass.rb
│   │   │   ├── fp_tree.rb
│   │   │   └── node.rb
│   │   ├── models
│   │   │   └── transaction.rb
│   │   └── ruby
│   │   └── version.rb
│   └── fpgrowth.rb
├── LICENSE.txt
├── Rakefile
├── README.md
└── test
└── tc_first_pass.rb
In the TestCase for first_pass I wrote:
require 'test/unit'
require "../lib/fpgrowth/fptree/builder/first_pass"
Then I get this:
ruby test/tc_first_pass.rb
/home/damien/.rvm/rubies/ruby-1.9.3-p392/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- ../lib/fpgrowth/fptree/builder/first_pass (LoadError)
from /home/damien/.rvm/rubies/ruby-1.9.3-p392/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from test/tc_first_pass.rb:2:in `<main>'
Something is wrong, but I don't know what.

Use the -I flag on the ruby command line, to specify a require path at runtime.
from your top level directory
ruby -I lib test/tc_first_pass.rb
The above tells the ruby interpreter to include /lib in the load path for this execution only.
Then for your require line,
require 'fpgrowth/fptree/builder/first_pass'
For gem building, and organizing your source I suggest reading chapters on organizing your source, and distributing and packaging your code from the Programming Ruby book found here: http://pragprog.com/book/ruby3/programming-ruby-1-9

You can't require files like that unless you use require_relative.
Barring that, you should do is alter $LOAD_PATH to include ../lib.

You could use the File class-methods to help you.
First is to start off at the directory not relative to the cwd, but relative to the file calling the require. They might not be the same.
require File.dirname(__FILE__) + "../lib/fpgrowth/fptree/builder/first_pass"
This, however, is not very portable and can be cleaned up by using the join class-method:
require File.join(File.dirname(__FILE__), '..', 'lib', 'fpgrowth', 'fptree', 'builder', 'first_pass')
But you probably find yourself adding this all over the place, not? In that case, consider adding a helper in fpgrowth.rb:
def self.root
Pathname.new(File.expand_path(File.dirname(__FILE__)))
end
Now, you can use that helper all over the place:
FpGrowth.root #=> "/absolute/path/to/fpgrowth/lib"
FpGrowth.root.join("fpgrowth", "fbtree", "builder") #=> "/absolute/path/to/fpgrowth/lib/fpbrowth/fbtree/builder"

Related

pre-commit prints 'golint: command not found'

Envs
$ go version
go version go1.15.2 linux/amd64
What I want
I want to make a microservice implemented by Go.
What happened
When I run git commit, pre-commit run golint command, and now it prints 'golint: command not found'.
asuha on asuha-HP-EliteDesk-800-G4-TWR in ~/go/src/github.com/Asuha-a/URLShortener/api/services/user(27m|feat/_20_design_backend_architecture*)
$ git commit -m "feat: add user app #20"
go fmt...................................................................Passed
go lint..................................................................Failed
- hook id: go-lint
- exit code: 1
/home/asuha/.cache/pre-commit/repo5ywtpl6j/run-go-lint.sh: line 7: golint: command not found
go imports...............................................................Passed
go-cyclo.................................................................Failed
- hook id: go-cyclo
- exit code: 127
/home/asuha/.cache/pre-commit/repo5ywtpl6j/run-go-cyclo.sh: line 9: exec: gocyclo: not found
validate toml........................................(no files to check)Skipped
Check files aren't using go's testing package........(no files to check)Skipped
go-unit-tests............................................................Passed
go-mod-tidy..............................................................Passed
Codes
settings for go in .zshrc
export PATH=$PATH:/usr/local/go/bin
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export GOBIN=$GOPATH/bin
project tree
asuha on asuha-HP-EliteDesk-800-G4-TWR in ~/go/src/github.com/Asuha-a/URLShortener(43m|feat/_20_design_backend_architecture*)
$ tree
.
├── api
│   ├── Dockerfile
│   ├── go.mod
│   ├── go.sum
│   ├── main.go
│   ├── pb
│   └── services
│   ├── README.md
│   └── user
│   ├── go.mod
│   ├── go.sum
│   └── main.go
├── docker-compose.yml
└── README.md
tree in gopath
.
├── bin
│   ├── gocyclo
│   ├── golint
│   ├── gopls
│   ├── go-test
│   ├── my-first-go
│   ├── protoc-gen-go
│   ├── protoc-gen-go-grpc
│   └── user
├── pkg
│   ├── linux_amd64
│   │   └── github.com
│   ├── mod
│   │   ├── cache
│   │   ├── cloud.google.com
│   │   ├── github.com
│   │   ├── golang.org
│   │   ├── google.golang.org
│   │   ├── gopkg.in
│   │   ├── honnef.co
│   │   └── mvdan.cc
│   └── sumdb
│   └── sum.golang.org
└── src
├── github.com
│   ├── Asuha-a
│   ├── fzipp
│   ├── gin-contrib
│   ├── gin-gonic
│   ├── golang
│   ├── go-playground
│   ├── leodido
│   ├── mattn
│   └── ugorji
├── golang.org
│   └── x
├── google.golang.org
│   └── protobuf
└── gopkg.in
└── yaml.v2
.pre-commit-config.yaml
repos:
- repo: git://github.com/dnephin/pre-commit-golang
rev: master
hooks:
- id: go-fmt
- id: go-lint
- id: go-imports
- id: go-cyclo
args: [-over=15]
- id: validate-toml
- id: no-go-testing
- id: go-unit-tests
- id: go-mod-tid
/home/asuha/go/src/github.com/Asuha-a/URLShortener/api/go.mod
module github.com/Asuha-a/URLShortener/api
go 1.15
require (
github.com/fzipp/gocyclo v0.3.1 // indirect
github.com/gin-gonic/gin v1.6.3
github.com/go-playground/validator/v10 v10.4.1 // indirect
github.com/golang/protobuf v1.4.3 // indirect
github.com/json-iterator/go v1.1.10 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/ugorji/go v1.1.13 // indirect
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 // indirect
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
golang.org/x/sys v0.0.0-20201026173827-119d4633e4d1 // indirect
golang.org/x/tools v0.0.0-20201028025901-8cd080b735b3 // indirect
google.golang.org/protobuf v1.25.0 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
)
/home/asuha/go/src/github.com/Asuha-a/URLShortener/api/services/user/go.mod
module github.com/Asuha-a/URLShortener/api/services/user
go 1.15
require (
github.com/fzipp/gocyclo v0.3.1 // indirect
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
golang.org/x/tools v0.0.0-20201028025901-8cd080b735b3 // indirect
)
What I want to know
Why golint can't run?
How to fix it?
You need to source and persist changes to your PATH env variable. If you using bash you can add next changes to .bashrc or .bash_profile (it's up to OS).
export GOPATH="${HOME}/go"
export GOROOT="/usr/local/opt/go/libexec"
if [[ $PATH != *$GOPATH* ]]; then
export PATH="${GOPATH}/bin:${PATH}"
fi
if [[ $PATH != *$GOROOT* ]]; then
export PATH="${GOROOT}/bin:${PATH}"
fi
Note: there is $HOME variables in my case, but you can write full path to your gopath.
I added these lines directly into the pre-commit hook (at .git/hooks/pre-commit in your repo) and that fixed it for me:
export GOPATH=$HOME/go
if [[ $PATH != *$GOPATH* ]]; then
export PATH="${GOPATH}/bin:${PATH}"
fi

Where do I put common development methods for rspec and rake in my gem file tree?

Here is current gem structure:
├── Gemfile
├── LICENSE.txt
├── README.md
├── Rakefile
├── mygem.gemspec
├── images
│   ├── 1b1d4bde376084011d027bba1c047a4b.jpg
│   ├── 1d468d064d2e26b5b5de9a0241ef2d4b.jpg
│   ├── 309666c7b45ecbf8f13e85a0bd6b0a4c.jpg
│   ├── 3f9f3db06db20d1d9f8188cd753f6ef4.jpg
│   ├── 679634ff89a31279a39f03e278bc9a01.jpg
│   ├── 6d97739b4a08f965dc9239dd24382e96.jpg
│   ├── 71662d4d4029a3b41d47d5baf681ab9a.jpg
│   ├── 92d90b8977f813af803c78107e7f698e.jpg
│   ├── ad8a37f872956666c3077a3e9e737984.jpg
│   └── df0a3b93e9412536ee8a11255f974141.jpg
├── lib
│   └── mygem.rb
└── spec
   └── _spec.rb
The ./images folder does not really exist until you run rspec the first time -- tests do download these binary files from a remote storage, use them and cache them here for later.
There are also rake tasks that use these files and instead of leaving the developer a memo "run this rake task only after you ran rspec" I would like to put the download_and_keep() procedure in some common place callable by both rspec and rake. The question is what is the recommended place to put such method?
There is a folder ./spec/support by rspec design but I'm thinking about switching to minitest so I need something more universal.
P.S.: can't think up more tags for this question.
There isn't really a standard for such a directory. The important part is to pick a name that, at a glance, doesn't sound like it's supposed to be included in the shipped gem.
For some inspiration, rails/rails has a tools, and rubygems/rubygems has util. A top-level support seems like it'd make a fair choice too.

Cannot require ruby files from a directory other then the one with main files (LoadError)

My problem is the following:
I can't require a ruby file from any directory other than the one with all the main files, i.e. requires like this: ./file work fine, but requires like this: dir_name/file fail.
Here's my project structure:
├── bin
│   ├── console
│   └── setup
├── CODE_OF_CONDUCT.md
├── Gemfile
├── lib
│   ├── riverbattle
│   │   ├── base.rb <------- main file that starts everything
│   │   ├── colorful.rb
│   │   ├── computer.rb
│   │   ├── constants.rb
│   │   ├── exit_error.rb
│   │   ├── field.rb
│   │   ├── game.rb
│   │   ├── human.rb
│   │   ├── invalid_move_error.rb
│   │   ├── move.rb
│   │   ├── player.rb
│   │   ├── version.rb
│   │   └── victory_error.rb
│   └── riverbattle.rb <------ the file from where I get the error
├── LICENSE
├── LICENSE.txt
├── Rakefile
├── README.md
├── spec
│   ├── spec_helper.rb
│   └── riverbattle_spec.rb
├── riverbattle-0.1.2.gem
└── riverbattle.gemspec
So, when I launch the app like this: ruby base.rb when I am in the lib/riverbattle/ directory, everything launches fine, but when I try to do ruby riverbattle.rb from the directory lib/, I get the following error:
➜ lib git:(master) ✗ ruby riverbattle.rb
/home/denis/.rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in require': cannot load such file -- ./field (LoadError) from
/home/denis/.rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:inrequire' from
/home/denis/.rvm/gems/ruby-2.2.1/gems/riverbattle-0.1.2/lib/riverbattle/game.rb:1:in
<top (required)>' from
/home/denis/.rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:inrequire' from
/home/denis/.rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in require' from
/home/denis/.rvm/gems/ruby-2.2.1/gems/riverbattle-0.1.2/lib/riverbattle/base.rb:1:in
' from
/home/denis/.rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in require' from
/home/denis/.rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:inrequire' from riverbattle.rb:2:in `'
I just don't get it why it cannot require one single file.
By the way, here's the content of the file (riverbattle.rb) from which I get the error:
require "riverbattle/version"
module Riverbattle
require "riverbattle/base"
end
and nothing else.
I was told that require actually requires an absolute path to the file and I need to do something with my $LOAD_PATH or something, but this information doesn't help at all to solve the issue. Why is it okay to require files from the same directory, but not okay, if I require them from another one?
1) Could anybody help me with solving that problem?
2) Is it the problem with only my computer and I can safely publish it as a gem (i.e. it may work properly on another computer), or it is the wrong code that doesn't work?
require searches in your $LOAD_PATH. require should generally be used if you want to use a gem that is installed on your system. For your purposes you want to use require_relative:
require_relative 'riverbattle/version'
Note that at first glance
require './riverbattle/version'
might also seem to work. However, . here points to the current directory from where you run the process, not the directory where the file resides, obviously this is not what you want.
If lib/base.rb is your main file, then perhaps it should be the "executable" file? If that is the case, should it be in bin?
$LOAD_PATH can be added to by using -I option with the ruby executable.
ruby -Ipath_to_project_root/lib lib/main.rb
would then let any file that requires files in your project look in the lib folder.
It can also be used like the answer in your other question with the $: or $LOAD_PATH.
Look at how other gems are set up, and you will find that your base.rb file can live in the bin folder, just like your setup and console files are. If it is the main script that starts it all, it could be named riverbattle as is common with gems to have an executable of the same or similar name.
require is not used to load gems, it is used to load files and without any explicit path given, will look in the load path. It doesn't matter if it is a gem or not.
require_relative is used to load files that are always local relative to the file that is using the require_relative method.
Of course, the documentation is your friend.

How to execute code from a Ruby GEM I'm building?

I'm new in ruby and I'm trying to create a GEM. The "problem" is that I found really hard to execute the code I'm building, without having to repeat a lot of steps.
This is basically my gem structure
├── Gemfile
├── Gemfile.lock
├── Guardfile
├── LICENSE.txt
├── README.md
├── Rakefile
├── bin
│   └── hermes
├── hermes.gemspec
├── lib
│   ├── hermes
│   │   ├── code.rb
│   │   ├── issue.rb
│   │   └── version.rb
│   └── hermes.rb
├── requirements.md
└── spec
├── hermes_spec.rb
└── spec_helper.rb
So I'm running bundle exec irb, then require 'hermes'and then Hermes.init, but if I change any of the files code, I have to exit irb and repeat the steps. Is there a better way of doing it? Which is the "correct" way of doing it (without using rspec) ?
Thanks!
You can use pry and then load "path/to/file.rb" every time you change your code. You can also give it a simple web interface with sinatra and use shotgun to have your code reloaded on the fly.
But, the correct way is using rspec. Nothing better than to start fresh and effective employing test driven development. Trust me, you'll be ahead of 90% of the market by just starting with tdd from scratch.

This application failed to start because it could not find or load the Qt platform plugin "cocoa"

I think I did everything I could in the last 20 hours, but nothing seems to work. My app is running and working -- just as it should -- the only problem I have is that I cannot create a .app bundle from it. I tried both Py2App and cx_Freeze but non of them is working. Because of the multi-platform support I would stick with the latter -- if possible.
The setup.py looks like this:
import sys
from cx_Freeze import setup, Executable
base = None
if sys.platform == 'win32':
base = 'Win32GUI'
OPTIONS = {'build_exe': {'includes': ['sip',
'PyQt5',
'PyQt5.QtCore',
'PyQt5.QtGui',
'PyQt5.QtWidgets',
'PyQt5.QtMultimediaWidgets',
'PyQt5.QtMultimedia',
'PyQt5.QtNetwork']}}
EXECUTABLES = [Executable('main.py', base=base)]
NAME = 'coublet'
VERSION = '0.5.70'
setup(name = NAME,
version = VERSION,
options = OPTIONS,
executables = EXECUTABLES)
The error message I have is this:
objc[28404]: Class NotificationReceiver is implemented in both
/Users/.../build/coublet-0.5.70.app/Contents/MacOS/QtWidgets and
/usr/local/Cellar/qt5/5.3.1/lib/QtWidgets.framework/Versions/5/QtWidgets. One of
the two will be used. Which one is undefined.
QObject::moveToThread: Current thread (0x7fc4b96e98b0) is not the object's thread
(0x7fc4b95dbc80).
Cannot move to target thread (0x7fc4b96e98b0)
On Mac OS X, you might be loading two sets of Qt binaries into the same process.
Check that all plugins are compiled against the right Qt binaries. Export
DYLD_PRINT_LIBRARIES=1 and check that only one set of binaries are being loaded.
This application failed to start because it could not find or load the Qt
platform plugin "cocoa".
Available platform plugins are: cocoa, minimal, offscreen.
Reinstalling the application may fix this problem.
Abort trap: 6
My system Info:
Mac OS X : 10.9.4
Python : 3.4.1
cx_Freeze : 0.9
PyQt5: : 5.3.1
- - -
Packages installed via: Homebrew and PIP
.app structure:
build/coublet-0.5.70.app
└── Contents
├── Frameworks
├── Info.plist
├── MacOS
│   ├── PyQt5.QtCore.so
│   ├── PyQt5.QtGui.so
│   ├── PyQt5.QtMultimedia.so
│   ├── PyQt5.QtMultimediaWidgets.so
│   ├── PyQt5.QtNetwork.so
│   ├── PyQt5.QtWidgets.so
│   ├── Python
│   ├── QtCore
│   ├── QtCore.so
│   ├── QtGui
│   ├── QtGui.so
│   ├── QtMultimedia
│   ├── QtMultimedia.so
│   ├── QtMultimediaWidgets
│   ├── QtMultimediaWidgets.so
│   ├── QtNetwork
│   ├── QtNetwork.so
│   ├── QtOpenGL
│   ├── QtWidgets
│   ├── QtWidgets.so
│   ├── _bisect.so
│   ├── _bz2.so
│   ├── _codecs_cn.so
│   ├── _codecs_hk.so
│   ├── _codecs_iso2022.so
│   ├── _codecs_jp.so
│   ├── _codecs_kr.so
│   ├── _codecs_tw.so
│   ├── _datetime.so
│   ├── _hashlib.so
│   ├── _heapq.so
│   ├── _json.so
│   ├── _lzma.so
│   ├── _md5.so
│   ├── _multibytecodec.so
│   ├── _opcode.so
│   ├── _pickle.so
│   ├── _posixsubprocess.so
│   ├── _random.so
│   ├── _scproxy.so
│   ├── _sha1.so
│   ├── _sha256.so
│   ├── _sha512.so
│   ├── _socket.so
│   ├── _ssl.so
│   ├── _struct.so
│   ├── array.so
│   ├── binascii.so
│   ├── grp.so
│   ├── imageformats
│   │   ├── libqdds.dylib
│   │   ├── libqgif.dylib
│   │   ├── libqicns.dylib
│   │   ├── libqico.dylib
│   │   ├── libqjp2.dylib
│   │   ├── libqjpeg.dylib
│   │   ├── libqmng.dylib
│   │   ├── libqsvg.dylib
│   │   ├── libqtga.dylib
│   │   ├── libqtiff.dylib
│   │   ├── libqwbmp.dylib
│   │   └── libqwebp.dylib
│   ├── libcrypto.1.0.0.dylib
│   ├── liblzma.5.dylib
│   ├── library.zip
│   ├── libreadline.6.dylib
│   ├── libssl.1.0.0.dylib
│   ├── main
│   ├── math.so
│   ├── platforms
│   │   ├── libqcocoa.dylib
│   │   ├── libqminimal.dylib
│   │   └── libqoffscreen.dylib
│   ├── pyexpat.so
│   ├── readline.so
│   ├── select.so
│   ├── sip.so
│   ├── termios.so
│   ├── time.so
│   ├── unicodedata.so
│   └── zlib.so
└── Resources
The question is I think pretty obvious: what am I doing wrong? (or what am I not doing?)
When building an app with cx_Freeze on MacOSX all dependent libraries (.so files on MacOSX) are packaged into the application bundle. It is this that makes the application portable to other systems, without requiring a second install of Qt.
When launching the Application, the libraries should therefore be loaded from within the bundle. However, in your case the system libraries are still being loaded:
/Users/.../build/coublet-0.5.70.app/Contents/MacOS/QtWidgets
/usr/local/Cellar/qt5/5.3.1/lib/QtWidgets.framework/Versions/5/QtWidgets
The result One of the two will be used. Which one is undefined. means that either of these could be loaded. If it picks the correct one, great! If it doesn't you've got two separate sets of libraries loading simultaneously, and that fails shortly afterwards. As an aside, you may find that if you try your Application on another system it will work fine! Sometimes.
For an overview of the problem I suggest taking a look at the following bug #33.
Before you begin
Make sure you have an up-to-date version of cx_Freeze installed. I would suggest trying to clone the repository and installing from there.
Secondly, ensure that the Qt plugins are being correctly built into your application. Cx_Freeze previously looked for the qt-menu.nib file to determine if it was building a Qt application. This is no longer available in Qt5, but you can pass it on the command-line when building your app. Set it to whatever you want, it really doesn't matter:
python setup.py bdist_mac --qt-menu-nib=/usr/local/Cellar/qt5/5.3.1/plugins/platforms/
This may be enough to fix your problem. But if not, you have two options:
Option 1
Each library file contains the paths to it's dependencies. If you're receiving this error, it means some of those paths are either a) still pointing to the original file, or b) not specific enough (and being found on your PATH or DYLD_LIBRARY_PATH). However, you can re-write paths using install_name_tool from the command line (as described here:
install_name_tool -change /usr/local/Cellar/qt5/5.3.1/lib/QtWidgets.framework/Versions/5/QtWidgets #executable_path/QtWidgets build/MyApp.app/Contents/MacOS/qt_plugins/platforms/libqcocoa.dylib
install_name_tool -change /usr/local/Cellar/qt5/5.3.1/lib/QtCore.framework/Versions/5/QtCore #executable_path/QtCore build/MyApp.app/Contents/MacOS/qt_plugins/platforms/libqcocoa.dylib
install_name_tool -change /usr/local/Cellar/qt5/5.3.1/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport #executable_path/QtPrintSupport build/MyApp.app/Contents/MacOS/qt_plugins/platforms/libqcocoa.dylib
install_name_tool -change /usr/local/Cellar/qt5/5.3.1/lib/QtGui.framework/Versions/5/QtGui #executable_path/QtGui build/MyApp.app/Contents/MacOS/qt_plugins/platforms/libqcocoa.dylib
This rewrites the paths in the libraries to point into your application folder, using #executable_path as the base. You will need to do this for all the paths that you find loading incorrectly. I'd suggest wrapping it up into an script, to run automatically after the build.
If you want to look at which libraries a file is referencing you can use otool. For example, in a successfully built application of mine:
otool -L libqcocoa.dylib
libqcocoa.dylib:
#executable_path/../Resources/qt_plugins/platforms/libqcocoa.dylib (compatibility version 0.0.0, current version 0.0.0)
/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 20.0.0)
...
There was an updated workaround in the issue tracker that suggests that just importing the correct module in your app will get it to function, however it seems unlikely that you've made an application without QtWidgets.
Option 2
If the above doesn't work, there is another approach outlined here. This is a bit of a sledgehammer approach in that it simply prevents loading of plugins at all.
Add a qt.conf file next to the executable (in the .app bundle that contains:
[Paths]
Plugins = '.'
Either set the environment variable QT_PLUGIN_PATH="" (you can do this within your application before importing PyQt. Or call QtGui.QApplication.setLibraryPaths([]) before creating your application object.
The result is no plugins, so your application will not have access to the MacOSX Cocoa style and UI (e.g. file, colour dialogs).
Use this command :
pip install opencv-python-headless
It resolved the same issue in my case.
This is in addition to #mfitzp's answer.
This QT Plugins Document came in handy.
To look for default locations that your QT app is trying to search you can use following command:
$sudo dtruss MacOS/ncher
getattrlist("/ncher.app\0", 0x7FFF954B51A4, 0x7FFF5C8FDD20) = 0 0
getattrlist("/ncher.app/Contents\0", 0x7FFF954B51A4, 0x7FFF5C8FDD20) = 0 0
getattrlist("/ncher.app/Contents/MacOS\0", 0x7FFF954B51A4, 0x7FFF5C8FDD20) = 0 0
stat64("/ncher.app/Contents/MacOS\0", 0x7FFF5C8FDED8, 0x7FFF5C8FDD20) = 0 0
stat64("/ncher.app/Contents/MacOS/platforms/.\0", 0x7FFF5C8FDF58, 0x7FFF5C8FDD20) = -1 Err#2
open("/dev/tty\0", 0x1000000, 0x1FF) = 5 0
fcntl(0x5, 0x2, 0x1) = 0 0
close(0x5) = 0 0
write_nocancel(0x2, "This application failed to start because it could not find or load the Qt platform plugin \"cocoa\".\n\nReinstalling the application may fix this problem.\n\0", 0x97) = 151 0
sigprocmask(0x3, 0x7FFF5C8FE6B4, 0x0) = 0x0 0
__pthread_sigmask(0x3, 0x7FFF5C8FE6C0, 0x0) = 0 0
__pthread_kill(0x603, 0x6, 0x0) = 0 0
kevent64(0x4, 0x0, 0x0) = -1 Err#4
You can see this QT app trying to look into MacOS/platforms, once i copied my libqcocoa.dylib plugin (its path were modified by install_name_tool command as per #mfitzp's answer) there, my application worked like charm.
BTW it is advisable by MAC codesigning guide to have this directory structure correctly setup, DONT put Frameworks, plugins in ncher.app/Contents/MacOS directory
I had this problem in the context of just starting a Qt Widgets app from Qt Creator.
What helped me was to set the variable QT_PLUGIN_PATH to the value <Qt-dir>/plugins (where <Qt-dir> is the absolute path to the folder in the Qt directory containing, among others, bin, doc, include, lib and of course plugins).
This probably did not fix the root cause of the problem but it was a quick fix that's working fine so far.

Resources