r462 - in trunk: . examples/duke3d/scripts examples/ut3-dedicated/scripts scripts

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Thu Jan 24 05:43:29 EST 2008


Author: icculus
Date: 2008-01-24 05:43:28 -0500 (Thu, 24 Jan 2008)
New Revision: 462

Modified:
   trunk/docs.txt
   trunk/examples/duke3d/scripts/config.lua
   trunk/examples/ut3-dedicated/scripts/config.lua
   trunk/scripts/config.lua
   trunk/scripts/localization.lua
   trunk/scripts/mojosetup_init.lua
   trunk/scripts/mojosetup_mainline.lua
Log:
Rest of the uninstall support. Should be good to go on Unix. Windows will need
 more work to hook into Add/Remove Programs, but there's lots of other Windows
 work to do before that...


Modified: trunk/docs.txt
===================================================================
--- trunk/docs.txt	2008-01-24 10:31:53 UTC (rev 461)
+++ trunk/docs.txt	2008-01-24 10:43:28 UTC (rev 462)
@@ -313,6 +313,42 @@
     (!!! FIXME) This attribute is for future expansion.
 
 
+   write_manifest (default true, mustBeBool)
+
+    If true, MojoSetup will create a hidden metadata directory in the
+    destination folder with lists of all files installed and some other
+    pertinent facts about the installed package. This allows other tools to
+    operate on the installation later, such as a software updater program or
+    an uninstaller. MojoSetup will also install tools in the metadata
+    directory to aid in manifest management and uninstallation.
+
+    Unless your package is a well-defined, static installation, you probably
+    want this. It adds a couple hundred kilobytes to the final install in the
+    filesystem (but not your download package), and puts an extra directory
+    in there (Usually called ".mojosetup", and hidden from the end-user).
+
+
+   support_uninstall (default true, mustBeBool)
+
+    If true, MojoSetup will include a means for the end-user to uninstall
+    this package. On Unix, this takes the form of a shell script in the
+    destination folder, on Windows, this hooks your package into the
+    "Add/Remove Programs" control panel.
+
+    If you enable support_uninstall, you must enable write_manifest, or the
+    installer will refuse to run to alert you to the problem immediately.
+
+    Please note that if you haven't anything outside the destination folder
+    to clean up, uninstall is merely a user-friendly formality; MojoSetup
+    doesn't implicitly write anything to the system outside this folder, so
+    the user can just drag it to the trash in the basic usage scenario. Indeed,
+    on Mac OS X, this is Apple's recommended "uninstall" procedure. On Windows,
+    hooking into Add/Remove Programs is probably desirable in all cases.
+
+    Enabling this option adds very little overhead to the normal install, once
+    you swallow the cost from write_manifest.
+
+
  Setup.Eula:
 
   This element can be a child of Setup.Package or Setup.Option. It can be

Modified: trunk/examples/duke3d/scripts/config.lua
===================================================================
--- trunk/examples/duke3d/scripts/config.lua	2008-01-24 10:31:53 UTC (rev 461)
+++ trunk/examples/duke3d/scripts/config.lua	2008-01-24 10:43:28 UTC (rev 462)
@@ -27,6 +27,8 @@
     version = "1.5",
     splash = "splash.bmp",
     superuser = false,
+    write_manifest = true,
+    support_uninstall = true,
     recommended_destinations =
     {
         MojoSetup.info.homedir,
@@ -88,15 +90,15 @@
             },
             Setup.File
             {
-                source = "http://icculus.org/mojosetup/examples/duke3d/data/duke3d_shareware_bins_" .. ostype() .. "_" .. arch() .. ".zip"
+                source = "http://centralserver/mojosetup/examples/duke3d/data/duke3d_shareware_bins_" .. ostype() .. "_" .. arch() .. ".zip"
             },
             Setup.File
             {
-                source = "http://icculus.org/mojosetup/examples/duke3d/data/duke3d_shareware_data.zip"
+                source = "http://centralserver/mojosetup/examples/duke3d/data/duke3d_shareware_data.zip"
             },
             Setup.File
             {
-                source = "http://icculus.org/mojosetup/examples/duke3d/data/duke3d_unified_content.zip"
+                source = "http://centralserver/mojosetup/examples/duke3d/data/duke3d_unified_content.zip"
             },
         },
 
@@ -116,17 +118,17 @@
 
             Setup.File
             {
-                source = "http://icculus.org/mojosetup/examples/duke3d/data/duke3d_retail_bins_" .. ostype() .. "_" .. arch() .. ".zip"
+                source = "http://centralserver/mojosetup/examples/duke3d/data/duke3d_retail_bins_" .. ostype() .. "_" .. arch() .. ".zip"
             },
 
             Setup.File
             {
-                source = "http://icculus.org/mojosetup/examples/duke3d/data/duke3d_unified_content.zip"
+                source = "http://centralserver/mojosetup/examples/duke3d/data/duke3d_unified_content.zip"
             },
 
             Setup.File
             {
-                source = "http://icculus.org/mojosetup/examples/duke3d/data/duke3d_retail_demos.zip"
+                source = "http://centralserver/mojosetup/examples/duke3d/data/duke3d_retail_demos.zip"
             },
 
             Setup.File

