Cannot understand folder structure for ruby project in linux - ruby

I am learning rspec and cucumber from the book - The Rspec book. This question is not about those two things. It is more about linux. My book gives me instructions which make no sense. Please help me to understand it.
Create a bin in the project root directory (sibling to lib and spec), and add a bin/codebreaker file. If you’re on a *nix system, enter this code in that file:
#!/usr/bin/env ruby
$LOAD_PATH.unshift File.expand_path( '../../lib' , __FILE__)
require 'codebreaker'
game = Codebreaker::Game.new(STDOUT)
game.start
Shouldn't that be a bin/codebreaker folder ? Anyway, I made a folder bin, under project root. I also made a file bin/codebreaker.rb with the above code and continued.
If you’re on *nix, now run chmod +x bin/codebreaker so we can execute
it, and then run this:
$ bin/codebreaker
Welcome to Codebreaker!
Enter guess:
Now look at that! Who knew that this little bit of code was actually going to start to make something work?
I don't get the above output when I go to project root and execute bin/codebreaker from there. I only see this output -
bash: bin/codebreaker: Is a directory
Am I missing something ? How do I make this work ?

The instructions tell you to create a file named codebreaker. However, you created a file named codebreaker.rb, not codebreaker. In addition to the file named codebreaker.rb which you weren't supposed to create, you also created a directory named codereaker which you also weren't supposed to create.
I don't know CodeBreaker, but the instructions you posted should work, although they are a little ugly (e.g. manually fiddling with $LOAD_PATH instead of simply using require_relative). Just follow them. Or if you do deviate from them as you did with naming your file codebreaker.rb instead of codebreaker, then you must of course also adapt all further instructions to that change, e.g. for example running bin/codebreaker.rb instead of bin/codebreaker.

Related

Rookie - Ruby: Run file in terminal

Very inexperienced Ruby student here.
I’m not sure how to write a Ruby program in Atom, save it then try to run it in the terminal (Mac OSX).
Could someone run me through the absolute basics, please?
Forgive my cluelessness!
Ruby programs generally use the '.rb' extension, so in order to run a ruby file that you've written, you need to save it somewhere with that extension first- eg. 'my-app.rb'.
It's a good idea when starting out to save it in a folder inside your "Home" directory (/Users/your user name/). You can find that in the mac "Finder" by clicking on the folder on the left hand list that's named "your username". In your terminal, your home directory is shortened to '~/' - and you can easily change directory into it with that shortcut:
cd ~
While I've been learning, I've stuck to a quick, short directory to store my files- '~/code/'. Anything will do, but it's much quicker to type 'cd ~/code/my-app.rb' than to type something long like 'cd ~/Documents/Programming/Ruby/my-app.rb' every time. So when you're deciding on where to save, think about how much you'll have to type in terminal! :)
Once you've saved your file, and used 'cd' to change into the directory you've saved it in, you use the command 'ruby' to run it.
ruby my-app.rb
That's about all there is to actually running your file! There's so much more to using the terminal, and writing code- but there's plenty of info out there on how to start.
I found Chris Pine's "Learn To Program" really simple and easy to follow. There are plenty of other resources out there, too! Try out Try Ruby to get going straight in your browser.

Creating a Homebrew formula for standalone application

I'm trying to create a homebrew formula for an application that doesn't need to be compiled. I've tried looking through the formula cookbook, but I'm missing something to make things properly work. Below is my use-case with more generic filenames.
Inside the container is two files: one is the script for the application, the other being a file for man pages. We'll use the following filenames to keep things generic:
myapp.py (executable script)
resource.txt (a resource file that the script needs)
myapp.1 (man page)
What are the best ways to get these into the correct locations? Presume I have the ability to modify the code in the script for choosing the location to load the resource.
Thanks.
You can either modify your script at install time to use the correct location of the resource or just assume it’s in the same directory and let Homebrew do the magic for you. I wrote an example formula for the latter case in another answer.
Here’s how it looks like for your needs:
class Foo < Formula
desc "Blah blah"
url "https://github.com/foo/foo/archive/master.zip"
version "1.2.3"
def install
man1.install "myapp.1"
libexec.install Dir["*"]
bin.write_exec_script (libexec/"myapp.py")
end
end
It installs myapp.1 in the correct directory. You can also use man2, man3, etc for other man directories.
It then installs all the remaining files under libexec then create an exec script in bin/myapp.py. This will be a simple shell script that execs your script in libexec. That way, your script will executes from libexec and thus will be able to find resource.txt that’s located in the same directory.
If you’d like to call it myapp and not myapp.py it’d look like that:
def install
man1.install "myapp.1"
libexec.install "resource.txt"
libexec.install "myapp.py" => "myapp"
bin.write_exec_script (libexec/"myapp")
end

Executing a command from the current directory without dot slash like "./command"

