11

I've made a package available on github, which can be installed with

PacletInstall["https://github.com/cklausme/EcoEvo/releases/download/v1.1.0/EcoEvo-1.1.0.paclet"]

Is there a way to have a stable URL that always points to the latest release, so that I don't need to change the installation instructions with every version?

Kuba
  • 136,707
  • 13
  • 279
  • 740
Chris K
  • 20,207
  • 3
  • 39
  • 74
  • 2
    I think if you want to make this work using Mathematica technology you need to provide a PacletSite.mz file and use a bit more of the (I think still undocumented) Paclet functionality. How to do that is answered here, although the question is not really a duplicate to this one. There might be possibilities to achieve this (latest release URL) with github functionality, but there might be better places to get answers to that... – Albert Retey Nov 07 '19 at 16:43
  • 2
    In addition to the resource function Kuba mentions, check out the updateMaTeX[] function here: https://github.com/szhorvat/MaTeX#installation IGraph/M has a more complicated version of the same: https://github.com/szhorvat/IGraphM/blob/master/IGInstaller.m The FEMAddOns installer was also based on a version of this code. – Szabolcs Dec 13 '19 at 09:46

2 Answers2

10

Assuming all we want to use is GitHub, the best way does not exist but there are couple of alternatives used by folks around.

Regardless of the final installation method it is safe to say that it is beneficial to first have a .paclet file created (search around for PackPaclet) and, depending on the method, attached to a GitHub release.


TLDR I am using ResourceFunction["GitHubInstall"][ author_, name_ ]

1.1. install.m script

You can add an install.m script in your repository. User is supposed to call Import @ "url/to/install.m" and the installation procedure does whatever you want it to do.

Examples:

Pros:

  • flexible installation routine

Cons:

  • ugly url to type by the user: https://raw.githubusercontent.com/`username`/`pacletName`/master/install.m, sure it can be copied but the fewer steps the better.

1.2 ResourceFunction installation script

Presented in Szabolcs' MaTeX where the installation script is a ResourceFunction:

Examples:

Pros:

  • flexible installation routine
  • simple call e.g. ResourceFunction["MyPacletInstall"]

Cons:

  • The resource function needs to be verified by WRI before it is available

2. GitHub hosted PacletSite

You just build .paclet to your repository and update PacletSite.info.

Example:

Pros:

  • once paclet site is added user can quickly check for updates etc.
  • all WRI built-in functions based deploy-release-install

Cons:

  • Adds a lot of weight to your repository since binary .paclets need to be kept there. For this reason probably not the best for large or frequently updated projects.

3.1. A paclet installation manager

The idea is to install a 'paclet manager' once and it should handle standard Github released packages.

Examples

  • MPM`

    I created a simple installation manager MPM`: https://github.com/kubaPod/MPM

    Once you install it (using install.m :)) you can just call MPMInstall["szhorvat", "MaTeX"]. Check more examples in the GitHub wiki or this answer

        Import["https://raw.githubusercontent.com/kubapod/mpm/master/install.m"] (*only once*)
        Needs @ "MPM`"
        MPMInstall["kubapod", "devtools"]
    
  • PDInstallPaclet

    Alternatively take a look at b3m2a1's PDInstallPaclet

Pros:

  • easy to use
  • full of utilities

Cons:

  • you need to trust the source of the manager like MPM (otoh with plain text .m it is easy to inspect)
  • unless standards are expanded it only does paclet install and any fancy setup needs to be run separately

3.2. ResourceFunction["GitHubInstall"]

I pushed a reduced version of the MPMInstall to the function repository. It is straightforward to use:

ResourceFunction["GitHubInstall"]["szhorvat", "matex"]

see ResourceFunction["GitHubInstall", "DocumentationNotebook"] for more information.

Cons and Pros the same as with 3.1 + it is easier to use.

