Adding PowerShell-based scripts for Linux and macOS

This commit is contained in:
vector-of-bool 2018-03-11 20:25:17 -06:00
Родитель de0772972a
Коммит 39d88b6897
18 изменённых файлов: 437 добавлений и 63 удалений

3
.gitignore поставляемый
Просмотреть файл

@ -3,5 +3,6 @@ node_modules
.browse.VC.db*
*.old
build/
test/fakebin/*
test/fakebin/
.vscode-test
.ci-build

Просмотреть файл

@ -1,50 +1,38 @@
language: cpp
os:
- osx
# - osx
- linux
compiler:
- clang
# - clang
- gcc
env:
matrix:
- CMAKE_MINOR=3.5 CMAKE_VER=3.5.0
- CMAKE_MINOR=3.7 CMAKE_VER=3.7.0
- CMAKE_MINOR=3.7 CMAKE_VER=3.7.2
dist: trusty
sudo: false
addons:
apt:
sources:
- sourceline: deb [arch=amd64] https://packages.microsoft.com/ubuntu/14.04/prod trusty main
key_url: https://packages.microsoft.com/keys/microsoft.asc
packages:
- powershell
env:
- CMAKE_MINOR=3.7 CMAKE_VER=3.7.2
before_install:
- |
if [ $TRAVIS_OS_NAME == "linux" ]; then
export DISPLAY=:99.0
sh -e /etc/init.d/xvfb start
curl https://cmake.org/files/v${CMAKE_MINOR}/cmake-${CMAKE_VER}-Linux-x86_64.sh -o /tmp/cmake.sh
sudo sh /tmp/cmake.sh --exclude-subdir --prefix=/usr/local
sleep 3
else
curl https://cmake.org/files/v${CMAKE_MINOR}/cmake-${CMAKE_VER}-Darwin-x86_64.tar.gz -o /tmp/cmake.tgz
pushd /tmp
tar xf /tmp/cmake.tgz
if test -e /Applications/CMake.app; then
sudo rm -rf /Applications/CMake.app
fi
sudo cp -r cmake-${CMAKE_VER}-Darwin-x86_64/CMake.app /Applications/
sudo /Applications/CMake.app/Contents/bin/cmake-gui --install
popd
brew tap caskroom/cask || exit 2
brew cask install powershell || exit 2
fi
install:
- npm install
- npm run vscode:prepublish
- bash scripts/prepare_test.sh
script:
- node --version
- cmake --version
- bash scripts/run_tests.sh
- bash scripts/run_extension_tests.sh
script: pwsh -NonInteractive -NoProfile -NoLogo scripts/ci.ps1
notifications:
email:

12
.vscode/tasks.json поставляемый
Просмотреть файл

@ -1,3 +1,13 @@
{
"version": "2.0.0"
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "compile",
"problemMatcher": [
"$tsc-watch"
],
"isBackground": true
}
]
}

Просмотреть файл

@ -9,6 +9,8 @@ tsconfig.json
vsc-extension-quickstart.md
build/**
docs/**
.ci-build/**
.vscode-test/**
cSpell.json
CMakeLists.txt
tslint.json

Просмотреть файл

@ -2,10 +2,13 @@ cmake_minimum_required(VERSION 3.7)
project(CMakeTools VERSION 0.11.0 LANGUAGES NONE)
find_program(NODE_EXECUTABLE node)
find_program(NPM_EXECUTABLE npm)
find_program(VSCE_EXECUTABLE vsce)
find_program(SPHINX_EXECUTABLE sphinx-build)
include(CTest)
get_filename_component(package_json package.json ABSOLUTE)
get_filename_component(package_lock package-lock.json ABSOLUTE)
get_filename_component(npm_stamp "${CMAKE_CURRENT_BINARY_DIR}/npm.stamp" ABSOLUTE)
@ -48,7 +51,7 @@ if(SPHINX_EXECUTABLE)
"${docs_dest}"
)
endif()
add_custom_target(docs
add_custom_target(docs ALL
COMMAND ${SPHINX_EXECUTABLE}
-W # Warning as error
-q # Quiet. Only warnings and errors
@ -69,6 +72,7 @@ if(SPHINX_EXECUTABLE)
${docs_copy}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Generating documentation"
USES_TERMINAL
)
endif()
add_subdirectory(test)

69
scripts/ci.ps1 Normal file
Просмотреть файл

@ -0,0 +1,69 @@
param(
# CMake Version to test with
[Parameter()]
[string]
$CMakeVersion = "3.10.0"
)
$ErrorActionPreference = "Stop"
# The root directory of our repository:
$REPO_DIR = Split-Path (Split-Path $MyInvocation.MyCommand.Source -Parent) -Parent
$SCRIPTS_DIR = Join-Path $REPO_DIR "scripts"
. $SCRIPTS_DIR/util.ps1
Write-Debug "Repository directory is $REPO_DIR"
$cmake_binary = Install-TestCMake -Version $CMakeVersion
ConvertTo-Json $cmake_binary
Write-Host "cmake $cmake_binary"
Write-Debug "Preparing test utilities..."
& $SCRIPTS_DIR/prepare-test.ps1 -CMakePath $cmake_binary
$bindir = Join-Path $REPO_DIR ".ci-build"
& $cmake_binary "-H$REPO_DIR" "-B$bindir"
$retc = $LASTEXITCODE
if ($retc) {
throw "CMake configure failed [$retc]"
}
& $cmake_binary --build $bindir
$retc = $LASTEXITCODE
if ($retc) {
throw "CMake build failed [$retc]"
}
& $cmake_binary -E chdir $bindir ctest --output-on-failure -j4
$retc = $LASTEXITCODE
if ($retc) {
throw "CTest failed [$retc]"
}
# set -eu
# if [[ "$OSTYPE" == "darwin"* ]]; then
# realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; }
# ROOT=$(dirname $(dirname $(realpath "$0")))
# else
# ROOT=$(dirname $(dirname $(readlink -f $0)))
# fi
# cd $ROOT
# echo "CMake on \$PATH: $(type -P cmake)"
# if [ "${CMAKE_VER:-}" != "" ]; then
# echo "Checking CMAKE_VER"
# local cmv=$(cmake --version)
# if cmake --version | grep "${CMAKE_VER}"; then
# echo "CMake version matches expectations"
# else
# echo "CMake version does not match that from the Travis configuration"
# echo "Failing build"
# exit 1
# fi
# else
# echo "CMAKE_VER is not defined. We'll use the following CMake for testing:"
# echo "CMake version: $(cmake --version)"
# fi

35
scripts/prepare-test.ps1 Normal file
Просмотреть файл

@ -0,0 +1,35 @@
param(
# Path to CMake to use when configuring
[Parameter()]
[string]
$CMakePath
)
$ErrorActionPreference = "Stop"
$REPO_DIR = Split-Path (Split-Path $MyInvocation.MyCommand.Source -Parent) -Parent
$fakebin_src = Join-Path $REPO_DIR "test/fakeOutputGenerator"
$fakebin_build = Join-Path $fakebin_src "build"
$conf_out = & $CMakePath "-H$fakebin_src" "-B$fakebin_build"
if ($LASTEXITCODE) {
throw "Failed to parepare tests (configure) [$LASTEXITCODE]: $conf_out"
}
$build_out = & $CMakePath --build $fakebin_build
if ($LASTEXITCODE) {
throw "Failed to parepare tests (configure) [$LASTEXITCODE]: $build_out"
}
$fakebin_dest = Join-Path $REPO_DIR "test/fakebin"
$ext = if ($PSVersionTable.Platform -eq "Unix") { "" } else { ".exe" }
New-Item $fakebin_dest -ItemType Directory -Force | Out-Null
$in_binary = Join-Path $fakebin_build "FakeOutputGenerator$ext"
$targets = @("clang-0.25", "gcc-42.1", "gcc-666")
foreach ($target in $targets) {
Copy-Item $in_binary "$fakebin_dest/$target$ext"
}

103
scripts/util.ps1 Normal file
Просмотреть файл

@ -0,0 +1,103 @@
function Download-File ($Url, $Path) {
# Ensure that the parent directory is present
$parent = Split-Path $Path -Parent
New-Item $parent -ItemType Directory -Force | Out-Null
# Only download if the file does not exist
if (! (Test-Path $installer_file -PathType Leaf)) {
Write-Host "Downloading from $Url -> $Path ..."
$tmp = "$Path-tmp"
try {
Invoke-WebRequest $Url -UseBasicParsing -OutFile "$tmp" | Out-Null
Rename-Item $tmp $Path
}
finally {
if (Test-Path $tmp) {
Remove-Item $tmp -Force
}
}
}
else {
Write-Host "Cached download file $Path"
}
}
function Install-TestCMake ($Version) {
if ($PSVersionTable.Platform -eq "Unix") {
$test_cmake_dir = Join-Path $env:HOME ".local/share/CMakeTools/test-cmake-root/$Version"
}
else {
$test_cmake_dir = Join-Path $env:AppData "CMakeTools/test-cmake-root/$Version"
}
if ($PSVersionTable.Platform -eq "Windows") {
$cmake_bin = Join-Path $test_cmake_dir "bin/cmake.exe"
}
else {
$cmake_bin = Join-Path $test_cmake_dir "bin/cmake"
}
if (Test-Path $cmake_bin -PathType Leaf) {
Write-Host "Using existing CMake test root at $test_cmake_dir"
return $cmake_bin
}
$cmake_minor = if ($Version -match "(\d+\.\d+)\.\d+") {
$Matches[1]
}
else {
throw "Invalid CMake version number: $cmake_minor"
}
$cmake_files_url = "https://cmake.org/files/v$cmake_minor"
Write-Host "Installing CMake $Version for testing at $test_cmake_dir"
$tmpdir = "$test_cmake_dir-tmp"
New-Item $tmpdir -ItemType Directory -Force | Out-Null
if ($CMakeVersion -match "(\d+\.\d+)\.\d+") {
$cmake_minor = $Matches[1]
Write-Debug "CMake minor version is $cmake_minor"
}
else {
throw "Invalid CMake version string: $CMakeVersion"
}
if ($PSVersionTable.OS.StartsWith("Microsoft Windows")) {
throw "Unimplemented for Windows"
}
elseif ($PSVersionTable.OS.StartsWith("Linux")) {
# Install using the Linux self-extracting shell script executable
$installer_url = "$cmake_files_url/cmake-$CMakeVersion-Linux-x86_64.sh"
$installer_file = "/tmp/cmake-$CMakeVersion.sh"
Download-File -Url $installer_url -Path $installer_file
Write-Host "Installing CMake $Version to $tmpdir ..."
& bash $installer_file --prefix=$tmpdir --exclude-subdir | Out-Null
if (Test-Path -LiteralPath $test_cmake_dir) {
Remove-Item $test_cmake_dir -Force -Recurse
}
Rename-Item $tmpdir $test_cmake_dir | Out-Null
}
elseif ($PSVersionTable.OS.StartsWith("Darwin")) {
$installer_url = "$cmake_files_url/cmake-$CMakeVersion-Darwin-x86_64.tar.gz"
$installer_file = Join-Path $tmpdir "/cmake-$CMakeVersion.tgz"
Download-File -Url $installer_url -Path $installer_file
pushd /tmp
& tar xf $installer_file
Copy-Item `
-Path "/tmp/cmake-$Version-Darwin-x86_64/CMake.app/Contents" `
-Destination $test_cmake_dir `
-Recurse `
-Verbose
# Get-ChildItem $test_cmake_dir -Recurse | Write-Host
}
Write-Host "Successfully created CMake installation for testing at $test_cmake_dir"
& $cmake_bin --version | Write-Host
return $cmake_bin
}

39
test/CMakeLists.txt Normal file
Просмотреть файл

@ -0,0 +1,39 @@
add_test(
NAME cmt.lint.tslint
COMMAND "${NODE_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/node_modules/tslint/bin/tslint" -p "${PROJECT_SOURCE_DIR}"
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
)
set(code_ext_lock vscode.runlock)
add_test(
NAME cmt.test.unit.all
COMMAND "${NODE_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/node_modules/vscode/bin/test"
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
)
set(unit_env
CMT_TESTING=1
CODE_TESTS_PATH=${PROJECT_SOURCE_DIR}/out/test/unit-tests
CODE_TESTS_WORKSPACE=${PROJECT_SOURCE_DIR}/test/unit-tests/test-project-without-cmakelists
)
set_tests_properties(cmt.test.unit.all PROPERTIES
ENVIRONMENT "${unit_env}"
RESOURCE_LOCK "${code_ext_lock}"
)
foreach(test vs-preferred-gen successful-build without-cmakelist-file)
set(name cmt.test.smoke.${test})
add_test("${name}"
${NODE_EXECUTABLE} ${PROJECT_SOURCE_DIR}/node_modules/vscode/bin/test
)
set(env
CMT_TESTING=1
CODE_TESTS_PATH=${PROJECT_SOURCE_DIR}/out/test/extension-tests/${test}
CODE_TESTS_WORKSPACE=${PROJECT_SOURCE_DIR}/test/extension-tests/${test}/project-folder
)
set_tests_properties("${name}" PROPERTIES
ENVIRONMENT "${env}"
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
RESOURCE_LOCK "${code_ext_lock}"
)
endforeach()

Просмотреть файл

@ -1,4 +1,3 @@
{
"cmake.buildDirectory": "${workspaceRoot}/build",
"cmake.preferredGenerators": [ ]
"cmake.buildDirectory": "${workspaceRoot}/build"
}

Просмотреть файл

@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 3.0.0)
project(TestBuildProcess VERSION 0.1.0)
add_executable(TestBuildProcess main.cpp)
add_custom_command(
TARGET TestBuildProcess
POST_BUILD
COMMAND $<TARGET_FILE:TestBuildProcess> > output.txt
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Running in ${CMAKE_CURRENT_BINARY_DIR}"
)

Просмотреть файл

@ -1,23 +1,4 @@
#include <iostream>
#include <string>
#ifndef _CMAKE_VERSION
#define _CMAKE_VERSION "0.0"
#endif
std::string getCompilerName() {
#if defined(__clang__)
return "Clang/LLVM";
#elif defined(__GNUC__) || defined(__GNUG__)
return "GNU GCC/G++";
#elif defined(_MSC_VER)
return "Microsoft Visual Studio";
#endif
}
int main(int, char**) {
std::cout << "{\n";
std::cout << " \"compiler\": \"" << getCompilerName() << "\",\n";
std::cout << " \"cmake-version\": \"" << _CMAKE_VERSION << "\"\n";
std::cout << "}\n";
}
int main(int, char**) { std::cout << "{ \"cookie\": \"passed-cookie\" }"; }

Просмотреть файл

@ -14,12 +14,14 @@ suite('Build', async() => {
let testEnv: DefaultEnvironment;
setup(async function(this: Mocha.IBeforeAndAfterContext) {
if (process.env.HasVs != 'true') {
this.skip();
}
this.timeout(100000);
testEnv = new DefaultEnvironment('test/extension-tests/successful-build/project-folder');
const kit_re = '';
const build_loc = 'build';
const exe_res = 'output.txt';
testEnv
= new DefaultEnvironment('test/extension-tests/successful-build/project-folder', build_loc, exe_res, kit_re);
cmt = await CMakeTools.create(testEnv.vsContext);
// This test will use all on the same kit.
@ -48,7 +50,7 @@ suite('Build', async() => {
expect(await cmt.build()).to.be.eq(0);
const result = await testEnv.result.getResultAsJson();
expect(result['compiler']).to.eq('Microsoft Visual Studio');
expect(result['cookie']).to.eq('passed-cookie');
}).timeout(60000);
@ -57,7 +59,7 @@ suite('Build', async() => {
expect(await cmt.build()).to.be.eq(0);
const result = await testEnv.result.getResultAsJson();
expect(result['compiler']).to.eq('Microsoft Visual Studio');
expect(result['cookie']).to.eq('passed-cookie');
}).timeout(60000);
test('Configure and Build', async() => {
@ -65,7 +67,7 @@ suite('Build', async() => {
expect(await cmt.build()).to.be.eq(0);
const result = await testEnv.result.getResultAsJson();
expect(result['compiler']).to.eq('Microsoft Visual Studio');
expect(result['cookie']).to.eq('passed-cookie');
}).timeout(60000);
test('Test setting watcher', async() => {

Просмотреть файл

@ -0,0 +1,23 @@
//
// PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING
//
// This file is providing the test runner to use when running extension tests.
// By default the test runner in use is Mocha based.
//
// You can provide your own test runner if you want to override it by exporting
// a function run(testRoot: string, clb: (error:Error) => void) that the extension
// host can call to run the tests. The test runner is expected to use console.log
// to report the results back to the caller. When the tests are finished, return
// a possible error to the callback or null if none.
// tslint:disable-next-line:no-var-keyword
var testRunner = require('vscode/lib/testrunner');
// You can directly control Mocha options by uncommenting the following lines
// See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info
testRunner.configure({
ui : 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.)
useColors : true // colored output from test results
});
module.exports = testRunner;

Просмотреть файл

@ -0,0 +1,4 @@
{
"cmake.buildDirectory": "${workspaceRoot}/build",
"cmake.preferredGenerators": [ ]
}

Просмотреть файл

@ -0,0 +1,23 @@
#include <iostream>
#include <string>
#ifndef _CMAKE_VERSION
#define _CMAKE_VERSION "0.0"
#endif
std::string getCompilerName() {
#if defined(__clang__)
return "Clang/LLVM";
#elif defined(__GNUC__) || defined(__GNUG__)
return "GNU GCC/G++";
#elif defined(_MSC_VER)
return "Microsoft Visual Studio";
#endif
}
int main(int, char**) {
std::cout << "{\n";
std::cout << " \"compiler\": \"" << getCompilerName() << "\",\n";
std::cout << " \"cmake-version\": \"" << _CMAKE_VERSION << "\"\n";
std::cout << "}\n";
}

Просмотреть файл

@ -0,0 +1,79 @@
import * as chai from 'chai';
import {expect} from 'chai';
import * as chaiAsPromised from 'chai-as-promised';
chai.use(chaiAsPromised);
import {clearExistingKitConfigurationFile} from '../../../test-helpers';
import {DefaultEnvironment} from '../../../helpers/test/default-environment';
import {CMakeTools} from '../../../../src/cmake-tools';
import config from '../../../../src/config';
suite('Build', async() => {
let cmt: CMakeTools;
let testEnv: DefaultEnvironment;
setup(async function(this: Mocha.IBeforeAndAfterContext) {
if (process.env.HasVs != 'true') {
this.skip();
}
this.timeout(100000);
testEnv = new DefaultEnvironment('test/extension-tests/successful-build/project-folder');
cmt = await CMakeTools.create(testEnv.vsContext);
// This test will use all on the same kit.
// No rescan of the tools is needed
// No new kit selection is needed
await clearExistingKitConfigurationFile();
await cmt.scanForKits();
await cmt.selectKit();
testEnv.projectFolder.buildDirectory.clear();
});
teardown(async function(this: Mocha.IBeforeAndAfterContext) {
this.timeout(30000);
await cmt.asyncDispose();
testEnv.teardown();
});
test('Configure ', async() => {
expect(await cmt.configure()).to.be.eq(0);
expect(testEnv.projectFolder.buildDirectory.isCMakeCachePresent).to.eql(true, 'no expected cache present');
}).timeout(60000);
test('Build', async() => {
expect(await cmt.build()).to.be.eq(0);
const result = await testEnv.result.getResultAsJson();
expect(result['compiler']).to.eq('Microsoft Visual Studio');
}).timeout(60000);
test('Configure and Build', async() => {
expect(await cmt.configure()).to.be.eq(0);
expect(await cmt.build()).to.be.eq(0);
const result = await testEnv.result.getResultAsJson();
expect(result['compiler']).to.eq('Microsoft Visual Studio');
}).timeout(60000);
test('Configure and Build', async() => {
expect(await cmt.configure()).to.be.eq(0);
expect(await cmt.build()).to.be.eq(0);
const result = await testEnv.result.getResultAsJson();
expect(result['compiler']).to.eq('Microsoft Visual Studio');
}).timeout(60000);
test('Test setting watcher', async() => {
expect(config.buildDirectory).to.be.eq('${workspaceRoot}/build');
await testEnv.setting.changeSetting('buildDirectory', 'Hallo');
expect(config.buildDirectory).to.be.eq('Hallo');
testEnv.setting.restore();
expect(config.buildDirectory).to.be.eq('${workspaceRoot}/build');
});
});