diff --git a/julia/README.md b/julia/README.md new file mode 100644 index 0000000..f3d8cd1 --- /dev/null +++ b/julia/README.md @@ -0,0 +1,128 @@ +--- +title: Julia +homepage: https://julialang.org/ +tagline: | + Julia: A Language for Data Science, Visualization, and Machine Learning +--- + +To update or switch versions, run `webi julia@stable` (or `@v1.10`, `@beta`, +etc). + +## Cheat Sheet + +> Julia is a programming language for Data Science - a far better alternative to +> (or plugin for) Python when performance matters. + +## Table of Contents + +- Files +- Hello World +- Compile for Distribution +- Vim Plugin + +### Files + +These are the files / directories that are created and/or modified with this +install: + +```text +~/.config/envman/PATH.env +~/.local/opt/julia/ +``` + +### How to create a Hello World with Julia + +Try out the REPL by coping and pasting the code below (it'll print some nice +ASCII art to the console): + +```sh +julia -i +``` + +```julia +function mandelbrot(a) + z = 0 + for i=1:50 + z = z^2 + a + end + return z +end + +for y=1.0:-0.05:-1.0 + for x=-2.0:0.0315:0.5 + abs(mandelbrot(complex(x, y))) < 2 ? print("*") : print(" ") + end + println() +end +``` + +Or write the program to `./mandelbrot.jl` and run it: + +```sh +julia ./mandelbrot.jl +``` + +## How to Build a Distributable Binary with Julia + +Here's an example project that you can build: + +1. Clone and enter the example project + ```sh + git clone --depth=1 https://github.com/JuliaLang/PackageCompiler.jl ./PackageCompiler + pushd ./PackageCompiler/examples + ``` +2. Run Julia in project mode + ```sh + julia -q --project + ``` +3. Compile the binary + ```julia + using PackageCompiler + create_app("MyApp", "MyAppCompiled") + exit() + ``` +4. Test & Enjoy + ```sh + ./MyAppCompiled/bin/MyApp foo bar --julia-args -t4 + ``` + +See also: + +- +- + +## How to Install the Language Server (for VSCode, Vim, etc) + +Open the Julia REPL and add `LanguageServer`: + +```sh +julia -i +``` + +```jl +using Pkg +Pkg.add("LanguageServer") +Pkg.add("SymbolServer") +``` + +You'll need to reinstall if you switch environments. + +## How to Install the Julia Vim Plugin + +`julia-vim` adds support for: + +- Latex-to-Unicode +- jumping from between start and end of blocks with `%` \ + (and other block jump sequences) + +```sh +mkdir -p ~/.vim/pack/plugins/start +git clone https://github.com/JuliaEditorSupport/julia-vim.git \ + ~/.vim/pack/plugins/start/julia-vim +``` + +Usage Examples: + +- `\alpha` will produce `α` \ + (meaning typing `\alpha` and hitting the `tab` key) +- Hitting `%` on an `end` will take you to the `function` or `for`, etc diff --git a/julia/install.ps1 b/julia/install.ps1 new file mode 100644 index 0000000..cd7ec72 --- /dev/null +++ b/julia/install.ps1 @@ -0,0 +1,56 @@ +#!/usr/bin/env pwsh + +################# +# Install julia # +################# + +# Every package should define these variables +$pkg_cmd_name = "julia" + +$pkg_dst_cmd = "$Env:USERPROFILE\.local\opt\julia\bin\julia.exe" +$pkg_dst_bin = "$Env:USERPROFILE\.local\opt\julia\bin" +$pkg_dst_dir = "$Env:USERPROFILE\.local\opt\julia" +$pkg_dst = "$pkg_dst_dir" + +$pkg_src_cmd = "$Env:USERPROFILE\.local\opt\julia-v$Env:WEBI_VERSION\bin\julia.exe" +$pkg_src_dir = "$Env:USERPROFILE\.local\opt\julia-v$Env:WEBI_VERSION" +$pkg_src = "$pkg_src_dir" + +New-Item "$Env:USERPROFILE\Downloads\webi" -ItemType Directory -Force | Out-Null +$pkg_download = "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE" + +# Fetch archive +IF (!(Test-Path -Path "$pkg_download")) { + Write-Output "Downloading julia from $Env:WEBI_PKG_URL to $pkg_download" + & curl.exe -A "$Env:WEBI_UA" -fsSL "$Env:WEBI_PKG_URL" -o "$pkg_download.part" + & Move-Item "$pkg_download.part" "$pkg_download" +} + +IF (!(Test-Path -Path "$pkg_src_dir")) { + Write-Output "Installing julia" + + # TODO: create package-specific temp directory + # Enter tmp + Push-Location .local\tmp + + # Remove any leftover tmp cruft + Remove-Item -Path ".\julia*" -Recurse -ErrorAction Ignore + + # Unpack archive file into this temporary directory + # Windows BSD-tar handles zip. Imagine that. + Write-Output "Unpacking $pkg_download" + & tar xf "$pkg_download" + + # Settle unpacked archive into place + Write-Output "Install Location: $pkg_src_cmd" + Move-Item -Path ".\julia*" -Destination "$pkg_src_dir" + + # Exit tmp + Pop-Location +} + +Write-Output "Copying into '$pkg_dst' from '$pkg_src'" +Remove-Item -Path "$pkg_dst" -Recurse -ErrorAction Ignore | Out-Null +Copy-Item -Path "$pkg_src" -Destination "$pkg_dst" -Recurse +webi_path_add "$pkg_dst_bin" +& "$pkg_dst_cmd" --version diff --git a/julia/install.sh b/julia/install.sh new file mode 100644 index 0000000..c8518ee --- /dev/null +++ b/julia/install.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +# shellcheck disable=SC2034 +# "'pkg_cmd_name' appears unused. Verify it or export it." + +__init_julia() { + set -e + set -u + + ################## + # Install julia # + ################## + + # Every package should define these 6 variables + pkg_cmd_name="julia" + + pkg_dst_cmd="$HOME/.local/opt/julia/bin/julia" + pkg_dst_dir="$HOME/.local/opt/julia" + pkg_dst="$pkg_dst_dir" + + pkg_src_cmd="$HOME/.local/opt/julia-v$WEBI_VERSION/bin/julia" + pkg_src_dir="$HOME/.local/opt/julia-v$WEBI_VERSION" + pkg_src="$pkg_src_dir" + + # pkg_install must be defined by every package + pkg_install() { + # ~/.local/opt/julia-v3.27.0/ + mkdir -p "$(dirname "${pkg_src_dir}")" + + # mv ./julia-*/ ~/.local/opt/julia-v3.27.0/ + mv ./julia-*/ "${pkg_src_dir}" + } + + # pkg_get_current_version is recommended, but not required + pkg_get_current_version() { + # 'julia --version' has output in this format: + # julia version 1.10.0-rc1 + # This trims it down to just the version number: + # 1.10.0-rc1 + julia --version 2> /dev/null | + head -n 1 | + cut -d ' ' -f 3 + } + +} + +__init_julia diff --git a/julia/releases.js b/julia/releases.js new file mode 100644 index 0000000..4e1b2f4 --- /dev/null +++ b/julia/releases.js @@ -0,0 +1,145 @@ +'use strict'; + +var osMap = { + winnt: 'windows', + mac: 'darwin', +}; +var archMap = { + armv7l: 'armv7', + i686: 'x86', + powerpc64le: 'ppc64le', +}; + +async function getAllReleases() { + let all = { + releases: [], + download: '', + _names: ['julia', 'macaarch64'], + }; + + let resp = await fetch( + 'https://julialang-s3.julialang.org/bin/versions.json', + { + headers: { + Accept: 'application/json', + }, + }, + ); + let buildsByVersion = await resp.json(); + + /* + { + "url": "https://julialang-s3.julialang.org/bin/mac/aarch64/1.9/julia-1.9.4-macaarch64.tar.gz", + "triplet": "aarch64-apple-darwin14", + "kind": "archive", + "arch": "aarch64", + "asc": "-----BEGIN PGP SIGNATURE-----\n\niQIzBAABCAAdFiEENnPfUp2QSUd/drN1ZuPH3APW5JUFAmVTQBcACgkQZuPH3APW\n5JWUqw//QF/CJLAxXZdcXqpBulLUs/AX+x/8aERGcKxZqfeYOwA5efOzma8sASa/\nUzYCLp9E31x/RMDoZah6vPRRjBR+uVI6CLlXCCCmbAJP3lD2vlcY9LKe2/7s3Ba8\nhwITRaL6R5zNr+YfSHW1Hoj2tWgAQh9Y+Te7bP3jzwp5dlFygFO0pzoN+aeJbPNA\nbgT0ry8tgh78/tgNjgt4Ev3E2t3ehhrDGK4tgkkKieO6sdFz8jOacZVZkR1kLVEg\nMBIqmqZfk+5/HMf/6gHwd5GOXW8+GakN7vYXO+9VFETA2EiD5Z5k4Edq/VrNCn4O\npC6WHpBmVBBYX4aQtHkJyQaV8PtFd1j9338jUWlDaa6BVtX2hjRtU1k1oLZB1TTX\nl4awzYgFqdCRnFmOtzTdMDBcfedOiIHdTyxXPjJCX3i0GXmeuk89e5dE4P6sTT9n\n24GeBVQgMaXuNorg9L0oKrsQ8RDT20yEnVbfhy4Cvoq7dNIks6IxLZt10tjJFp1j\n0oJ5f6KucGyqFM9UhXRcuLj8Z+Q+JDzBs5c2pPe/bEzv6nChRNv252e5dve17esg\nK7tHkhXzM+6wl60oyRtpWghOubXyBDsNu1MH3qC9lWy3wmWuMN7no+yX0vGFyhMT\naxjLJSeYdccKD3SuzYotp3XwBKk05PFX9lWy0vuIjVj1sGWcES8=\n=G1tO\n-----END PGP SIGNATURE-----\n", + "sha256": "67542975e86102eec95bc4bb7c30c5d8c7ea9f9a0b388f0e10f546945363b01a", + "size": 119559478, + "version": "1.9.4", + "os": "mac", + "extension": "tar.gz" + } + */ + + let versions = Object.keys(buildsByVersion); + for (let version of versions) { + let release = buildsByVersion[version]; + + // let odd = isOdd(asset.filename); + // if (odd) { + // return; + // } + + for (let build of release.files) { + // // For debugging + // let paths = build.url.split('/'); + // let extlen = build.extension.length + 1; + // let name = paths.at(-1); + // name = name.replace(`-${build.version}`, ''); + // name = name.slice('julia-'.length); + // name = name.slice(0, -extlen); + // console.log(`name: ${name}`); + + // console.log(`triplet: ${build.triplet}`); + // console.log(`arch: ${build.arch}`); + // console.log(`os: ${build.os}`); + // console.log(`kind: ${build.kind}`); + // console.log(`extension: ${build.extension}`); + // console.log(`version: ${build.version}`); + + if (build.kind === 'installer') { + continue; + } + + let arch = archMap[build.arch] || build.arch || '-'; + let os = osMap[build.os] || build.os || '-'; + let libc = ''; + let hardMusl = /\b(musl)\b/.test(build.url); + if (hardMusl) { + libc = 'musl'; + } else if (os === 'linux') { + libc = 'gnu'; + } + + let webiBuild = { + version: build.version, + _version: build.version, + lts: false, + channel: '', // autodetect by filename (-beta1, -alpha1, -rc1) + date: '1970-01-01', // the world may never know + os: os, + arch: arch, + libc: libc, + _musl: hardMusl, + ext: '', // let normalize run the split/test/join + hash: '-', // build.sha256 not ready to standardize this yet + download: build.url, + }; + all.releases.push(webiBuild); + } + } + + all.releases.sort(sortByVersion); + + return all; +} + +function sortByVersion(a, b) { + let [aVer, aPre] = a.version.split('-'); + let [bVer, bPre] = b.version.split('-'); + + let aVers = aVer.split('.'); + let bVers = bVer.split('.'); + for (let i = 0; i < 3; i += 1) { + aVers[i] = aVers[i].padStart(4, '0'); + bVers[i] = bVers[i].padStart(4, '0'); + } + + aVer = aVers.join('.'); + if (aPre) { + aVer += `-${aPre}`; + } + bVer = bVers.join('.'); + if (bPre) { + bVer += `-${aPre}`; + } + + if (aVer > bVer) { + return -1; + } + if (aVer < bVer) { + return 1; + } + return 0; +} + +module.exports = getAllReleases; + +if (module === require.main) { + getAllReleases().then(function (all) { + all = require('../_webi/normalize.js')(all); + all.releases = all.releases.slice(0, 10); + console.info(JSON.stringify(all, null, 2)); + }); +}