How to start a .command script from a mac automator app - bash

I'm trying to create a mac "app" using automator that basically calls a .command file to do all the work. The command file will be in the same dir as the .app but i'm falling at the first which is - get the current directory of the .app file thats been clicked to determine the file location of the .command file.
i've tried
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
echo "-- $SCRIPTPATH"
This just returns my users director - basically ~
The app itself is in a dir on the Desktop example: ~/Desktop/foo/my.app
I've also tried
here="`dirname \"$0\"`"
echo "cd-ing to $here"
cd "$here" || exit 1
neither work.
ultimately i need to call my.command to run the command but need to know its actual position - or even relative to the app so that it'll fire. currently i get the error that it can't find the my.command as its not located in the root of my user account (since i wont have control over where it can be placed on the end users machine).
Any pointers on what i can do to solve this much appreciated.
Note: To answer - why am i using an app which has a terminal script to call a .command which is essentially a script - basically because if you do it this way a terminal doesn't actually pop up.. which for this demo is what i need to happen.

As you did not include explicit details of your Automator workflow, saved as an application, I'm presenting the following as an example of how to have and Automator app, e.g. my.app, execute the e.g. my.command script file, that which is located in the same folder as e.g. my.app is.
For the purpose of the example, I created a folder named foo on my Desktop, in which my.app was saved along with the my.command script file.
The Automator application workflow uses a Run AppleScript action to accomplish the goal.
Replace the default code with the following example AppleScript code:
set myCommandFilename to "my.command"
set myAppPathAlias to path to me
tell application "System Events"
set myDirName to POSIX path of container of myAppPathAlias
set myCommandFilePathname to myDirName & "/" & myCommandFilename
set myCommandFilenameExists to exists file myCommandFilePathname
end tell
if myCommandFilenameExists then
try
do shell script myCommandFilePathname's quoted form
on error eStr number eNum
display dialog eStr & " number " & eNum ¬
buttons {"OK"} default button 1 ¬
with title "File I/O Error..." with icon stop
end try
else
display dialog "A necessary file, ' " & myCommandFilePathname & ¬
"', is missing!" buttons {"OK"} default button 1 ¬
with title "Missing File..." with icon stop
end if
Note: Change my.command to the actual filename. The rest of the example AppleScript code should not need to be modified.
If my.app is launched and the my.command script file is not in the same folder as my.app, then an error message will be displayed, e.g.:
If my.app is launched and the my.command script file doesn't have its executable bit set, then this error message will be displayed, e.g.:
Also, if the my.command script file does not exit cleanly, it too will display an error message, e.g.:
The content of the error message will vary based on the content of the e.g. my.command script file, how it's coded and how it fails. This example is worst case scenario in that it lets you know something failed, but not what failed.
Note: The example AppleScript code is just that and does not contain any additional error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors.

Related

MacOS Terminal: Is it possible to create a "drag-and-drop" action via script?

