Skip to content

Commit

Permalink
Linux support (#21)
Browse files Browse the repository at this point in the history
* gcc warning

* ubuntu dockerfile

* try ubuntu CI buld

* add publish job; remove create release job

* every time

* .

* .

* exit stat different for posix

* capitalization error

* .

* testing

* .

* remove debug step

* incorrect script

* of course windows isn't posix

* don't prefix exe on windows

* separate artifact names; help win find artifact
  • Loading branch information
McCallisterRomer authored Mar 10, 2023
1 parent 1fddb51 commit 223c8ef
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 63 deletions.
14 changes: 14 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "ubuntu",
"build": {
"dockerfile": "ubuntu.dockerfile"
},
"customizations": {
"vscode": {
"extensions": [
"ms-vscode.cpptools-extension-pack",
"twxs.cmake"
]
}
}
}
5 changes: 5 additions & 0 deletions .devcontainer/ubuntu.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM ubuntu:22.04

RUN apt update && \
apt -y install git g++-12 make cmake && \
ln -s /usr/bin/g++-12 /usr/bin/g++
98 changes: 58 additions & 40 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,30 @@ env:
VERSION: '1.0.0'

jobs:
Win-VS-17:
runs-on: windows-2022
Build:
strategy:
matrix:
include:
- name: Windows
os: windows-2022
generator: "Visual Studio 17 2022"
artifactName: "nc-convert-windows-x64"
- name: Linux
os: ubuntu-22.04
generator: "Unix Makefiles"
env: "CXX=/usr/bin/g++-12"
definitions: "-DCMAKE_BUILD_TYPE=Release"
artifactName: "nc-convert-ubuntu22.04-x64"

name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}

steps:
- name: Checkout Branch
uses: actions/checkout@v3

- name: Setup MSVC
if: matrix.name == 'Windows'
uses: ilammy/msvc-dev-cmd@v1

- name: Setup Artifact Cache
Expand All @@ -35,58 +52,59 @@ jobs:
key: ${{ runner.os }}_cache_key

- name: Configure
run: cmake -G "Visual Studio 17 2022" -S ./ -B build -DCMAKE_INSTALL_PREFIX=install
run: ${{ matrix.env }} cmake -G "${{ matrix.generator }}" -S ./ -B build ${{ matrix.definitions }} -DCMAKE_INSTALL_PREFIX=install

- name: Build
run: cmake --build build --config "Release"

- name: Install
run: cmake --install build/source --config "Release"
run: cmake --build build --target install --config Release

- name: Run Tests
run: ctest --test-dir build/test -C Release -V
run: ctest --test-dir build/test --output-on-failure --output-junit TestResults.xml

- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.name }}-TestResults
path: build/test/TestResults.xml

- name: Copy artifacts to cache
if: steps.cache.output.cache-hit != true
- name: Copy Artifacts to Cache
if: steps.cache.output.cache-hit != true && matrix.name == 'Windows'
run: |
if (!(Test-Path artifacts)) {
New-Item artifacts -ItemType Directory
}
Copy-Item "install/bin/nc-convert.exe" -Destination "artifacts/"
- name: Copy Artifacts to Cache
if: steps.cache.output.cache-hit != true && matrix.name == 'Linux'
run: |
if [ ! -d artifacts ]
then
mkdir artifacts
fi
cp install/bin/nc-convert artifacts
- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
name: nc-tools
name: ${{ matrix.artifactName }}
path: |
artifacts/nc-convert.exe
artifacts/nc-convert*
CreateRelease:
runs-on: windows-2022
if: inputs.createRelease && github.ref == 'refs/heads/release'
needs: Win-VS-17
Publish-Test-Results:
runs-on: ubuntu-latest
needs: [Build]
permissions:
checks: write
pull-requests: write
if: always()
steps:
- name: Setup Artifact Cache
id: cache
uses: actions/cache@v3
with:
path: artifacts/nc-convert.exe
key: ${{ runner.os }}_cache_key

- name: Create archive
run: 7z a -tzip -mx=9 artifacts/nc-tools.zip artifacts/nc-convert.exe

- name: Hash artifacts
shell: pwsh
run: |
$hash = Get-FileHash -Path /artifacts/nc-tools.zip -Algorithm SHA256
"nc-tools.zip {0}: {1}" -f $hash.Algorithm, $hash.Hash | Out-File -FilePath hash.txt
- name: Create release
uses: softprops/action-gh-release@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
tag_name: ${{ format('v{0}', env.VERSION) }}
body_path: hash.txt
fail_on_unmatched_files: true
files: artifacts/nc-tools.zip
- name: Download Results
uses: actions/download-artifact@v3
with:
path: artifacts
- name: Publish Results
uses: mikepenz/action-junit-report@v3
if: always()
with:
report_paths: 'artifacts/**/*.xml'
1 change: 1 addition & 0 deletions source/ncconvert/builder/BuildInstructions.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <filesystem>
#include <unordered_map>
#include <vector>

