shawnrice / alfred-bundler Goto Github PK
View Code? Open in Web Editor NEWa utility / workflow to handle dependencies
License: MIT License
a utility / workflow to handle dependencies
License: MIT License
Besides coding standards (#16), the Bash bundler needs a full rewrite.
I've tried changing themes, but the LightOrDark
util always returns light
. Even with a black theme.
I don't recall this error occurring on my computer, but on the one I'm using now, the osascript
called from gatekeeper gives me this error:
2014-08-01 20:05:06.394 osascript[28065:507] Error loading /Library/ScriptingAdditions/QXPScriptingAdditions.osax/Contents/MacOS/QXPScriptingAdditions: dlopen(/Library/ScriptingAdditions/QXPScriptingAdditions.osax/Contents/MacOS/QXPScriptingAdditions, 262): no suitable image found. Did find:
/Library/ScriptingAdditions/QXPScriptingAdditions.osax/Contents/MacOS/QXPScriptingAdditions: mach-o, but wrong architecture
osascript: OpenScripting.framework - scripting addition "/Library/ScriptingAdditions/QXPScriptingAdditions.osax" declares no loadable handlers.
It doesn't seem to affect the display of the dialog at all, and it doesn't seem to affect the functionality, so, should we worry about it?
Should we add Octicons (Github's own icon font) to the supported icon sets?
I've been poking around in the Taurus bash bundler/wrapper, and I think we need to have a proper think about the error handling.
In particular, I think this (from the shell wrappers) is sub-optimal:
kill -s TERM $TOP_PID
IMO, the bash bundler and wrappers should return documented non-zero exit statuses if something goes wrong instead of just dying. That way, workflows (and other wrappers) using them can behave appropriately depending on what went wrong, e.g. show/log an error message, try again.
As a start-off suggestion:
3
, but arguably more critical than a failed icon install)Also, there's currently no verification of whether the downloaded zip extracted okay. I suspect this was the cause of Stephen's problem documented here.
The bundler needs to be able to recognise and back out of any failed installation, as it has an uncommonly large scope for breaking shit and is also tricky to fix (without deleting the whole thing).
Implement caching... etc.
Redo the gh-pages for better documentation of all the bundlers. Make separate versions for all major versions.
Implement custom messages for Gatekeeper (from JSON value).
Each bundler, except bash (and misc), should have a nice "notify" function that will let people easily tap into cocoaDialog. The code saved for the bash one just isn't enough to make sense.
Each should tap into the native bindings that @Ritashugisha wrote (bundler/includes/bindings/terminal-notifier/...
).
Hi Shawn,
I'm using your bundler to have an updated version of terminal-notifier 1.6.0 whereas default one is 1.5.0 (BTW that would be great to have this one by default :) it adds support of contentImage. For some reason, version 1.5.0 is in release but not the 1.6.0, which is the one when you download the project. If you want it there is a version here https://github.com/vdesabou/alfred-spotify-mini-player/blob/master/bundler/terminal-notifier.app.zip
Anyway, back to my problem..
So I have a json here https://github.com/vdesabou/alfred-spotify-mini-player/blob/master/bundler/Terminal-Notifier-Version-1.6.json
And I use it like this:
// Load and use Terminal Notifier, a "helper" utility
$tn = __load('Terminal-Notifier-Version-1.6' , '1.6.0' , 'utility', './bundler/Terminal-Notifier-Version-1.6.json' );
exec( "$tn -title 'Spotify Mini Player' -sender 'com.spotify.miniplayer' -message '" . $output . "'" );
It was working fine until now but I've removed the data directory for the bundler to fix another issue, so I guess I have now the latest version of bundler in there
Now I constantly get this popup window:
Looks like the version 1.6.0 is installed because I get notifications as expected, it's just that I have this popup every time.
I've uploaded here the bundler data folders (old-> was working, new-> have this issue with popup asking every time to install version 1.6.0)
https://cloudup.com/cBAHL3uXp7u
Thanks!
Let's track this...
We need to create a workflow that will interface with the registry.json file to provide information about installed assets and allow the user to uninstall orphaned assets.
It should work across all versions of the bundler.
It could also force update the bundler between minor versions.
Another possibility is to bake in some extra functionality to delete orphaned data and cache directories.
Currently, the bundler calls the registry.php script via an exec()
call. Integrate these functions into AlfredBundler.php
.
Theoretically, it is possible to add other ENV
s to the bundler (nodejs
, Go
, groovy
, etc...). Raised by @deanishe in #28.
To do so, we'd have to figure out how to install them into our data directory. Thus, we'd either have to (a) compile them on the user's machine (ouch!), or (b) host our own package installers that would map everything correctly. Further, we'd have to statically link each binary, which is a pain, but not impossible. Lastly, we'd need to make sure that we had versions that would work on at least a few of the versions of OS X that are relevant.
Assuming we got all the above done, then the best way to implement them would be through something like the bash bundler. So the workflow text would be something like:
#!/bin/bash
. <path/to/bundler>
$(AlfredBundler::load_env nodejs) <nodefile>
Going with the adopted coding standards and practice, the misc bundler is an executable while the bash bundler is a library.
We need to rewrite it as such.
Should we keep it in "wrappers," or should we put it elsewhere (as it isn't really a wrapper).
Calling the misc bundler directly, I'm getting the following error:
./alfred.bundler.misc.sh: line 42: `AlfredBundler::load': not a valid identifier
I'm afraid I'm not very familiar with the new bundler. Any idea what's going wrong?
From issues #37 and #35, the idea of a public log function has been introduced.
The bundler would still maintain its own, internal logs, but it would also make logging functionality available for the workflow authors.
Proposal:
Each bundler implements its own bindings for a log
function. This log function is then divided into log_internal
and log
. The internal logs are always placed in data/logs/<logname>.log
; and the external logs are always located at <alfred_data_directory>/bundleid/logs/<name.log>
.
The external logging functions will be unavailable if a bundleid is unavailable (this issue is linked to #38).
Okay. So I rewrote the misc bundler, which is easy because it's less than ten lines of code added to the bash bundler.
Currently it supports all assets, including icons.
bash <path/to/alfred.bundler.misc.sh> icon font icon_name color alter
alter
defaults to FALSE and takes either a hex color or TRUE
color
defaults to #000000
If color
is empty, then alter
defaults to TRUE
bash <path/to/alfred.bundler.misc> type name version json
version
is optional and defaults to default
json
is optional
So, at this point, the misc bundler just needs review and testing.
I'm finding myself writing error messages in a few different ways — especially between different implementations of the bundler, and I'm starting to notice (my own) inconsistencies, so I'd like to start a discussion to standardize error messages.
First, we should make sure that all error messages are sent to STDERR.
echo "<error message>" >&2
file_put_contents( 'php://stderr', "<error message>" );
STDERR.puts "<error message>"
sys.stderr.write('<error message>')
However, sometimes the error message needs to be put to STDOUT when a function calling it needs the output of the error message and a simple exit status will not suffice. These need to be identified.
Fallbacks: Output sent to STDERR doesn't necessarily mess up a script filter in Alfred (this might need verification), so, when we provide fallbacks (such as the backup broken IE icon: #8), we should send a warning to STDERR.
Bundle IDs: The bundler is supposed to work with Alfred, and so we should be able to find an info.plist
to use for certain things such as gatekeeper messages, the registry, automatic icns generation, etc.... Not being able to find a suitable info.plist
should issue a warning.
Errors: we need to determine the threshold at which an error is non-recoverable and should shutdown the script. For the install
function in the bash bundler (see bundler/wrappers/alfred.bundler.sh
), when the bundler cannot be installed, the script sends kills the overall script that called it. That might be a bit harsh.
The inconsistencies arose out of the syntax for the error messages. Should we indicate "Error:" or "Bundler Error:"? Should we use all caps: "ERROR: "?
Currently the Ruby bundler tests each server for a connection before trying to download an asset. We need to reduce these calls.
As indicated in the README.md file, Bash code should follow Google's Shell Style Guide. So, we need to convert the following files:
bundler/AlfredBundler.sh
bundler/uninstall.sh
bundler/includes/gatekeeper.sh
bundler/includes/helper-functions.sh
bundler/includes/png_to_icns.sh
bundler/includes/icns_to_png.sh
bundler/meta/fork.sh
bundler/meta/installer.sh
bundler/meta/update-wrapper.sh
bundler/meta/update.sh
bundler/meta/updates/update_bundler_data_structure.sh
bundler/wrappers/alfred.bundler.sh
bundler/wrappers/alfred.bundler.misc.sh
What's the purpose of this code from the bash wrappers?
# Define the global bundler version.
if [ -f "../meta/version_major" ]; then
declare AB_MAJOR_VERSION=$(cat "../meta/version_major")
else
declare AB_MAJOR_VERSION="devel"
fi
I'm not clear on why you'd want to check a file that's only present if the wrapper is being run from the repo.
For development purposes, I think it would be a good idea to be able to set an environmental variable to specify which major version (i.e. branch) to use. That way, I can tinker on the Python bundler in a different branch without having to remember to change loads of files on merge.
-latest
to installmisc
)misc
)TL;DR: Assets names should be normalized in the JSON filenames as well as inside the JSON. The problem is that the load
functions rely heavily on the name
variable, keeping naming both rigid and inconsistent. Question: how to fix/should we fix?
The names of the assets as defined in the JSON defaults (and the JSON files) are fairly rigid and seem arbitrary.
The naming is strict and can resort to problems like #5; however, it's deeply integrated into the way that the Bundler locates and calls assets. So, Terminal Notifier
is always referred to as Terminal-Notifier
. The -
was put in there because that's how it names itself, although the app is terminal-notifier.app
. Cocoa Dialog is cocoaDialog
because v2.1.1's application is called cocoaDialog.app
; however, v 3.0.0-beta7 (current default) is CocoaDialog.app
. The invoke
file was supposed to help take care of these, and it does so but not the best way.
So, we should normalize these, at least through the bundler (and the bindings). Should we just make them consistent through each asset (i.e. make all versions of cocoaDialog
become CocoaDialog
), or should we make them consistent across all assets (i.e. all lowercase and spaces turn hyphenated, underscores, or camelCase)?
The more radical version would be to decouple the naming consistencies making them either case insensitive.
Thoughts?
The current Python wrapper code is compliant with PEP 8.
While I've always been a TAB rather than spaces man, PEP8 is the de facto Python style guide, and adhering to it will encourage contributions. Plugins to verify compliance are available for most decent editors.
As a result, I believe there is no compelling reason to not follow PEP 8, and we should therefore strive to write PEP 8-compliant Python code.
We need to figure out how to deal with different versions (10.6, 10.7, 10.8, 10.9, 10.10). Since new icons are introduced and phased out, we might consider limiting the 'displayed' options to the ones that exist throughout all versions that Alfred supports.
Need to cement fallback method (discussion) and implement
Add your input in this Issue and we can formalise it either in this OP or a Markdown doc in the repo.
Whenever I install the bundler, the majority of the log entries are PHP code reporting some cache directory/file it's deleted.
Most of the logged paths are contained within other deleted paths. Would it be possible to just log the deletion of the top-level directory in each case? If /some/dir
has been deleted, it goes without saying that /some/dir/more_stuff/…
and everything in it has been deleted.
So, I decided to look further into the color conversion algorithms that I was using.
I went back to the source (equations) and rewrote them. They work much better now, especially because if you convert hex->rgb->hsv->rgb->hex
, you'll get the same output as input. One major issue that I found was that PHP's %
plays only with integers, so I had to switch to fmod
. Regardless, I think everything is cleaner and nicer. We need to make sure that the logic in the other languages can spit out the same hex after those conversions.
As a bonus, I wrote a little test script for PHP (to test the functions), you'll find it under tests/generic/color_conversion_tests.php
. When you run it, you're asked for a hex color, and then it shows you the conversions from the hex to hsv and back again.
Ruby code should follow Github's Style Guide. We can adopt another one if there is a more popular guide out there. But, files need to be converted:
bundler/AlfredBundler.rb
bundler/includes/convert_icon_colors.rb
bundler/wrappers/alfred.bundler.rb
@deanishe and I decided to change the argument order for the load functions and the icon functions.
The generic load call should be load( TYPE, ASSET_NAME, VERSION, JSON )
where version
is optional and should default to default
and json
is optional and should default to empty.
The icon call should be icon( FONT, NAME, COLOR, ALTER )
where color
and alter
are optional. color
should default to 000000
, and alter should default to FALSE
(unless color
and alter
are both empty, in which, color
defaults to 000000
, and alter
defaults to true
).
Use this issue to track the changes:
I know there are other ones that hook into these, but let's list and track them here.
We need to settle how best to do the Ruby abstraction.
Currently, the AlfredBundler.rb
file is a module, and the alfred.bundler.rb
file contains a class. And we just do a simple include
statement to allow all the module methods to become part of the class.
We can't use the include statement before we download/install the bundler. So, we need to find an elegant way to do this.
Right now, the Ruby wrapper just has some code in it that bypasses the installation function because it refers to the bundler file itself. This is there simply for development purposes. (I'm actually doing that with most all the bundler files so that I don't have to push a release tag and then re-install the bundler with each change to the backend).
My current, inelegant solution is to run the check-or-install logic at the top of the wrapper before the class is defined and before we try to include the AlfredBundler.rb
file. There has to be a better way to do that.
So, I was thinking about adding an Applescript dialog that tells you when you're about to install the bundler and asks permission.
For a quick check, delete the installed bundler directory, and then just run the PHP bundler from the command line.
Tell me what you think. Good idea? Annoying?
more info
buttonCurrently, the bundler needs to assume that the wrapper will be located in either the workflow root directory or one level above the workflow root directory. Hence, current behavior looks for info.plist
and falls back to ../info.plist
. Finding none, it assumes there is no plist available.
We could add in other functionality in that the workflow author provides the path to the info.plist
, optionally. This behavior is partially baked into the PHP bundler for testing/development purposes.
Adding the plist file is easy enough with modern languages (instantiate them as a property of a class object or the like), but harder with Bash. Hence, we could just not implement the latter feature with bash.
So, let's quickly decide what to do here and close out the issue:
info.plist
file (excluding Bash); orMy current vote is to implement 1 and 2 and not bother for 3.
Add in two flags for utilities:
The message will be shown when requesting gatekeeper permissions so as to give more information during the installation process to reassure users of what the utility will do.
As far as I know, Gatekeeper is invoked only when using the open
command from the CLI, so the Gatekeeper script needs to be called much less often than it already does. However, this needs confirmation.
Other Flags
Are there any other flags that we should implement? Or should we change the JSON structure entirely? This needs to be sorted out before Taurus.
We need to provide an easy way to load bindings for users, however the language works best.
For PHP (and I think Ruby), we just have to look to see if the wrapper exists and then require it.
wrapper
to bundlet
binding
to wrapper
So, for PHP, the implementation creates a method that is invoked by:
<?php
require_once( 'alfred.bundler.php' );
$b = new AlfredBundler;
$b->wrapper( 'cocoadialog' );
Then, we have the cocoadialog bindings loaded and ready to use. Currently, it just looks for a file in AB_DATA/bundler/includes/wrappers/{name}/{name}.php
. Hence, the folder and the inner names need to be the same. We should normalize these to match the asset name in the defaults. Hence, we need to have Terminal-Notifier
and CocoaDialog
.
Altered script parameters for icon generation. Re-implement and test.
Also, test with grabbing bundles and the fallback bundler.icns icon.
Currently, we just add the bundler path to the directories. Is this the best way?
I've noticed that the color conversion for icons in Bash is somewhat slow, so I'm implementing a "color-cache"; basically, if argument to alter a color is thrown, then it executes the function and stores the result in data/color-cache
. A file is saved as the original color name and the contents of said file is the color conversion. This should speed things up in bash, and, potentially in other bundler.
If bundler.sh encounters an error, it prints an error to stdout (not stderr) and exits with status 0 (not 1 or anything but 0). That is to say, it returns an error message to its caller instead of a path. It's then up to the caller to figure out if bundler.sh worked by checking if the return value is a valid path.
The script should at the very least exit with a non-zero status.
Errors should be sent to stderr, not stdout.
More specific error messages (and/or exit codes) that indicate what might have gone wrong would be very helpful.
Some of the bundlers cache the results of expensive operations.
Is it worthwhile to implement a common cache format across bundlers, so that each bundler can benefit from the work already done by others?
Obviously, this would tie the bundlers quite closely together, and will likely mean suboptimal performance in one or more implementations. Both are things I'm broadly against, but the performance advantage may outweigh the downsides.
The Python bundler currently saves altered colours in the bash bundler's cache, mostly as a courtesy to its sibling, but uses its own cache for everything else, such as utility paths.
What do you folks reckon is the best thing to do?
These issues need to be sorted before we can release Taurus.
I notice you guys are using the GPL v. 3 licence for your code.
I prefer the MIT licence for mine. Is that a problem?
The Ruby (and I think Python) bundler currently uses the alfred.bundler.misc.sh
script to install assets. Since native code is faster, installation functions need to be written for both of those languages.
The install process :
We can review the installation process if we think that there is a faster / better way to do it. Right now the alfred.bundler.misc.sh outsources the JSON handling to a PHP script that does much of the processing.
There are a few flags to note: DATA, CACHE, and FILE. These strings are replaced dynamically by the installation script.
We need to define logging standards across all versions of the bundler.
This includes defining logging levels as well as what information is stored and retrieved.
In the past I have followed a simple format built from Python's logging module.
[LoggingLevel] <Class, function:line#>....message
Any ideas on how to improve our logging practice in the bundler?
We have only one log.
{ab_data_dir}/data/logs/bundler-{major_version}.log
Each implementation will rotate the logs when necessary. We keep one backup named <logname>1.log
, and the max filesize for a log is 1MB
or (decision needed.... 1048576
) bytes.
0 – DEBUG
1 – INFO
2 – WARNING (alias: WARN)
3 – ERROR
4 – CRITICAL (alias: FATAL)
To log file
[2014-08-10 02:58:13] [bundler.py:295] [DEBUG] AlfredBundler.py imported
To STDERR
[02:58:13] [bundler.py:295] [DEBUG] AlfredBundler.py imported
Ruby files should be documented so as to take advantage of TomDoc.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.