There are many posts that explain how to drag-and-drop things into an open Terminal window. But what I would like to do is to tell Terminal to drag-and-drop a previously selected directory onto another application like VSCode or Renamer. I have not found any documentation for that. Is it at all possible? And if so, would somebody please point me to a documentation?
UPDATE:
I'd like to clarify my question with what I intend to do:
Pre requisites:
a "work folder" contains folders and files that shall be renamed
the renaming is done by an application called "A better finder renamer" (which allows presets)
An "Automator" (MacOS app) action shall imitate these steps:
the "work folder" is right clicked
the folder is drag-and-dropped onto the ABFR, which initiates the currently active preset
other actions via bash (like 'mv .//.* ./') ...
It is the "drag-and-drop" part of the Automator action that presents a riddle for me.
The "drag-and-drop" operation is manual operation. In AppleScript, instead the command to open the file or folder is given to the destination application itself.
Second thing to keep in mind. Getting Terminal's current working directory is easy with its do script "pwd" command. But the result of the do script Terminal command returned to the script is always the window tab, not the result of the pwd shell command. One solution is to redirect (remember) the result of pwd in a temporary text file.
set tempFolder to (path to temporary items folder from user domain)
set temp to POSIX path of tempFolder & "workingDirectory.txt"
tell application "Terminal" to do script ("pwd > " & temp) in selected tab of window 1
set curDirPosixPath to paragraph 1 of (read file ((tempFolder as text) & "workingDirectory.txt"))
set curDirHFSPath to curDirPosixPath as POSIX file as Unicode text
tell application "Visual Studio Code" to open curDirHFSPath
.
NOTE: other possible solution (I don't like) is parsing the text contents of Terminal window after pwd command execution. You can get contents using property contents (of selected tab of front window).
Open Automator, choose create New Document.
Choose create new Quick Action (service).
Set workflow receives current folders in any application.
From library Add Run AppleScript action. Edit it contents:
on run {input, parameters}
set curDirHFSPath to (item 1 of input) as text
tell application "Visual Studio Code" to open curDirHFSPath
end run
Save this Quick Action as service. Now when right-clicking the folder, opens the context menu, where you can choose and run this service.

How can I automate opening a Gradle failed test report in my web browser on demand after a build failure?

I have a Gradle Java project with multiple modules. When tests fail in one or more of the modules, an HTML test report is created under ${parentProject}/${childProject}/build/reports/tests/test/index.html. This test report is output to the Gradle command line as follows:
There were failing tests. See the report at: file:///path/to/parent-project/child-project-1/build/reports/tests/test/index.html
When a test fails in this manner, I often like to open the HTML test report in my web browser, so I can interactively view the failures in a manner that is easier for me to see at a glance than looking at the text output of the failures. I use the open command from my macOS Terminal for this purpose. Since the open target is a URL, it opens in my default browser, as desired.
open file:///path/to/parent-project/child-project-1/build/reports/tests/test/index.html
OPEN(1) BSD General Commands Manual OPEN(1)
NAME
open -- open files and directories
SYNOPSIS
open [-e] [-t] [-f] [-F] [-W] [-R] [-n] [-g] [-j] [-h] [-s sdk] [-b bundle_identifier] [-a application] file ... [--args arg1 ...]
DESCRIPTION
The open command opens a file (or a directory or URL), just as if you had double-clicked the file's icon. If no application name is speci-
fied, the default application as determined via LaunchServices is used to open the specified files.
If the file is in the form of a URL, the file will be opened as a URL.
Currently to do this, I use my mouse to scroll up to the report line in the output, copy the report path, paste it into the terminal after typing open , and then hit enter.
This involves using multiple input devices (mouse, keyboard), and searching and identifying the line. I would like to automate this (either within Gradle or within the shell) so that I can quickly open a failed test in my browser. I don't want it to automatically happen on failed tests, since I tend to be doing things in the background when running the full project build, and I don't want web browser windows just popping up on me.
I'm not really sure how best to begin. As far as I know, there isn't a way to get the previous process's output after the fact to scrape the failing test from (though if there is, that would be a potential avenue of attack). I'm not sure if Gradle has a way to get the failed test report as a follow-up task, while still failing the build (if it does, I could use that task to get the failure).
I suppose I could write a standalone task which checks the project's build reports for failures and apply it to each subproject, using the presence of an XML file in ${subproject}/build/test-results/test as an indicator that a test has failed (it looks like it's only being generated for failed tests, but I could be wrong).
So in short, is there a clean way to automatically open Gradle failed tests in my macOS web browser of choice as a simple shell script, alias, Gradle command, or the like that can be run after a test fails?
Assuming there is only one instance of the file:///.../index.html URL in the contents of the entire scrolling buffer of the tab, then the following example AppleScript code can do that:
tell application "Terminal" to ¬
set tabHistory to ¬
history of tab of ¬
front window as text
set fileURL to ¬
do shell script ¬
"grep -o 'file:///.*\\.html' <<< " & ¬
tabHistory's quoted form & "; exit 0"
if fileURL is not "" then ¬
do shell script ¬
"open " & fileURL's quoted form
Notes:
The example AppleScript code above acts on the selected tab of the front window in Terminal.
If there is a file:///.../index.html URL in the contents of the entire scrolling buffer it will be opened by the open command.
If there is more than one instance of the file:///.../index.html URL in the contents of the entire scrolling buffer of the tab, then make the following change in the example AppleScript code above to open the last instance of the file:///.../index.html URL:
Change:
set fileURL to ¬
do shell script ¬
"grep -o 'file:///.*\\.html' <<< " & ¬
tabHistory's quoted form & "; exit 0"
To:
set fileURL to ¬
last paragraph of ¬
(do shell script ¬
"grep -o 'file:///.*\\.html' <<< " & ¬
tabHistory's quoted form & "; exit 0")
The example AppleScript code can be saved as a shell script with a #!/usr/bin/osascript shebang, made executable and run from Terminal.
Note: The example AppleScript code is just that and sans any included error handling does not contain any additional error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5, with the value of the delay set appropriately.

Run script on a selected file

I'm trying to make script or automate unrar to unrar a selected file to a specific folder (hard coded).
I want the following code to be run in terminal by clicking a button in finder or a keyboard shortcut while I have a file selected.
unrar e <path_to_selected_file.rar> <hard_coded_path>
How can I do this in the best way?
If your destination path is hardcoded, then I suggest you to use Automator.
First create a Service. Select on top, "get the file" in application "Finder".
Then add only one action : "run an Applescript".
In that action, the default script starts with variable "input". This variable will contains the list of all selected files while you're doing a right click on them in the Finder. Build your script to loop through files of that list, using POXIS function to convert the finder path (myUser:myfolder:myfile) to shell path (myUser/myfolder/myfile). With this path, use the "do shell script" command to run your "unbar" script.
When saved and tested, you can also define a shortcut key for that Service (in System Preferences).
Here is the script which should be in your Applescript Action :
on run {input, parameters}
set Destination to path to desktop folder -- User Desktop by default. can be changed
set PosixDest to POSIX path of Destination
set SelectedFiles to input
repeat with myFile in SelectedFiles -- loop through each selected file
set PosixF to POSIX path of myFile -- convert Finder path to Unix path
try -- try block to handle error during unbar
do shell script "unrar e " & (quoted form of PosixF) & " " & (quoted form of PosixDest)
end try
end repeat -- next file
return input
end run
This example is running as long as you select compressed file (to accept the unbar command). To be more safe, you should just add a test to your file, to check if it is a file OK for unbar. If not, just do nothing.

"Do Shell Script" command in applescript works in script editor but not in my cocoa applescript application

So I made a script in applescript that uses the "do shell script" command to run a terminal command for google apps manager (if you dont know what that is,it isnt important). I am making a cocoa applescript application and wanted to include this script in the functionalities. The script basically resets passwords for users.
Below I have provided the script in script editor and in xcode. The problem I am running into is that the script works just fine when I run it through script editor but it doesn't work when I run it in xcode. The error is as follows in bold.
--
2015-08-11 18:49:03.205 DMA Tech Team[16153:1910832] *** -[AppDelegate Passwordreset:]: python: can't open file 'Users/Nikhil/Desktop/gam/gam.py': [Errno 2] No such file or directory (error 2)
The weird thing is that my "gam" directory and "gam.py" file are all definitely in the correct place so there shouldn't even be an error.
I was wondering if there is something special I have to do for this that is different in applescript obj c than in just plane applescript?
Note "CTN" is just a email address. checkEmail() is a function that checks to see if that email entered already exists, it is not the reason for the error.
Script in Script Editor
set User to short user name of (system info)
display dialog "What is the ctn?" default answer ""
set theCTN to text returned of result
display dialog "What is the new password?" default answer ""
set thePassword to text returned of result
do shell script "python Users/" & User & "/Desktop/gam/gam.py update user " & theCTN & " password " & thePassword
Script in Xcode's app delegate
on Passwordreset_(sender)
set User to short user name of (system info)
set theCTN to RESETPASSIND_CTN's stringValue() as text
set thePassword to RESETPASSIND_PASSWORD's stringValue() as text
do shell script "python Users/" & User & "/Desktop/gam/gam.py update user " & theCTN & " password " & thePassword
end Passwordreset_
Thanks!!
You are using a relative pathname (Users/...) instead of an absolute path (/Users/...)
XCode projects tend to start in an obscure project build directory.
Presumably (I haven't checked) the Script Editor is starting in "/".

Applescript droplet doesn't run another handler

I'm trying to make a droplet script in Applescript using the code below.
I have a handler which runs a command line with the POSIX path of the selected file.
When I run the script everything works (my command line handler works fine). But, if I drop the file to my script, nothing happens.
I need some help, please
on run
set thePath to POSIX path of (choose file of type "img" default location (path to downloads folder from user domain))
doIt(thePath)
end run
on open myImageFile
tell application "Finder"
if (count of myImageFile) is greater than 1 then
display alert "A message" as critical
else if name extension of item 1 of myImageFile is not "img" then
display alert "A message" as critical
else
set thePath to POSIX path of item 1 of myImageFile
doIt(thePath)
end if
end tell
end open
Change the line: doIt(thePath) in the open handler into: my doIt(thePath).
The reason for the error, is that you try to use your handler from within the scope of finder, and finder, doesn't reckognize it as something of its own. Therefore you must add myin front of it, so the handler can be resolved.

Resources