namespace nc::convert
{
Expand Down
2 changes: 2 additions & 0 deletions source/ncconvert/utility/BlobSize.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include "ncasset/AssetsFwd.h"

#include <cstddef>

namespace nc::convert
{
/** @brief Get the serialized size in bytes for an AudioClip. */
Expand Down
58 changes: 35 additions & 23 deletions test/integration/NcConvert_integration_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,22 @@
#endif

const auto exePath = std::filesystem::path{NC_CONVERT_EXECUTABLE_PATH};
#ifdef WIN32
const auto exeName = exePath.filename().string();
#else
const auto exeName = "./" + exePath.filename().string();
#endif
const auto ncaTestOutDirectory = collateral::collateralDirectory / "test_temp_dir";

auto RunCmd(const std::string& cmd) -> int
{
#ifdef WIN32
return std::system(cmd.c_str());
#else
return WEXITSTATUS(std::system(cmd.c_str()));
#endif
}

auto BuildSingleTargetCommand(std::string_view type, std::string_view sourceName, std::string_view assetName) -> std::string
{
const auto source = (collateral::collateralDirectory / sourceName).string();
Expand Down Expand Up @@ -48,106 +61,106 @@ class NcConvertIntegration : public ::testing::Test
TEST_F(NcConvertIntegration, SingleTarget_audioClip_succeeds)
{
const auto cmd = BuildSingleTargetCommand("audio-clip", "sine_c_e.wav", "myAudioClip");
ASSERT_EQ(std::system(cmd.c_str()), ResultCode::Success);
ASSERT_EQ(RunCmd(cmd), ResultCode::Success);
EXPECT_TRUE(std::filesystem::exists(ncaTestOutDirectory / "myAudioClip.nca"));
}

TEST_F(NcConvertIntegration, SingleTarget_audioClip_wrongSourceType_fails)
{
const auto cmd = BuildSingleTargetCommand("audio-clip", "cube.fbx", "myAudioClip");
EXPECT_EQ(std::system(cmd.c_str()), ResultCode::RuntimeError);
EXPECT_EQ(RunCmd(cmd), ResultCode::RuntimeError);
}

TEST_F(NcConvertIntegration, SingleTarget_concaveCollider_succeeds)
{
const auto cmd = BuildSingleTargetCommand("concave-collider", "plane.fbx", "myConcaveCollider");
ASSERT_EQ(std::system(cmd.c_str()), ResultCode::Success);
ASSERT_EQ(RunCmd(cmd), ResultCode::Success);
EXPECT_TRUE(std::filesystem::exists(ncaTestOutDirectory / "myConcaveCollider.nca"));
}

TEST_F(NcConvertIntegration, SingleTarget_concaveCollider_wrongSourceType_fails)
{
const auto cmd = BuildSingleTargetCommand("concave-collider", "rgb_corners_4x8.png", "myConcaveCollider");
EXPECT_EQ(std::system(cmd.c_str()), ResultCode::RuntimeError);
EXPECT_EQ(RunCmd(cmd), ResultCode::RuntimeError);
}

TEST_F(NcConvertIntegration, SingleTarget_cubeMap_succeeds)
{
const auto cmd = BuildSingleTargetCommand("cube-map", "cube_map_horizontal_array.png", "myCubemap");
ASSERT_EQ(std::system(cmd.c_str()), ResultCode::Success);
const auto cmd = BuildSingleTargetCommand("cube-map", "cube_map_horizontal_array.png", "myCubeMap");
ASSERT_EQ(RunCmd(cmd), ResultCode::Success);
EXPECT_TRUE(std::filesystem::exists(ncaTestOutDirectory / "myCubeMap.nca"));
}

TEST_F(NcConvertIntegration, SingleTarget_cubeMap_wrongSourceType_fails)
{
const auto cmd = BuildSingleTargetCommand("cube-map", "cube.fbx", "myCubeMap");
EXPECT_EQ(std::system(cmd.c_str()), ResultCode::RuntimeError);
EXPECT_EQ(RunCmd(cmd), ResultCode::RuntimeError);
}

TEST_F(NcConvertIntegration, SingleTarget_hullCollider_succeeds)
{
const auto cmd = BuildSingleTargetCommand("hull-collider", "cube.fbx", "myHullCollider");
ASSERT_EQ(std::system(cmd.c_str()), ResultCode::Success);
ASSERT_EQ(RunCmd(cmd), ResultCode::Success);
EXPECT_TRUE(std::filesystem::exists(ncaTestOutDirectory / "myHullCollider.nca"));
}

TEST_F(NcConvertIntegration, SingleTarget_hullCollider_wrongSourceType_fails)
{
const auto cmd = BuildSingleTargetCommand("hull-collider", "rgb_corners_4x8.png", "myHullCollider");
EXPECT_EQ(std::system(cmd.c_str()), ResultCode::RuntimeError);
EXPECT_EQ(RunCmd(cmd), ResultCode::RuntimeError);
}

TEST_F(NcConvertIntegration, SingleTarget_mesh_succeeds)
{
const auto cmd = BuildSingleTargetCommand("mesh", "cube.fbx", "myMesh");
ASSERT_EQ(std::system(cmd.c_str()), ResultCode::Success);
ASSERT_EQ(RunCmd(cmd), ResultCode::Success);
EXPECT_TRUE(std::filesystem::exists(ncaTestOutDirectory / "myMesh.nca"));
}

TEST_F(NcConvertIntegration, SingleTarget_mesh_wrongSourceType_fails)
{
const auto cmd = BuildSingleTargetCommand("mesh", "rgb_corners_4x8.png", "myMesh");
EXPECT_EQ(std::system(cmd.c_str()), ResultCode::RuntimeError);
EXPECT_EQ(RunCmd(cmd), ResultCode::RuntimeError);
}

TEST_F(NcConvertIntegration, SingleTarget_texture_succeeds)
{
const auto cmd = BuildSingleTargetCommand("texture", "rgb_corners_4x8.png", "myTexture");
ASSERT_EQ(std::system(cmd.c_str()), ResultCode::Success);
ASSERT_EQ(RunCmd(cmd), ResultCode::Success);
EXPECT_TRUE(std::filesystem::exists(ncaTestOutDirectory / "myTexture.nca"));
}

TEST_F(NcConvertIntegration, SingleTarget_texture_wrongSourceType_fails)
{
const auto cmd = BuildSingleTargetCommand("texture", "cube.fbx", "myTexture");
EXPECT_EQ(std::system(cmd.c_str()), ResultCode::RuntimeError);
EXPECT_EQ(RunCmd(cmd), ResultCode::RuntimeError);
}

TEST_F(NcConvertIntegration, SingleTarget_noType_fails)
{
const auto source = (collateral::collateralDirectory / "cube.fbx").string();
const auto cmd = fmt::format(R"({} -s "{}" -n {})", exeName, source, "myMesh");
EXPECT_EQ(std::system(cmd.c_str()), ResultCode::ArgumentError);
EXPECT_EQ(RunCmd(cmd), ResultCode::ArgumentError);
}

TEST_F(NcConvertIntegration, SingleTarget_noSource_fails)
{
const auto cmd = fmt::format(R"({} -t {} -n {})", exeName, "mesh", "myMesh");
EXPECT_EQ(std::system(cmd.c_str()), ResultCode::ArgumentError);
EXPECT_EQ(RunCmd(cmd), ResultCode::ArgumentError);
}

TEST_F(NcConvertIntegration, SingleTarget_noName_fails)
{
const auto source = (collateral::collateralDirectory / "cube.fbx").string();
const auto cmd = fmt::format(R"({} -t mesh -s "{}")", exeName, "mesh", source);
EXPECT_EQ(std::system(cmd.c_str()), ResultCode::ArgumentError);
EXPECT_EQ(RunCmd(cmd), ResultCode::ArgumentError);
}

TEST_F(NcConvertIntegration, Manifest_succeeds)
{
const auto manifestPath = (collateral::collateralDirectory / "manifest.json").string();
const auto cmd = fmt::format(R"({} -m "{}")", exeName, manifestPath);
const auto result = std::system(cmd.c_str());
const auto result = RunCmd(cmd);
ASSERT_EQ(result, ResultCode::Success);
EXPECT_TRUE(std::filesystem::exists(ncaTestOutDirectory / "myAudioClip.nca"));
EXPECT_TRUE(std::filesystem::exists(ncaTestOutDirectory / "myConcaveCollider.nca"));
Expand All @@ -160,25 +173,24 @@ TEST_F(NcConvertIntegration, Manifest_succeeds)
TEST_F(NcConvertIntegration, Manifest_noManifestPath_fails)
{
const auto cmd = fmt::format("{} -m", exeName);
const auto result = std::system(cmd.c_str());
const auto result = RunCmd(cmd);
EXPECT_EQ(result, ResultCode::ArgumentError);
}

TEST_F(NcConvertIntegration, Inspect_succeeds)
{
const auto buildCmd = BuildSingleTargetCommand("texture", "rgb_corners_4x8.png", "myTexture");
const auto buildResult = std::system(buildCmd.c_str());
const auto buildResult = RunCmd(buildCmd);
ASSERT_EQ(buildResult, ResultCode::Success);

const auto targetPath = (ncaTestOutDirectory / "myTexture.nca").string();
const auto inspectCmd = std::format(R"({} -i "{}")", exeName, targetPath);
const auto inspectResult = std::system(inspectCmd.c_str());
const auto inspectCmd = fmt::format(R"({} -i "{}")", exeName, targetPath);
const auto inspectResult = RunCmd(inspectCmd);
EXPECT_EQ(inspectResult, ResultCode::Success);
}

TEST_F(NcConvertIntegration, Inspect_noTarget_fails)
{
const auto cmd = fmt::format("{} -i", exeName);
const auto result = std::system(cmd.c_str());
ASSERT_EQ(result, ResultCode::ArgumentError);
EXPECT_EQ(RunCmd(cmd), ResultCode::ArgumentError);
}

0 comments on commit 223c8ef

Please sign in to comment.