Modified: trunk/examples/ut3-dedicated/scripts/config.lua
===================================================================
--- trunk/examples/ut3-dedicated/scripts/config.lua	2008-01-24 10:31:53 UTC (rev 461)
+++ trunk/examples/ut3-dedicated/scripts/config.lua	2008-01-24 10:43:28 UTC (rev 462)
@@ -6,6 +6,8 @@
     id = "ut3-dedicated",
     description = "Unreal Tournament 3 Dedicated Server",
     version = "3487",
+    write_manifest = false,     -- don't want to update...
+    support_uninstall = false,  -- ...or uninstall. This is just a fancy unzip.
 
     recommended_destinations =
     {

Modified: trunk/scripts/config.lua
===================================================================
--- trunk/scripts/config.lua	2008-01-24 10:31:53 UTC (rev 461)
+++ trunk/scripts/config.lua	2008-01-24 10:43:28 UTC (rev 462)
@@ -43,6 +43,8 @@
     destination = "/usr/local/bin",
     recommended_destinations = { "/opt/games", "/usr/local/games" },
     updateurl = "http://localhost/updates/",
+    write_manifest = true,
+    support_uninstall = true,
 
     -- Things named Setup.Something are internal functions we supply.
     --  Generally these return the table you pass to them, but they

Modified: trunk/scripts/localization.lua
===================================================================
--- trunk/scripts/localization.lua	2008-01-24 10:31:53 UTC (rev 461)
+++ trunk/scripts/localization.lua	2008-01-24 10:43:28 UTC (rev 462)
@@ -287,6 +287,13 @@
         se = "FEL: inget option",
     };
 
+    -- This is shown if the config file wants us to add an installer to the
+    --  files we write to disk, but didn't enable the manifest support the
+    --  installer needs. This is a bug the developer must fix before shipping
+    --  her installer.
+    ["BUG: support_uninstall requires write_manifest"] = {
+    };
+
     -- This is a file's permissions. Programmers give these as strings, and
     --  if one isn't valid, the program will report this. So, on Unix, they
     --  might specify "0600" as a valid string, but "sdfksjdfk" wouldn't be

Modified: trunk/scripts/mojosetup_init.lua
===================================================================
--- trunk/scripts/mojosetup_init.lua	2008-01-24 10:31:53 UTC (rev 461)
+++ trunk/scripts/mojosetup_init.lua	2008-01-24 10:43:28 UTC (rev 462)
@@ -263,6 +263,8 @@
         { "binarypath", nil, mustBeString, cantBeEmpty },
         { "updateurl", nil, mustBeString, mustBeUrl },
         { "superuser", false, mustBeBool },
+        { "write_manifest", true, mustBeBool },
+        { "support_uninstall", true, mustBeBool },
     })
 
     if MojoSetup.installs == nil then

Modified: trunk/scripts/mojosetup_mainline.lua
===================================================================
--- trunk/scripts/mojosetup_mainline.lua	2008-01-24 10:31:53 UTC (rev 461)
+++ trunk/scripts/mojosetup_mainline.lua	2008-01-24 10:43:28 UTC (rev 462)
@@ -15,8 +15,15 @@
 
 MojoSetup.metadatakey = ".mojosetup_metadata."
 MojoSetup.metadatadesc = _("Metadata")
+MojoSetup.metadatadirname = ".mojosetup"
 
+if MojoSetup.info.platform == "windows" then
+    MojoSetup.controlappname = "mojosetup.exe"
+else
+    MojoSetup.controlappname = "mojosetup"
+end
 
+
 local function badcmdline()
     MojoSetup.fatal(_("Invalid command line"))
 end
@@ -376,7 +383,7 @@
             percent = calc_percent(MojoSetup.written, MojoSetup.totalwrite)
             item = MojoSetup.format(_("%0: %1%%"), fname, calc_percent(bw, total))
         end
-        keepgoing = MojoSetup.gui.progress(ptype, component, percent, item)
+        keepgoing = MojoSetup.gui.progress(ptype, component, percent, item, true)
         return keepgoing
     end
 
@@ -704,7 +711,7 @@
 
     MojoSetup.loginfo("Install dest: '" .. dest .. "'")
     MojoSetup.destination = dest
-    MojoSetup.metadatadir = MojoSetup.destination .. "/.mojosetup"
+    MojoSetup.metadatadir = MojoSetup.destination .. "/" .. MojoSetup.metadatadirname
     MojoSetup.controldir = MojoSetup.metadatadir  -- .. "/control"
     MojoSetup.manifestdir = MojoSetup.metadatadir .. "/manifest"
     MojoSetup.scratchdir = MojoSetup.metadatadir .. "/tmp"
