Can the output of a Shake action be used in the FilePattern for a Rule? - shake-build-system

I would like to take the output of a Shake Action Stdout installRoot <- cmd "stack paths --local-install-root" and use it in the FilePattern for a Shake rule installRoot </> "bin" </> "*" %> \_ -> makeSureStackHasBeenRun
However I can't see where to put these lines in a way that would make the types line up. I can put the cmd call in a rule, but then I can't use the result to define another rule (rules can't nest).
I tried just running this command as an IO action and passing the result to the rules builder, which works but is insufficient for this build, because it has dependencies of its own which then are not tracked.
I looked at using an Oracle but don't understand the documentation well enough to know if this is what they are intended for.

Related

Run with stdin in CLion

I would like to ask if there is any possibility to run code with custom parameters in CLion. And where to put the file.txt in project folder.
Something equivalent to ./program <file.txt
It seems as if redirection of stdin for the program to be run or debugged is still not implemented. See the issue "Add an option to specify default input and output streams for console applications" at JetBrain's bugtracker.
Other IDEs like Eclipse can do this.
In CLion, go to your Run/Debug Configurations. There's a field named Program arguments. This field allows you to set "a custom parameter":
You can find the corresponding documentation here.
An excerpt from the documentation to help finding the correct dialog:
With the Navigation bar visible (View | Appearance | Navigation Bar), the available run/debug configurations are displayed in the run/debug configuration selector in the Run area:
Note that this of course only works for executable targets (or non executable targets that have an executable set).
Also note that this will most likely not allow you to do any shell redirection. Setting the field to < myfile.txt will not have the effects you are looking for. It will literally copy the strings < and myfile.txt as input arguments 1 and 2 (0 being the binary name).
If you want to pass file contents in this manner you'll have to just pass the file path using this method and then open & load the file in your application.
This is now possible.
In the Run/Debug Configuration, you’ll find a new field called
Redirect input from. Enable it, and fill in the file path/name:
Source: https://blog.jetbrains.com/clion/2020/03/clion-2020-1-eap-input-redirection-config-macros/#input_redirection

Shake: automatically deleting file after failed command

Using Shake, to create an mp3 (this is just a learning example), I use lame, and then id3v2 to tag it.
If the lame succeeds, but the id3v2 fails, then I'm left with the mp3 file in place; but of course it is "wrong". I was looking for an option to automatically delete target files if a producing command errors, but I can't find anything. I can do this manually by checking the exit code and using removeFiles, or by building in a temporary directory and moving as the last step; but this seems like a common-enough requirement (make does this by default), so I wonder if there's a function or simple technique that I'm just not seeing.
The reason Make does this by default is that if Make has a partial incomplete file on disk, it considers the task to have run successfully and be up to date, which breaks everything. In contrast, Shake records that a task ran successfully in a separate file (.shake.database), so it knows that your mp3 file isn't complete, and will rebuild it next time.
While Shake doesn't need you to delete the file, you might still want to so as to avoid confusing users. You can do that with actionOnException, something like:
let generateMp3 = do cmd "lame" ... ; cmd "id3v2" ...
let deleteMp3 = removeFile "foo.mp3"
actionOnException generateMp3 deleteMp3

Using bukhantsov.org command line query output with options

I am trying to use the tool here business objects query builder output
And there are virtually no examples, so I'm struggling to make it work. It produces no errors, but outputs no file in the directory where the batch file is, that I can see.
Here is the code inside querybuilder.bat:
set lib=c:\Program Files\Business Objects\Common\4.0\java\lib
java -cp "querybuilder.jar;poi-3.8-20120326.jar;%lib%\*" org.bukhantsov.querybuilder.Program %*
Here is the code inside what I am running, which I've named RunQuery_ALLACTIVE.bat, except of course with my Server, Username, and Password changed for the purpose of this post.
I have this all on one line, with no line breaks.
querybuilder.bat -cms:SERVER -username:OURUSERNAME -password:OURPASSWORD -query:"SELECT * FROM CI_INFOOBJECTS where SI_SCHEDULE_STATUS = 9 order by SI_NAME" -auth:windowsad -excel "Output.xls"
Can't tell if the - options go on different LINES ?
Can't tell if I'm supposed to put output file in quotes, or if it should be an existing file or not?
can't tell if for Windows AD (which we use), I would put "Windows AD" or WindowsAD, I'm assuming no spaces obviously.
Tons of unanswered questions on this tool - it LOOKS cool, but has anyone actually successfully used it? Can't really find comments or history on the 'net..
To answer your questions:
The options go on the same line, not on different ones
As Joe said, you'll need to specify the output file as -excel:"Output.xls"
If you want to use Windows AD, you'll probably need to specify secWinAD (case-sensitive).
If you're not sure about the command line options, I suggest you build up gradually: first only specify the required options, then add the optional ones one by one so you know which one is giving you problems.
Also, I noticed that the download page contains a version compiled for XI3.x and BI4. Make sure you use the correct version, corresponding to the version of BusinessObjects you're using. Also, verify the path in the batch file to see if it points to a valid folder containing the JAR files for the BusinessObjects environment.
Update:
I just noticed that the same author/developer created another application (GUI, not command line) that might be a bit easier to use. Have a look here.

How to refactor a Windows batch script littered with GOTOs?

I have to maintain a batch script of about 3500 lines littered with GOTO. Seems that the original "developer" hasn't heard of this famous paper and modular programming.
What the script does?
The script deals with the (silent) installation/uninstallation/reinstallation of several programs using different options. It could be split in several files that deal with each program in part. The problem is that if you're trying to take a part in another file that part will still GOTO another section that needs to be in the original script.
Refactoring?
Normally you wouldn't do a refactoring without having automated tests (so you can be sure you didn't break anything), but I don't know how to do it. There's no testing framework for that.
Partial Solution
I have come up with a partial "solution" that is some kind of adaptation of characterization tests (from Working Effectively with Legacy Code by Michael Feathers) and approval tests:
- create another script: test.py that replaces all commands (like copy or msiexec) with echo,
- redirect the output to a text file (good.txt),
- change the original batch script,
- run the test.py script again and save the output to another text file (current.txt),
- diff good.txt and current.txt -> if there are no differences then I didn't break anything, but if they are different I need to check if I broke something.
Problem with partial solution
How can I capture and replace all the commands? I could make a list of commands to replace, but there are also a lot of string concatenations to get the name and path of the program to be installed.
CMD level capture/hook?
Is there any way I can hook into the command line interpreter (CMD.exe) so I can replace on the fly all the calls to installers with echo?
Other suggestions?
Do I approach the problem in the wrong way? Can I do it better somehow? Do you have some advice I could use?
You could replace all COPY, DEL or CALL with %COPY%, %DEL% ,...
So you can use the same file for production and also for the tests.
#echo off
if not defined UNITTEST (
set "COPY=COPY"
set "DEL=DEL"
set "CALL=CALL"
)
%COPY% src dest
%DEL% somefile.txt
%CALL% installer.exe
And from your unittest.bat, you could start it via
#echo off
set "COPY=>>trace.log ECHO COPY"
set "DEL=>>trace.log ECHO DEL"
set "CALL=>>trace.log CALL ECHO "
del trace.log
set "unittest=Active"
call production.bat
fc good.txt trace.log
I'm not an expert in Batch, but I have done my fair share of it. With that said, I can offer a few tips.
Forget trying to do it all at once. Batch is very hard to debug. Echoing out to a log file helps a lot, but it will not capture everything you need if something goes wrong.
Work on breaking out the exe and msiexec calls into self-contained scripts. It is much easier to test the small script for the functionality you desire. Once you have that working, it is simple to call that script from the "Master" script.
Establish a good protocol for passing args to, and return codes from the smaller scripts. If there are common settings needed to be used for all the scripts consider using a central settings file.
GOTOs are not the devil, unless they pass control all over the place. Normally there are two good reasons that I know of to use GOTO’s.
Skip past a block of code that does not need to run.
To SET values into variables. Note there is a bug that can prevent variables from having their value set from within an 'IF' statement block. That little bug caused a big headache for me at one time.
Calls to a label might be better option at times.
Depending on how far back the legacy support is required, consider using Powershell when possible. The power and debugging capabilities of Powershell far out way the benefits of simple scripting of Batch. Which at 3500 lines simplicity has already been lost. You are already looking at Python, so maybe that could be used instead.
If you need a break point, use Pause. ECHO all the settings you need to examine right before the pause. This is as close to a break point I have found for batch.
Echo the command you intend to run to a log file and actually run it.
Write small verification scripts to be used independently or with the “Master” script to confirm you are getting the results you are expecting.
Use the right tool for the job. I like to use EditPadPro, RegexBuddy, and BeyondCompare for batch editing and comparing differences. There free tools that can be used too NotePad++ and Windiff. Making many edits in a file of that size is best handled by a good editor. IE inserting an echo at the beginning of a line that calls a cmd.exe.
Remember it is scripting not programming. While there is a lot of overlap of the two, the same exact approach to a problem may not be viable between the two.
Always make a backup copy of the scripts as a whole before mucking around. A fallback position is greatly appreciated when there is one small bug that you can’t find.
If it ain't broke... well you wouldn't be working on it if everything was working just fine.
Always test changes. And when you are done test it again. After that have someone else test it.
Just my .02. I’m sure someone else can chime in with more advanced advice. My knowledge on Batch has been acquired from the school of hard knocks, supplemented by ss64.com