Kuba
  • 136,707
  • 13
  • 279
  • 740
  • Thanks for the comprehensive answer -- I'm still digesting it. Could you make your MPMInstall available as a ResourceFunction? – Chris K Dec 13 '19 at 17:11
  • @ChrisK I could but currently it contains few experimental features, like installing to a custom directory. I do not know if that is ok for them. I also plan to expand it and a resource function format does not feel right for anything more that a block of code. I need to think about it. – Kuba Dec 13 '19 at 21:53
  • I currently distribute my Mathematica applications manually with all files in a zip-file. Users just download the program from a homepage (e.g. https://packagex.hepforge.org) and place it in $UserBaseDirectory. Will this method be deprecated or no longer possible? Would I have to use paclets now? – HirenPatel Mar 10 '20 at 04:42
  • @HirenPatel I think it is safe to assume it will continue to be a valid method. – Kuba Mar 13 '20 at 13:23
6

You can have a look at the resource functions FEMAddOnsInstall or MaTexInstall that are both interfacing paclets hosted on GitHub. Both packages have code to automatically find the latest asset and install it.

This is what it looks like in practice:

ResourceFunction["FEMAddOnsInstall"][]
(* PacletObject["FEMAddOns", "1.3.2", <> ] *)

That's it. No URLs, Paclet manger stuff or any other monkey business, nothing. You do not even need to visit a web page. Just open M- and install the paclet. It can not get easier than that.

Update Info: For the first use of a ResourceFunction you need to be log into your account. That is a possible disadvantage I have been made aware of. At the time of writing the answer I was not aware of this.

Have a look at the code provided in the resource functions. Note that you need to write and get the resource function approved only once (copy it form either one of the two mentioned pages). Since there are already two functions that do this, I think yours will be approved too. You can then update your github repo to your hearts content.

user21
  • 39,710
  • 8
  • 110
  • 167
  • I did mention ResourceFunction for MaTeX :) To be clear, author needs to write and submit that function and in case of quick fixes any delay in approval can be stresfull. Anyway, your and Szabolcs' comments convinced me that this way deserves a separate section with pros and cons. – Kuba Dec 13 '19 at 13:34
  • @Kuba, yes you did. I felt that the convenience of this approach was not stressed enough, though and I thought I'd add an answer to do that ;-) Really, I think currently there is no better way to do this then this approach. – user21 Dec 13 '19 at 13:44
  • @Kuba, ah and a (+1) of course for your answer. Missed that in the first round.... Sorry. – user21 Dec 13 '19 at 13:47
  • This certainly looks like the simplest approach - provided WRI accepts the resource function that does the installation. In general, files hosted at WRI seem to have had the greatest persistence over the years. – murray Dec 13 '19 at 15:36
  • @murray, as mentioned there are two paclets that do this currently. These serve as presence I would argue. – user21 Dec 13 '19 at 16:28
  • 2
    Thanks for the idea. It seems a bit redundant to have a separate ResourceFunction for every package though. Could we make a more generic GitHubInstall ResourceFunction that takes a github username and repo as arguments -- i.e. ResourceFunction["GitHubInstall"]["WolframResearch","FEMAddOns"]? – Chris K Dec 13 '19 at 16:54
  • @Chris K, might be doable. Give it a try. Though, I'd model the path part after FileNameJoin. – user21 Dec 14 '19 at 06:02
  • 1
    @ChrisK that's what my PDInstallPaclet does (I wrote it to interface with packagedata.net originally). On the other hand, I refuse to contribute anything to the function repository on principle because I think it's a distraction and wasted time that could have been better spent elsewhere :) – b3m2a1 Dec 16 '19 at 07:39
  • @ChrisK That is also what MPMInstall does :) – Kuba Dec 16 '19 at 09:30
  • @b3m2a1 I feel ya about the function repository, but this might be a good case for an exception. It's sort of redundant to have to install a package to make it easier to install packages! – Chris K Dec 16 '19 at 09:33
  • @Kuba Maybe you could submit it to the function repository to make it easiest to use? – Chris K Dec 16 '19 at 09:36
  • 1
    @ChrisK I just did it with a stripped version of the MPMInstall and called it GitHubInstall. There is no point in pasting package contents to FR. I highly recommend to use MPM or PDInstallPaclet. This was my first, and last, submission so I don't know how long will it take. I will let you know. – Kuba Dec 16 '19 at 09:41
  • @Kuba Awesome, thanks! I owe you a beer or other drink of your choice :) – Chris K Dec 16 '19 at 09:46
  • 2
    @ChrisK https://resources.wolframcloud.com/FunctionRepository/resources/GitHubInstall – Kuba Dec 19 '19 at 08:20
  • @Kuba Works great -- thanks again! – Chris K Dec 19 '19 at 09:18
  • @Kuba, excellent! And I have made it into the second example on the ref page ;-) You should advertise the hell out of this. – user21 Dec 19 '19 at 09:28