@@ -865,8 +872,7 @@
     local maxbytes = -1  -- copy whole thing by default.
     local base = MojoSetup.archive.base
 
-    -- !!! FIXME: This needs an ".exe" appended on Windows.
-    dst = MojoSetup.controldir .. "/mojosetup"
+    dst = MojoSetup.controldir .. "/" .. MojoSetup.controlappname
     src = MojoSetup.info.binarypath
     if src == MojoSetup.info.basearchivepath then
         maxbytes = MojoSetup.archive.offsetofstart(base)
@@ -913,6 +919,29 @@
 end
 
 
+local function install_unix_uninstaller(desc, key)
+    -- Write a script out that calls the uninstaller.
+    local fname = MojoSetup.destination .. "/" ..
+                  "uninstall-" .. MojoSetup.install.id .. ".sh"
+
+    -- Man, I hate escaping shell strings...
+    local bin = "\"`dirname $0`\"'/" .. MojoSetup.metadatadirname .. "/" ..
+                MojoSetup.controlappname .. "'"
+    string.gsub(bin, "'", "'\\''")  -- Escape single quotes for shell.
+
+    local id = MojoSetup.install.id
+    string.gsub(id, "'", "'\\''")
+
+    local script =
+        "#!/bin/sh\n" ..
+        "exec " .. bin .. " uninstall '" .. id .. "' $*\n" ..
+        "exit 1\n\n"
+
+    install_parent_dirs(fname, key)
+    install_file_from_string(fname, script, "0755", desc, key)
+end
+
+
 local function install_manifests(desc, key)
     -- We write out a Lua script as a data definition language, a
     --  loki_setup-compatible XML manifest, and a straight text file of
@@ -989,6 +1018,11 @@
         MojoSetup.fatal(_("BUG: no options"))
     end
 
+    -- The uninstaller support needs a manifest to know what to do. Force it on.
+    if (install.support_uninstall) and (not install.write_manifest) then
+        MojoSetup.fatal(_("BUG: support_uninstall requires write_manifest"))
+    end
+
     -- This is to save us the trouble of a loop every time we have to
     --  find media by id...
     MojoSetup.media = {}
@@ -1291,7 +1325,7 @@
                                                 calc_percent(bw, total),
                                                 ratestr)
                     end
-                    return MojoSetup.gui.progress(ptype, component, percent, item)
+                    return MojoSetup.gui.progress(ptype, component, percent, item, true)
                 end
 
                 MojoSetup.loginfo("Download '" .. url .. "' to '" .. f .. "'")
@@ -1370,12 +1404,21 @@
             end
         end
 
-        install_control_app(MojoSetup.metadatadesc, MojoSetup.metadatakey)
-
         run_config_defined_hook(install.postinstall, install)
 
-        install_manifests(MojoSetup.metadatadesc, MojoSetup.metadatakey)   -- write out manifest.
+        if install.support_uninstall then
+            if MojoSetup.info.platform == "windows" then
+                MojoSetup.fatal(_("Unimplemented"))  -- !!! FIXME: write me.
+            else  -- Unix, Mac OS X, BeOS...
+                install_unix_uninstaller(MojoSetup.metadatadesc, MojoSetup.metadatakey)
+            end
+        end
 
+        if install.write_manifest then
+            install_control_app(MojoSetup.metadatadesc, MojoSetup.metadatakey)
+            install_manifests(MojoSetup.metadatadesc, MojoSetup.metadatakey)
+        end
+
         return 1   -- go to next stage.
     end
 
@@ -1590,9 +1633,17 @@
     local package = load_manifest(MojoSetup.info.argv[3])
 
     local title = _("Uninstall")
-    local question = _("Are you sure you want to uninstall '%0'?")
-    question = MojoSetup.format(question, package.description)
-    if MojoSetup.promptyn(title, question, false) then
+
+    local uninstall_permitted = false
+    if MojoSetup.cmdline("force") then
+        uninstall_permitted = true
+    else
+        local question = _("Are you sure you want to uninstall '%0'?")
+        question = MojoSetup.format(question, package.description)
+        uninstall_permitted = MojoSetup.promptyn(title, question, false)
+    end
+
+    if uninstall_permitted then
         start_gui(package.description, package.splash)
 
         -- Upvalued so we don't look this up each time...
@@ -1608,14 +1659,13 @@
             end
 
             local item = string.gsub(fname, "^.*/", "", 1)  -- chop off dirs...
-            MojoSetup.gui.progress(ptype, component, percent, item)
+            MojoSetup.gui.progress(ptype, component, percent, item, false)
             return true  -- !!! FIXME: need to disable cancel button in UI...
         end
 
         local filelist = flatten_manifest(package.manifest, prepend_dest_dir)
         delete_files(filelist, callback, true)
-
-        MojoSetup.msgbox(title, _("Uninstall complete"))
+        MojoSetup.gui.final(_("Uninstall complete"))
         stop_gui()
     end
 




More information about the mojosetup-commits mailing list