Find files in vim: how to do a partial filename match with Explore **/*

I've recently discovered the following to find files in Vim.
:Explore **/[pattern]
Finding files is pretty important to me, and I can't believe I've done without it for 8 years. I can relate to what this gentleman has said: http://vim.wikia.com/wiki/Find_files_in_subdirectories
I see people searching for files in TextMate and have to hang my head in shame :(
So using the above I'm able to search for files, "in theory", but the output baffles me and often has files that do not match. I'll use a Rails example.
For example doing this:
Explore **/envir*
Yields this, which a bunch of extra weird files:
../
deploy/
environments/
initializers/
locales/
.DS_Store
application.rb
authorization_rules.rb
boot.rb
config.yml
database.yml
deploy.rb
development.sphinx.conf
environment.rb
production.sphinx.conf
routes.rb
sphinx.yml
staging.sphinx.conf
test.sphinx.conf
That is at least usable, I can scroll down to environment.rb and open it.
But say I want to find a list of all helpers. I would think that this:
Explore **/*help*
Would work, but no files are found.
Can someone illuminate me?
Have you look at the Ctrl-P.vim plugin? https://github.com/kien/ctrlp.vim
This plugins finds files in a similar way to what you show.
No, :Ex[plore] **/foo* sucks.
The above mentioned CtrlP is a beauty (that I use extensively despite a few limitations) that allows you to find files in your project and other niceties. FuzzyFinder and Command-T are worthy alternatives, LustyExplorer as well and there are obviously many others.
But Vim is quite capable by himself. The wildmenu option is key, here. Just add these two lines to your ~/.vimrc:
set wildmenu " see :h 'wildmenu'
set wildmode=list:full " see :h 'wildmode' for all the possible values
With the setting above, the following command shows you an accurate list of matches that you can navigate easily and relatively intuitively.
:e **/foo*<Tab> " see :h starstar
If the "working directory" is set to your project directory, that command is sure to give you good results. It's not very sexy (I like it, though) but it's very effective and dependable. Of course, this method can be used with :sp, :vs or :tabe.
The :find command is even better and probably more suited to yor needs: it looks into the directories defined in the path option. :set path=/path/to/project at the beginning of your session and you can open any file in your project with:
:find foo<tab> " see :h :find
Neat.
Another possibility is to use "args". You add all the files matching some pattern to your "argument list" and use buffer navigation commands:
:argadd ./**/*.js " see :h arglist
:sb foo<tab>
But it can be a little messy.
Overall, there are many elegant ways to deal with file navigation in Vim (and I didn't even mention tags-based navigation!). Plugins may provide a nice unified UI to a number of navigation needs but they are not required for finding files efficiently. At all.
It is interesting to note that both TextMate's and Sublime Text's implementations of fuzzy search are actually limited to the current "project" which is not the case for those Vim plugins or for Vim's buit-in file handling.
If all you want is simple :find type functionality but with partial file name matching with tab auto-completion, the find-complete plugin is good.

Resources