I feel like I'm missing something very basic so apologies if this question is obtuse. I've been struggling with this problem for as long as I've been using the bash shell.
Say I have a structure like this:
├──bin
├──command (executable)
This will execute:
$ bin/command
then I symlink bin/command to the project root
$ ln -s bin/command c
like so
├──c (symlink to bin/command)
├──bin
├──command (executable)
I can't do the following (errors with -bash: c: command not found)
$ c
I must do?
$ ./c
What's going on here? — is it possible to execute a command from the current directory without preceding it with ./ and also without using a system wide alias? It would be very convenient for distributed executables and utility scripts to give them one letter folder specific shortcuts on a per project basis.
It's not a matter of bash not allowing execution from the current directory, but rather, you haven't added the current directory to your list of directories to execute from.
export PATH=".:$PATH"
$ c
$
This can be a security risk, however, because if the directory contains files which you don't trust or know where they came from, a file existing in the currently directory could be confused with a system command.
For example, say the current directory is called "foo" and your colleague asks you to go into "foo" and set the permissions of "bar" to 755. As root, you run "chmod foo 755"
You assume chmod really is chmod, but if there is a file named chmod in the current directory and your colleague put it there, chmod is really a program he wrote and you are running it as root. Perhaps "chmod" resets the root password on the box or something else dangerous.
Therefore, the standard is to limit command executions which don't specify a directory to a set of explicitly trusted directories.
Beware that the accepted answer introduces a serious vulnerability!
You might add the current directory to your PATH but not at the beginning of it. That would be a very risky setting.
There are still possible vulnerabilities when the current directory is at the end but far less so this is what I would suggest:
PATH="$PATH":.
Here, the current directory is only searched after every directory already present in the PATH is explored so the risk to have an existing command overloaded by an hostile one is no more present. There is still a risk for an uninstalled command or a typo to be exploited, but it is much lower. Just make sure the dot is always at the end of the PATH when you add new directories in it.
You could add . to your PATH. (See kamituel's answer for details)
Also there is ~/.local/bin for user specific binaries on many distros.
What you can do is add the current dir (.) to the $PATH:
export PATH=.:$PATH
But this can pose a security issue, so be aware of that. See this ServerFault answer on why it's not so good idea, especially for the root account.

How to set up system path for Ruby?

I am doing prep work for app academy. The final stage before I am done with my prep work is to complete a ruby intro course called "Test First Ruby".
The first line after you install Rspec is to enter the course directory. In the terminal it is "cd learn_ruby", simple enough, except it returns back a message that says "the system cannot find the path specified". I have been noticing this message on certain commands for all of my ruby learning thus far and I am just wondering what does this mean? And how can I fix this?
Any help would be great.
cd means 'change directory'. The error you are getting is that the directory is not existant in the location your command line is in.
This looks like a reasonable intro to UNIX filesystem: http://www.doc.ic.ac.uk/~wjk/UnixIntro/Lecture2.html
UNIX reference: http://sunsite.utk.edu/UNIX-help/quickref.html
Create the directory before you cd into it:
mkdir learn_ruby
cd learn_ruby
Do check out AJcodez's links to familiarize yourself with Unix filesystem commands.

How can I gain permission to rename a file for my Ruby program?

As per the answer to this question, I am trying to backup a file by renaming it, before I replace it with a new, modified file with the old name.
As per the comments and the documentation here, I am using the following line of code:
File.rename(File.basename(modRaw), File.basename(modRaw)+'.bak')
However, when I do so, I get the following error at runtime:
The program then aborts. (leatherReplacer.rb is the name of my program, and line 88 is the above line of code)
How do I allow my program to rename the files it needs to to run successfully?
Windows has some special rules regarding permissions. The important one at work here, is that the OS prevents moving or renaming a file while the file is open.
Depending on the nature of your code (in size and scope) and the importance of the file you're trying to back up, it may be unfeasible or otherwise not worthwhile to refactor the code in such a way as to make backups possible.
You probably don't want to be calling File.basename in there, that strips off the directory:
Returns the last component of the filename given in *file_name*, which must be formed using forward slashes ("/") regardless of the separator used on the local file system.
So, if modRaw is /where/is/pancakes.house, then you're saying:
File.rename('pancakes.house', 'pancakes.house.bak')
But pancakes.house probably isn't in the script's current directory. Try without the File.basename calls:
File.rename(modRaw, modRaw + '.bak')
If you are owner of that file, use File.chmod to set desired permissions.
I don't know much about ruby, but could you run it under command line/bash with admin privileges, such as "run as administrator" or "su root"?
According to Objectmix and ruby-forum, you should set it to 755 or +x, then perhaps chown to yourself.
try using full file path e.t
File.rename('c:\pancakes.house', 'c:\pancakes.house.bak')
in win7 i encounter same problem

Resources