Skip to content
Cecil edited this page Oct 31, 2015 · 1 revision

User Packaging with Shoes

Note: Building Shoes and creating Shoes installers is not what I call User Packaging. It's related but building installers is not the same as User Packaging.

User packaging is done using Shoes. Nothing more than a working Shoes (of any type) is needed. There are no rakefiles, no source code, no arcane editing mysterious files or yaml required. It's all about sharing a Shoes script or app you've written. You want to make it easy for for others to use your code.

Note: When you package a script or directory for a platform, you really should test the resulting package on a machine (Real or Virtual) that doesn't have Shoes installed on it. Get some friends to help out before you just dump it on the internet. That's what real programmers do.

Another Note: Packaging is actively being debugged, modified, screwed up, fixed and improved. If your screen has an advance button or check box and you select it, proceed with caution and low expectations.

You have choices to consider. Is the app you want to share a single script file or is do you have a directory of scripts and images and who knows what else? If it's a directory then you have select that link and pick the script in the directory you want Shoes to run on the users system.

If you pick directory and select the starting script, you'll get a Shy builder screen. Shy is just a container like tar or zip. It's actually a snip of yaml in front of the tar data and then zipped. When Shoes needs to run a .shy it unzips and untars it in a temp directory and runs the starting script you told it too. The shy dialog box is pretty simple -- truth is, you just have to enter a few characters in each edit_line. and click a few buttons to build the shy.

You have another choice. Do you want to create a small file that when it runs on the users system, downloads and installs Shoes if the user hasn't installed Shoes already, and then runs your app (or shy)?. Yes, you probably do want that. There are situations where you don't want. I'll get that later but it gets a little tricky.

Then you have to pick the platform to package for. You can pick any one you like. There are 5 platforms and you can package from any Shoes 3.2 to any other platform (that's a 5 x 5 matrix). Magic? Yes, it might be magic.

If you package a directory (a .shy), that resulting file will be one level above the directory. If you pick a single package, it will be next to the script. Then you upload that to your web server and tell the world about your new app. Google mail no longer allows me to email an exe or a tgz Grrr. Such is life.

What about that option I tried to talk you from selecting? What was it? Include Shoes with app? That one. It packages the complete Shoes platform of your choice along with your script (or shy) into a 8MB (raspberry) to 16MB (OSX) file and big files are a pain if your Internet provider has a much slower upload speed.

Another thing about a full pack install (aka repack) is they may not install Shoes. In Linux and OSX, they do not install Shoes. Well, they do but its installed in a temp dir that disappears when the program quits. The next time the user runs it, it does the same temporary install. It's really annoying on Linux and low end machines. Folks that want to hide the end user from knowing their app is a Shoes script might like that option. Beware! It does install Shoes on Windows and that is just slightly less annoying than the Linux marching ants. I think it's a feature (hiding Shoes) with some Windows bugs that may not be fixable. Others might call a bug. For now, don't select this option and tell me I didn't warn you. OK?

Technical Details - Download if Needed

The linux download if needed code is a bash script which calls wget or curl. One of the them is alway available in any Linux I've seen.

OSX also runs a bash script but curl and wget aren't installed so a native osxdnl is included with the package script/shy/app. It's a nice Graphical progress bar and specific to downloading shoes from a few command line arguments from the bash script.

It should not surprise you to learn that both bash based versions have the bash script generated by the Shoes packager code and the download url was part of the generated bash script (which is passed to wget/curl/osxdnl)

Windows also has a down loader program (shoes-stub.exe) packaged with the script/shy/app. Instead of command line arguments, shoes-stub gets its url to download from Windows pe resources - generated into the shoes-stub.exe by the Shoes packager (lib/shoes/app_packager.rb and winject.rb and exerb/*.rb).

The important part is app_packager.rb tells the 'stubs' what the download site is, the 'selector' path to use at that site and the name of the script/shy to run when Shoes is installed. The download site is not hard coded into osxdnl.m or shoes-stub.c. app_packager.rb can even read a file(s) in ~/.shoes/federales/packaging to get the values. (As of Shoes 3.2.16 - it's not well tested - but it certainly can work, I know of short comings).

Packaging stopped working in Policeman (Shoes 3.1) because no one was willing to change stub.m or shoes-stub.c to replace hackety.org. That doesn't have to happen again. It should never happen again. shoes-stub.c can be cross compiled from Linux (supposedly OSX) using MinGW cross compilers, bye bye MSVC. PE Resources can modified from 100% Ruby (exerb). osxdnl get's its download args from the command line. The shoes.mvmanila.com website is the default if the external file(s) don't exist. My website can be replaced - for example "Big Company" wants to keep it's own Shoes download site so they control the Shoes version avail to their users. Pretty easy to do now. Perhaps I disappear like _why and don't pay for web server or someone wants to fork Shoes and the distribution level. It's only a few lines of Ruby to make that happen.

Except I have an Web API [snort, cough PC expel] between Shoes and the web server for packaging.

Web server api and assumptions.

There are two directories on the web server. One holds all the versions of shoes installers available (.exe, .install, tgz) and the file names should probably use my naming scheme.

The second directory is a cgi directory. I use ruby (any version on the web server). pkg.rb lists all the files sorted by my naming scheme and returns a text file, each line has the size in MB, timestamp, and file name.

#!/usr/bin/ruby
lns = []
fns = []
Dir.glob('../shoes/*') do |fp|
  fns << fp
end
fns.sort.each do |fp|
  tm = File.mtime(fp).to_i
  sz = File.size(fp).to_i/1048576
  fn = File.basename(fp) 
  lns << "#{sz} #{tm} #{fn}\n"
end
require 'cgi'
cgi = CGI.new
cgi.out{ lns }

app_package.rb is knows about the file format and it only presents the newest for each arch. And then it generates a list of buttons for each arch. It's far from perfect but it does work. The buttons contain enough info to get to the next level of methods (download if needed, include shoes and deeper and deeper). Eventually, Shoes writes the PE resources or (re)generates the bash scripts to use 3 or 4 values for the stub/script to use when run on the users machine.

These are some combination of website (shoes.mvmanila.com or http://shoes.mvmanila.com) and the path to append to that be run the correct cgi at the web server from the users machine when installing. I call it the selector

When the packaged app is run on on the users machine and Shoes isn't installed it calls the os-arch selector at the web site to get the path to the the right file to download and install. I have 5 selectors: armhf.rb, i686.rb, osx.rb, win32.rb,x86_64.rb. They look mostly alike. Here's the win32.rb:

#!/usr/bin/ruby
lns = []
fns = []
Dir.glob('../shoes/*.exe') do |fp|
  fns << fp
end
fns.sort.each do |fp|
  lns << "/public/shoes/#{File.basename(fp)}\n"
end
require 'cgi'
cgi = CGI.new
cgi.out{ lns[-1] 

The returned line is a URL path on the website. It is not a complete URL to somewhere else. It's constrained to the system that it was told to use by app_packager.rb. We can argue the security issues vs flexibility or you could rewrite shoes-stub.c and osxdnl.m and the shell scripts to do it your way.

So let's say you're a Big Company and you want a private Shoes distribution for your mostly Solaris/sparc internal network or your stuck in ppc/aix. You could hire me, I'm available for the right situations. [email protected]. Or you could follow the bread crumbs.

Clone this wiki locally