Skip to content
Open
59 changes: 38 additions & 21 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,28 @@ orbs:
jobs:
wolfram-language-paclet-test:
docker:
- image: maxitg/set-replace-wl-ci:12.1.1
auth:
username: maxitg
password: $DOCKERHUB_PASSWORD
- image: wolframresearch/wolframengine:15.0.0
user: root
resource_class: large # The history-test report exceeds the default container memory.
parallelism: 4

steps:
- run:
name: Install Required Tools
command: |
apt-get update
apt-get install --no-install-recommends -y g++ git openssh-client

- checkout

- run:
name: Activate Wolfram Engine
command: |
: "${WOLFRAM_ID:?Set WOLFRAM_ID in CircleCI project settings}"
: "${WOLFRAM_PASSWORD:?Set WOLFRAM_PASSWORD in CircleCI project settings}"
wolframscript -authenticate "${WOLFRAM_ID}" "${WOLFRAM_PASSWORD}"
wolframscript -activate

- run:
name: Build
command: ./build.wls
Expand Down Expand Up @@ -42,6 +55,7 @@ jobs:

- run:
name: Test
no_output_timeout: 20m
command: |
testsToRun=$(circleci tests glob "Tests/*.wlt" \
| circleci tests split --total=4 --split-by=filesize \
Expand All @@ -57,6 +71,10 @@ jobs:
password: $DOCKERHUB_PASSWORD

steps:
- run:
name: Install checkout tools
command: apk add --no-cache git openssh-client

- checkout

- run:
Expand All @@ -65,7 +83,7 @@ jobs:
apk add --no-cache \
bash boost-dev boost-static git g++ make cmake \
clang py-pip shellcheck shfmt grep npm
pip install cpplint
pip install cpplint==1.5.5
npm install -g markdownlint-cli

- run:
Expand Down Expand Up @@ -104,6 +122,10 @@ jobs:
password: $DOCKERHUB_PASSWORD

steps:
- run:
name: Install checkout tools
command: apk add --no-cache git openssh-client

- checkout

- run:
Expand All @@ -129,21 +151,15 @@ jobs:

macos-build:
macos:
xcode: 12.2.0
xcode: 27.0.0
resource_class: m4pro.medium

steps:
- checkout

- run:
name: Install CMake
command: |
cmakeURL="https://github.com/Kitware/CMake/releases/download/v3.18.6/cmake-3.18.6-Darwin-x86_64.tar.gz"
curl -L --output cmake.tar.gz $cmakeURL
tar xf cmake.tar.gz
cmakeDir=$(ls | grep cmake-*)
mkdir -p /usr/local/bin /usr/local/share
cp -r $cmakeDir/CMake.app/Contents/bin/* /usr/local/bin/
cp -r $cmakeDir/CMake.app/Contents/share/* /usr/local/share/
command: command -v cmake >/dev/null || brew install cmake

- run:
name: Build
Expand All @@ -153,14 +169,15 @@ jobs:
root: LibraryResources
paths:
- MacOSX-x86-64
- MacOSX-ARM64

- store_artifacts:
path: ./LibraryResources/

windows-build:
executor:
name: win/default
shell: bash.exe
shell: bash.exe -eo pipefail

steps:
- checkout
Expand All @@ -169,21 +186,21 @@ jobs:
name: Install CMake
command: |
cmakeURL="https://github.com/Kitware/CMake/releases/download/v3.18.6/cmake-3.18.6-win64-x64.zip"
curl -L --output cmake.zip $cmakeURL
curl --fail --location --retry 3 --output cmake.zip "$cmakeURL"
unzip -q cmake.zip
cmakeDir=$(dir -1 | findstr -i cmake-*)
cmakeDir=cmake-3.18.6-win64-x64
echo "export PATH=\"$(pwd)/$cmakeDir/bin:$PATH\"" >> $BASH_ENV

- run:
name: Install Boost headers and build libraries
command: |
boostURL="https://dl.bintray.com/boostorg/release/1.72.0/source/boost_1_72_0.zip"
curl -L --output boost.zip $boostURL
boostURL="https://archives.boost.io/release/1.72.0/source/boost_1_72_0.zip"
curl --fail --location --retry 3 --output boost.zip "$boostURL"
unzip -q boost.zip
boostDir=$(dir -1 | findstr -i boost_*)
boostDir=boost_1_72_0
echo "export BOOST_ROOT=\"$(pwd)/$boostDir\"" >> $BASH_ENV
grep BOOST_ $BASH_ENV
cd $boostDir
cd "$boostDir"
./bootstrap.bat
./b2 --with-program_options

Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ if(POST_TAG_SYSTEM_BUILD_TESTING)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG master
GIT_TAG f8d7d77c06936315286eb55f8de22cd23c188571 # GoogleTest v1.14.0
)

set(CMAKE_POLICY_DEFAULT_CMP0048 NEW) # google test raises warning about it
Expand Down
2 changes: 1 addition & 1 deletion DevUtils/BuildLibPostTagSystem.m
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@
"Windows",
{"/std:c++17", "/EHsc"},
"MacOSX",
Join[{"-std=c++17"}, $warningsFlags, {"-mmacosx-version-min=10.14"}], (* for full support for optional *)
Join[{"-std=c++17"}, $warningsFlags, {"-mmacosx-version-min=11.0"}], (* for full support for optional *)
"Unix",
Join[{"-std=c++17"}, $warningsFlags]
];
Expand Down
47 changes: 43 additions & 4 deletions DevUtils/GitLink.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,35 @@
PackageImport["PacletManager`"] (* for PacletFind, PacletInstall in versions prior to 12.1 *)

PackageExport["$PostTagSystemGitLinkAvailableQ"]
PackageExport["$PostTagSystemGitAvailableQ"]

(* unfortunately, owing to a bug in GitLink, GitLink *needs* to be on the $ContextPath or GitRepo objects
end up in the wrong context, since they are generated in a loopback link unqualified *)
$PostTagSystemGitLinkAvailableQ := !FailureQ[Quiet @ Check[Needs["GitLink`"], $Failed]];
(* Needs can succeed after a previous library initialization failure, so also check the library itself. *)
$PostTagSystemGitLinkAvailableQ := AssociationQ[Quiet @ Check[
Needs["GitLink`"];
GitLink`$GitLibraryInformation,
$Failed
]];

$PostTagSystemGitAvailableQ := $PostTagSystemGitLinkAvailableQ ||
TrueQ[Quiet @ Check[RunProcess[{"git", "--version"}, "ExitCode"] === 0, False]];

runGit::failed = "Git command `` failed in ``: ``";

(* An argument list avoids shell quoting and supports repository paths containing spaces. *)
runGit[repoDir_String, args__String] := Module[{result},
result = Quiet @ Check[RunProcess[Join[{"git", "-C", repoDir}, {args}]], $Failed];
If[!AssociationQ[result],
Message[runGit::failed, {args}, repoDir, "Could not run git; check PATH."];
Return[$Failed];
];
If[result["ExitCode"] =!= 0,
Message[runGit::failed, {args}, repoDir, StringTrim[result["StandardError"]]];
Return[$Failed];
];
StringTrim[result["StandardOutput"]]
];

PackageExport["PostTagSystemGitSHAWithDirtyStar"]

Expand All @@ -27,15 +52,21 @@
If[cleanQ, sha, sha <> "*"]
];

PostTagSystemGitSHAWithDirtyStar[_] /; FalseQ[$PostTagSystemGitLinkAvailableQ] := Missing["NotAvailable"];
PostTagSystemGitSHAWithDirtyStar[repoDir_] /; FalseQ[$PostTagSystemGitLinkAvailableQ] := ModuleScope[
sha = runGit[repoDir, "rev-parse", "--verify", "HEAD"];
If[!StringQ[sha], Return[$Failed]];
status = runGit[repoDir, "status", "--porcelain=v1", "--untracked-files=normal", "--ignore-submodules=all"];
If[!StringQ[status], Return[$Failed]];
If[status === "", sha, sha <> "*"]
];

PackageExport["PostTagSystemInstallGitLink"]

SetUsage @ "
PostTagSystemInstallGitLink[] will attempt to install GitLink on the current system (if necessary).
PostTagSystemInstallGitLink[] will attempt to install GitLink if neither GitLink nor command-line git is available.
";

PostTagSystemInstallGitLink[] := If[PacletFind["GitLink", "Internal" -> All] === {},
PostTagSystemInstallGitLink[] := If[!$PostTagSystemGitAvailableQ && PacletFind["GitLink", "Internal" -> All] === {},
PacletInstall["https://www.wolframcloud.com/obj/maxp1/GitLink-2019.11.26.01.paclet"];
];

Expand All @@ -49,6 +80,14 @@

PostTagSystemCalculateMinorVersionNumber[repoDir_, masterBranch_] := ModuleScope[
versionInformation = Import[FileNameJoin[{repoDir, "scripts", "version.wl"}]];
If[!$PostTagSystemGitLinkAvailableQ,
If[TrueQ[$internalBuildQ] && runGit[repoDir, "fetch", "origin"] === $Failed, Return[$Failed]];
mergeBase = runGit[repoDir, "merge-base", "HEAD", masterBranch];
If[!StringQ[mergeBase], Return[$Failed]];
count = runGit[repoDir, "rev-list", "--count", versionInformation["Checkpoint"] <> ".." <> mergeBase];
If[!StringQ[count] || !StringMatchQ[count, DigitCharacter ..], Return[$Failed]];
Return[Max[0, FromDigits[count] - 1]];
];
gitRepo = GitLink`GitOpen[repoDir];
If[$internalBuildQ, GitLink`GitFetch[gitRepo, "origin"]];
minorVersionNumber = Max[0, Length[GitLink`GitRange[
Expand Down
24 changes: 14 additions & 10 deletions DevUtils/PackPostTagSystem.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@
PackPostTagSystem::packfailed = "Could not pack paclet from `` into ``.";
PackPostTagSystem::nopacletinfo = "Paclet info file was not present at ``.";
PackPostTagSystem::nobuildinfo = "Build info file was not present at ``.";
PackPostTagSystem::nogitlink = "GitLink is not installed, so the built paclet version cannot be correctly \
calculated. Proceed with caution, and consider installing GitLink by running InstallGitLink[].";
PackPostTagSystem::nogitlink = "Neither GitLink nor command-line git is available. Install git or a compatible \
GitLink to build a paclet with version information.";
PackPostTagSystem::gitmetadata = "Could not determine the Git version information for ``.";

SetUsage @ "
PackPostTagSystem[] creates a PacletObject containing the local source and last built library.
Expand All @@ -45,14 +46,16 @@
SetAutomatic[sourceDirectory, repositoryDirectory];
EnsureDirectory[outputDirectory];

If[$PostTagSystemGitLinkAvailableQ,
If[$PostTagSystemGitAvailableQ,
minorVersionNumber = PostTagSystemCalculateMinorVersionNumber[repositoryDirectory, masterBranch];
pacletInfoFile = createUpdatedPacletInfo[FileNameJoin[{sourceDirectory, "PacletInfo.m"}], minorVersionNumber];
gitSHA = PostTagSystemGitSHAWithDirtyStar[repositoryDirectory];
If[!IntegerQ[minorVersionNumber] || minorVersionNumber < 0 ||
!StringQ[gitSHA] || !StringMatchQ[gitSHA, Repeated[HexadecimalCharacter, 40] ~~ Repeated["*", {0, 1}]],
ReturnFailed["gitmetadata", repositoryDirectory];
];
pacletInfoFile = createUpdatedPacletInfo[FileNameJoin[{sourceDirectory, "PacletInfo.m"}], minorVersionNumber];
,
Message[PackPostTagSystem::nogitlink];
pacletInfoFile = FileNameJoin[{sourceDirectory, "PacletInfo.m"}];
gitSHA = Missing["GitLinkNotAvailable"];
ReturnFailed["nogitlink"];
];

buildInfo = <|"GitSHA" -> gitSHA, "BuildTime" -> Round[DateList[TimeZone -> "UTC"]]|>;
Expand Down Expand Up @@ -87,10 +90,11 @@
];

createUpdatedPacletInfo[pacletInfoFilename_, minorVersionNumber_] := ModuleScope[
pacletInfo = Association @@ Import[pacletInfoFilename];
versionString = pacletInfo[Version] <> "." <> ToString[minorVersionNumber];
(* Legacy PacletInfo symbols may be read in a different context from this package. *)
pacletInfo = KeyMap[If[StringQ[#], #, SymbolName[#]] &, Association @@ Import[pacletInfoFilename]];
versionString = pacletInfo["Version"] <> "." <> ToString[minorVersionNumber];
tempFilename = FileNameJoin[{$PostTagSystemDevUtilsTemporaryDirectory, "PacletInfo.m"}];
AppendTo[pacletInfo, Version -> versionString];
AppendTo[pacletInfo, "Version" -> versionString];
Block[{$ContextPath = {"System`", "PacletManager`"}},
Export[tempFilename, PacletManager`Paclet @@ Normal[pacletInfo]]
];
Expand Down
2 changes: 1 addition & 1 deletion PacletInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
Description -> "PostTagSystem implements the tag system {3, {{0, _, _} -> {0, 0}, {1, _, _} -> {1, 1, 0, 1}}}.",
Creator -> "Max Piskunov",
URL -> "https://github.com/maxitg/PostTagSystem",
SystemID -> {"MacOSX-x86-64", "Linux-x86-64", "Windows-x86-64"},
SystemID -> {"MacOSX-x86-64", "Linux-x86-64", "Windows-x86-64", "MacOSX-ARM64"},
Extensions -> {
{"Kernel", Context -> "PostTagSystem`"},
{"LibraryLink"}
Expand Down
6 changes: 2 additions & 4 deletions Tests/buildData.wlt
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@
],

VerificationTest[
$PostTagSystemBuildTime["TimeZone"],
"UTC"
TimeZoneOffset[$PostTagSystemBuildTime["TimeZone"]] == 0
],

(* could not be built in the future *)
Expand Down Expand Up @@ -57,8 +56,7 @@
],

VerificationTest[
$PostTagSystemLibraryBuildTime["TimeZone"],
"UTC"
TimeZoneOffset[$PostTagSystemLibraryBuildTime["TimeZone"]] == 0
],

(* could not be built in the future *)
Expand Down
41 changes: 24 additions & 17 deletions scripts/buildLibraryResources.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,30 +37,33 @@ echo "libPostTagSystem sources hash: $shortSHA"

# Build the library

cmakeOptions=()
if [ "$(uname -s)" = "Darwin" ]; then
cmakeOptions+=("-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64" "-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0")
fi

mkdir -p build
cd build
cmake .. -DPOST_TAG_SYSTEM_ENABLE_ALLWARNINGS=ON -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release
cmake .. -DPOST_TAG_SYSTEM_ENABLE_ALLWARNINGS=ON -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release "${cmakeOptions[@]}"
cmake --build . --config Release # Needed for multi-config generators
cd ..

# Set the platform-specific names

if [ "$(uname -sm)" = "Darwin x86_64" ]; then
libraryResourcesDirName=MacOSX-x86-64
if [ "$(uname -s)" = "Darwin" ]; then
libraryResourcesDirNames=(MacOSX-x86-64 MacOSX-ARM64)
libraryExtension=dylib
elif [ "$(uname -sm)" = "Linux x86_64" ]; then
libraryResourcesDirName=Linux-x86-64
libraryResourcesDirNames=(Linux-x86-64)
libraryExtension=so
elif [[ "$OSTYPE" == "msys" && "$(uname -m)" == "x86_64" ]]; then # Windows
libraryResourcesDirName=Windows-x86-64
libraryResourcesDirNames=(Windows-x86-64)
libraryExtension=dll
else
echo "Operating system unsupported"
exit 1
fi

libraryDir=LibraryResources/$libraryResourcesDirName
echo "LibraryResources directory: $postTagSystemRoot/$libraryDir"
echo "Library extension: $libraryExtension"

# Find the compiled library
Expand All @@ -79,19 +82,23 @@ echo "Found compiled library at $postTagSystemRoot/$compiledLibrary"

# Copy the library to LibraryResources

mkdir -p $libraryDir
libraryDestination=$libraryDir/libPostTagSystem-$shortSHA.$libraryExtension
echo "Copying the library to $postTagSystemRoot/$libraryDestination"
cp $compiledLibrary "$libraryDestination"

metadataDestination=$libraryDir/libPostTagSystemBuildInfo.json
echo "Writing metadata to $postTagSystemRoot/$metadataDestination"
echo "\
for libraryResourcesDirName in "${libraryResourcesDirNames[@]}"; do
libraryDir=LibraryResources/$libraryResourcesDirName
echo "LibraryResources directory: $postTagSystemRoot/$libraryDir"
mkdir -p "$libraryDir"
libraryDestination=$libraryDir/libPostTagSystem-$shortSHA.$libraryExtension
echo "Copying the library to $postTagSystemRoot/$libraryDestination"
cp "$compiledLibrary" "$libraryDestination"

metadataDestination=$libraryDir/libPostTagSystemBuildInfo.json
echo "Writing metadata to $postTagSystemRoot/$metadataDestination"
echo "\
{
\"LibraryFileName\": \"libPostTagSystem-$shortSHA.$libraryExtension\",
\"LibraryBuildTime\": $(date -u "+[%-Y, %-m, %-d, %-H, %-M, %-S]"),
\"LibrarySourceHash\": \"$shortSHA\"
}" >$metadataDestination
}" >"$metadataDestination"

cat $metadataDestination
cat "$metadataDestination"
done
echo "Build done"
4 changes: 2 additions & 2 deletions test.wls
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env wolframscript

(* Disable messages about outdated cloud. *)
Off[CloudConnect::clver];
(* These tests run locally; cloud support for older kernels is not required. *)
Off[CloudConnect::clver, CloudConnect::verr];

$redColor = "\033[0;31m";
$greenColor = "\033[0;32m";
Expand Down