Rails 5: How to add folders and files in application template script - ruby-on-rails-5

I would like to add folders and add files (like my own readme.md) to newly created rails apps using application templates.
In template.rb
require "fileutils"
require "shellwords"
def add_folders
mkdir views/components/buttons
mkdir csv/
end
def add_file
cd csv
touch user.csv
end
def add_readme
rm README.md
touch README.md
inject_into_file("README.md", "New readme..")
end
after_bundle do
add_folder
add_file
add_readme
end
But I don't know how to do it.

FileUtils covers most of what you want. mkdir_p uses the command line mkdir -p command, which makes the full path if the directories don't exist.
IO.write (which File inherits from IO) accepts a file name, and content. No need to delete the old file and touch a new one.
Also, you'll want to make sure you use Rails.root.join with your file paths. It's similar to File.join, in that it helps you build a file path without doubling up your / on accident, but it also returns an absolute file path on your computer. Also, it makes your code OS agnostic because while unix systems use '/' as the folder separator, Windows computers use '\'. So, Rails.root.join makes all of that safer.
Here's an example of using it on a unix system:
If Rails.root is '/some/cool/path/here', then Rails.root.join('views','components', 'buttons') would be '/some/cool/path/here/views/components/buttons'.
require 'fileutils'
require 'shellwords'
def add_folders
FileUtils.mkdir_p(Rails.root.join('views', 'components', 'buttons'))
FileUtils.mkdir_p(Rails.root.join('csv'))
end
def add_file
FileUtils.touch('Rails.root.join('csv', 'user.csv'))
end
def add_readme
File.write(Rails.root.join('README.md'), 'New readme..')
end
after_bundle do
add_folder
add_file
add_readme
end

Related

Unload statement

I am new to programming and I am running into a issue. I am calling a table and need to put my results into a csv file in a certain path.
This is what I am doing and the error I get.
dbuser#cbos1:/var/lib/dbspace/bosarc/testing/Abe_Lincoln> cd dbaccess labor32<<?
> UNLOAD TO '/var/lib/dbspace/bosarc/Active_Sites/Cronos_test/Position7'
> select * from informix.position;
> ?
-bash: cd: dbaccess: No such file or directory
dbuser#cbos1:/var/lib/dbspace/bosarc/testing/Abe_Lincoln>
the file path exist but keeps getting message.
Using just $ as the command line prompt, you should be using just:
$ dbaccess labor32 <<?
> UNLOAD TO '/var/lib/dbspace/bosarc/Active_Sites/Cronos_test/Position7'
> select * from informix.position;
> ?
…message(s) from dbaccess
$
This will run the dbaccess program (usually from $INFORMIXDIR/bin) against the database labor32, and generate an UNLOAD format file in the given file name.
The cd command is for changing directory; you don't have a directory called dbaccess (and probably shouldn't), and even if you did have such a directory, you shouldn't provide more options to the cd command, or a here document as standard input — it will ignore them.
Note that the file generated (Position7 will be the base name of the file) will be in Informix's UNLOAD format (pipe delimited fields by default), not CSV. It's certainly possible to convert between the two; I have Perl scripts that can do the conversions — last modified about a decade ago, but not much has changed in the interim. You could also consider using SQLCMD (available as open source from the IIUG Software Repository) which does have support for CSV load and unload formats. (This is the original SQLCMD — or at least an original SQLCMD — and is not Microsoft's Johnny-come-lately program of the same name.)
Create a file unload-table.sh containing:
#!/bin/sh
dbaccess labor32 <<EOF
UNLOAD TO '/var/lib/dbspace/bosarc/Active_Sites/Cronos_test/Position7'
SELECT * FROM informix.position;
EOF
You can then run this as bash unload-table.sh, or make it executable and install it in your $HOME/bin directory (which is on your PATH, isn't it?) so that you can simply run unload-table.sh. Or you can arrange to 'compile' (copy) the file to unload-table (no .sh suffix) so you don't have to type it to execute it: unload-table. You can enhance the script to allow the program (dbacess), database (labor32), table (informix.position) and file (/var/lib/dbspace/bosarc/Active_sites/Cronos_test/Position7) to be set as command line arguments or via environment variables. That requires a bit of fiddling in the script, but nothing outrageous. I'd probably allow the file name to be specified separately from the directory where the file is to be stored so that it is easier to configure on the command line.

How to read a Bunch of files in a directory in lua

I have a path (as a string) to a directory. In that directory, are a bunch of text files. I want to go to that directory open it, and go to each text file and read the data.
I've tried
f = io.open(path)
f:read("*a")
I get the error "nil Is a directory"
I've tried:
f = io.popen(path)
I get the error: "Permission denied"
Is it just me, but it seems to be a lot harder than it should be to do basic file io in lua?
A directory isn't a file. You can't just open it.
And yes, lua itself has (intentionally) limited functionality.
You can use luafilesystem or luaposix and similar modules to get more features in this area.
You can also use the following script to list the names of the files in a given directory (assuming Unix/Posix):
dirname = '.'
f = io.popen('ls ' .. dirname)
for name in f:lines() do print(name) end

RAR a folder without persisting the full path

1) I have a folder called CCBuilds containing couple of files in this path: E:\Testing\Builds\CCBuilds.
2) I have written C# code (Process.Start) to Rar this folder and save it in E:\Testing\Builds\CCBuilds.rar using the following command
"C:\program files\winrar\rar.exe a E:\Testing\Builds\CCBuilds.rar E:\Testing\Builds\CCBuilds"
3) The problem is that, though the rar file gets created properly, when I unrar the file to CCBuilds2 folder (both through code using rar.exe x command or using Extract in context menu), the unrared folder contains the full path, ie. extracting E:\Testing\Builds\CCBuilds.rar ->
E:\Testing\Builds\CCBuilds2\Testing\Builds\CCBuilds\<<my files>>
Whereas I want it to be something like this: E:\Testing\Builds\CCBuilds2\CCBuilds\<<my files>>
How can I avoid this full path persistence while adding to rar / extracting back from it. Any help is appreciated.
Use the -ep1 switch.
More info:
-ep = Files are added to an archive without including the path information. Could result in multiple files existing in the archive
with same name.
-ep1 = Do not store the path entered at the command line in archive. Exclude base folder from names.
-ep2 = Expand paths to full. Store full file paths (except drive letter and leading backslash) when archiving.
(source: http://www.qa.downappz.com/questions/winrar-command-line-to-add-files-with-relative-path-only.html)
Just in case this helps: I am currently working on an MS Access Database project (customer relations management for a small company), and one of the tasks there is to zip docx-files to be sent to customers, with a certain password encryption used.
In the VBA procedure that triggers the zip-packaging of the docx-files, I call WinRAR as follows:
c:\Programme\WinRAR\winrar.exe a -afzip -ep -pThisIsThePassword "OutputFullName" "InputFullName"
-afzip says: "Create a zip file (as opposed to a rar file)
-ep says: Do not include the paths of the source file, i.e. put the file directly into the zip folder
A full list of such switches is available in the WinRAR Help, section "Command line".
x extracts it as E:\Testing\Builds\CCBuilds2\Testing\Builds\CCBuilds\, because you're using full path when declaring the source. Either use -ep1 or set the default working dir to E:\Testing\Builds.
Use of -ep1 is needed but it's a bit tricky.
If you use:
Winrar.exe a output.rar inputpath
Winrar.exe a E:\Testing\Builds\CCBuilds.rar E:\Testing\Builds\CCBuilds
it will include the input path declared:
E:\Testing\Builds\CCBuilds -> E:\Testing\Builds\CCBuilds.rar:
Testing\Builds\CCBuilds\file1
Testing\Builds\CCBuilds\file2
Testing\Builds\CCBuilds\folder1\file3
...
which will end up unpacked as you've mentioned:
E:\Testing\Builds\CCBuilds2\Testing\Builds\CCBuilds\
There are two ways of using -ep1.
If you want the simple path:
E:\Testing\Builds\CCBuilds\
to be extracted as:
E:\Testing\Builds\CCBuilds2\CCBuilds\file1
E:\Testing\Builds\CCBuilds2\CCBuilds\file2
E:\Testing\Builds\CCBuilds2\CCBuilds\path1\file3
...
use
Winrar.exe a -ep1 E:\Testing\Builds\CCBuilds.rar E:\Testing\Builds\CCBuilds
the files inside the archive will look like:
CCBuilds\file1
CCBuilds\file2
CCBuilds\folder1\file3
...
or you could use ep1 to just add the files and folder structure sans the base folder with the help of recursion and defining the base path as the inner path of the structure:
Winrar.exe a -ep1 -r E:\Testing\Builds\CCBuilds.rar E:\Testing\Builds\CCBuilds\*
The files:
E:\Testing\Builds\CCBuilds\file1
E:\Testing\Builds\CCBuilds\file2
E:\Testing\Builds\CCBuilds\folder1\file3
...
inside the archive will look like:
file1
file2
folder1\file3
...
when extracted will look like:
E:\Testing\Builds\CCBuilds2\file1
E:\Testing\Builds\CCBuilds2\file2
E:\Testing\Builds\CCBuilds2\folder1\file3
...
Anyway, these are two ways -ep1 can be used to exclude base path with or without the folder containing the files (the base folder / or base path).

Remove unknown files in Bazaar

I have a bunch of unknown files in my Bazaar working tree that I no longer want. I can get a list of them using bzr stat, but I'd like an easy way to get rid of them. (I'd expect an option for bzr revert to do this, but I'm not finding one.)
I can always write a tiny script to parse the output of bzr stat and rm or mv the unknowns, but I thought something might already exist.
I have Bazaar (bzr) 1.13.1.
bzr clean-tree will get rid of all unknown files in a working tree. It also has switches to remove ignored files, merges backups and other types of unwanted files. See bzr clean-tree --usage for full details.
Edit to add: This is true for Bazaar 2.0.0, I'm not sure about 1.13
Made a script:
#!/usr/bin/env ruby
# Move unknown files in a Bazaar repository to the trash.
#
# Author: Benjamin Oakes
require 'fileutils'
TRASH_DIRECTORY = File.expand_path('~/.Trash/')
stdout = %x(bzr stat)
within = false
stdout.each_line do |line|
if line.match(/^unknown:$/)
within = true
next
elsif line.match(/^[a-z]+:$/i)
within = false
next
end
if within
FileUtils.move(line.match(/^\s+(.*?)$/)[1], TRASH_DIRECTORY)
end
end
I've only tested it a little, but it seems to work just fine. Please let me know if you find an issue via the comments.
On a separate topic, should I learn sed & awk? I tend to write these things using ruby -e "some ruby code".

How do I extend this batch command?

I came across this piece of batch code. It should find the path to every single .exe file if you enter it.
#Set Which=%~$PATH:1
#if "%Which%"=="" ( echo %1 not found in path ) else ( echo %Which% )
For instance, if you save this code in the file which.bat and then go to its directory in DOS, you can write
which notepad.exe
The result will be: C:\WINDOWS\System32\notepad.exe
But it's a bit limited in that it can't find other executables. I've done a bit of batch, but I don't see how I can edit this code so that it can crawl the hard drive and return the exact path.
When you want to find an executable (or other file) anywhere on the drive, not just in PATH, then perhaps only the following will work reliably:
dir /s /b \*%!~x1 | findstr "%1"
But still, it's horribly slow. And it doesn't work with cyclic directory structures. And it probably eats children.
You may be much better off using either Windows Search (dependin on OS) or writing a program from scratch which does exactly what you want (the cyclic dir thing might happen on recent Windows versions pretty easily; afaik they have that already by default).
Here's the same thing written in python:
import os
def which(program,additional_dirs=[]):
path = os.environ["PATH"]
path_components = path.split(":")
path_components.extend(additional_dirs)
for item in path_components:
location = os.path.join(item,program)
if os.path.exists(location):
return location
return None
If called with just an argument, this will only search the path. If called with two arguments ( the second being an array ), other directories will be searched.Here are some snippets :
# this will search notepad.exe in the PATH variable
print which("notepad.exe")
# this will search whatever.exe in PATH. If not found there,
# it will continue searching in the D:\ drive and in the Program Files
print which("whatever.exe",["D:/","C:/Program Files"])