Skip to content

Merge Packaging on Linux

Cecil Coupe edited this page Aug 19, 2019 · 5 revisions

Merge Packaging for Linux

This is the way to build and package an application that hides Shoes-ness as much as possible. It's called Merge because it copies your app and files into a copy of Shoes and arranges to your app to start instead of shoes.rb (the splash screen). Then we create an installer for that combination. We use the AppImage format because it's much easier for you and Shoes to deal with compared to Flatpack, Snap or the older deb and rpm.

The result is a single application file that doesn't depend of Shoes being separately installed.

AppImage

It's like Flatpack or Snap, only simpler. That said, AppImage is not all that forgiving - there are rules and it's easy to break the rules and Shoes doesn't really have the correct information. Shoes will build the appimage but more importantly, Shoes provides the scripts and data for you to package without the GUI. That way you can modify the data files to fit the rules, as best you can and (re)package from the command line until you and the app store maintainer are happy. There are several common download sites for appimages or you can distribute from your own website or both.

TODO: appimage links

You can use the Cobbler->Package->AppImage to build the needed files and it will attempt to package them. Once you have the yaml file from Shoes and the optional appdata.xml file you can (re)package from a simple script or you can use the GUI again. For example: my sample app, Ytm has a ytm.yaml I built with the GUI. The RUBY constant DIR points to where Shoes is on my system, quite Likely it is "#{ENV['HOME']}/.shoes/walkabout" for you. You'll also need to set the require path "#{DIR}/lib/package/merge-appimage" might work. The yaml location is your choice.

#! /usr/bin/env ruby
require 'yaml'
opts = YAML.load_file("../ytm/ytm.yaml")
DIR='/home/ccoupe/Projects/shoes3/xlin64'
require "/home/ccoupe/Projects/shoes3/lib/package/merge-appimage"
PackShoes::merge_appimage(opts) {|msg| puts msg }

If it's not obvious yet, everything is being done with ruby and the appimagetool. You can examine the ruby to see what's really going on.

The yaml file contains the required fields from the GUI wizard which you'll probably modify by hand or by GUI and you see fit. Inside the yaml is a usexml boolean and if set to true, then appimagetool` will want an AppStream xml file. I suggest your first try should not use the AppStream XML. Get a working packaged program to packaging and then you can deal with the AppStream xml.

Menus

AppImage uses a .desktop file created by the Shoes code so the package app will show up in the users desktop menus. It's possible you or your end user or your Linux distro provides AppImage integration automatically. It's a neat thing to have but sometimes you don't want it (repeated testing is one reason - you have to delete the old menu by a right click, but there are other reasons too). The no_integrate option can be set to true in the yaml file.

links to XDG sites

AppStream AppData

You need to install the appstreamcli and appimage-util programs to process the xml appdata. These may be difficult to find. Ubuntu/Mint has them (separate packages, of course) but you have to search around to find them. On raspbian, sudo apt install appstream appstream-util worked for me.

  download https://github.com/AppImage/AppImageKit/releases/download/12/appimagetool-armhf.AppImage

It's been simple so far (really!). When you get to the xml you'll have to deal with some issues you may not have thought about (and the xml is really finicky). You need a website. You shouldn't use shoes.rb or mvmanila.com because we know nothing about your app. Example.com would work but doesn't look very professional does it? Are you going to publish the appimage in a public store or repository? If so, you want it look good in the store, right? Is the icon good looking? Big enough? Memorable? You can have screen shots as part of the appimage so store browsers can peek at your app. You'll need a place to download those from (your website perhaps) appstream-util will look to see. You'll want a more useful description than 'Built by Shoes'. This one reason you really need to do the packaging by a tiny script like I showed above - lot's of testing and thinking.

older packaging method

There is a downside to all this goodness. You will have to do some more work and more importantly you can't package across platforms with merge packaging. If you want to make a Debian .deb, you need to do that on a Linux system running Shoes.

Command Line or GUI?

You will do both. There is a GUI wizard to help you define your app and build a configuration file. That configuration file can be used by the GUI to create another script that you have to run. Linux packaging uses the the fpm program.

There's a complication - Shoes won't call the fpm.sh for you. It turns out that fpm is actually a Ruby gem so you need to install it in an available Ruby, different from the ruby inside Shoes. gem install fpm That IS NOT the Ruby inside Shoes, probably your system installed ruby (or rvm/rbenv if using them) . lin-merge.rb you'll have to write for youself but we have a template down below.

build-lin.rb and merge-fpm.rb are scripts inside Shoes.

You can find Merge Packaging as a menu option in Cobbler. That launches the GUI. It is recommended you use the GUI to build the configuration file (yaml) at least once. While you can modify the fpm.sh file you probably shouldn't do it lightly.

Linux GUI

lin-cobbler

lin-page1

lin-page2

lin-page3

It is a very good idea to save the yaml file and reload it at the beginning to the GUI. It saves much typing.

Command line

Lets get the .deb built. The gui 'deploy' copied things to the 'packdir' directory so cd there. Mine has a fpm.sh and a Ytm-app/ directory. That -app directory has your code mixed in with a slightly modified Shoes and your desired gems.

./fpm.sh that's it. Now you have a .deb, Ytm-app.deb in this example.

You probably like to automate the build and not have to go through the GUI since nothing has changed there. Lets create the script to do it. Call it lin-merge.rb if you like.

# run this with  path-to-shoes/shoes --ruby lin-merge.rb file.yaml
require 'fileutils'
include FileUtils
require 'yaml'
opts = YAML.load_file(ARGV[0])
opts['packdir'] = Dir.getwd if ! opts['packdir']
home = ENV['HOME']
GEMS_DIR = File.join(home, '.shoes','+gem')
puts "DIR = #{DIR}"
puts "GEMS_DIR = #{GEMS_DIR}"
require "package/merge-lin"
PackShoes::merge_linux(opts) {|t| $stderr.puts t}```

Yes. it could be improved slightly. You can run this with your installed Shoes with a `~/.shoes/walkabout/shoes --ruby <path-to-cmd-merge.rb> <path-to-yaml>` [note: if you use a different Ruby to run this then set DIR to where Shoes is]  
Clone this wiki locally