PowerShell-only CI process
This commit is contained in:
Родитель
e876ba7409
Коммит
a6a414ef15
|
@ -1,79 +0,0 @@
|
|||
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)
|
||||
add_custom_command(OUTPUT ${npm_stamp}
|
||||
DEPENDS ${package_json}
|
||||
COMMAND ${NPM_EXECUTABLE} install
|
||||
COMMAND ${CMAKE_COMMAND} -E touch ${npm_stamp}
|
||||
COMMENT "Installing dependencies..."
|
||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
||||
USES_TERMINAL
|
||||
)
|
||||
add_custom_target(npm-install DEPENDS ${package_lock} ${npm_stamp})
|
||||
|
||||
add_custom_target(compile ALL
|
||||
DEPENDS npm-install
|
||||
COMMAND ${NPM_EXECUTABLE} run compile-once
|
||||
COMMENT "Compiling TypeScript code..."
|
||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
||||
# USES_TERMINAL
|
||||
)
|
||||
|
||||
add_custom_target(vsce-package
|
||||
DEPENDS npm-install
|
||||
COMMAND ${VSCE_EXECUTABLE} package
|
||||
COMMENT "Generating VSCode package"
|
||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
||||
)
|
||||
|
||||
if(SPHINX_EXECUTABLE)
|
||||
message(STATUS "Build documentation with the `docs` target")
|
||||
# This docs-copy logic is just for uploading it to my personal site at
|
||||
# vector-of-bool.github.io via Jekyll. Don't worry about it too much.
|
||||
get_filename_component(vb_site_dir "${CMAKE_CURRENT_SOURCE_DIR}/../vb-site/" ABSOLUTE)
|
||||
if(IS_DIRECTORY "${vb_site_dir}")
|
||||
message(STATUS "Copying documentation to vb-site")
|
||||
get_filename_component(docs_dest "${vb_site_dir}/docs/vscode-cmake-tools" ABSOLUTE)
|
||||
set(docs_copy
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/docs"
|
||||
"${docs_dest}"
|
||||
)
|
||||
endif()
|
||||
add_custom_target(docs ALL
|
||||
DEPENDS npm-install
|
||||
COMMAND ${SPHINX_EXECUTABLE}
|
||||
-W # Warning as error
|
||||
-q # Quiet. Only warnings and errors
|
||||
-C
|
||||
-D source_suffix=.rst
|
||||
-D master_doc=index
|
||||
-D project=${PROJECT_NAME}
|
||||
-D version=${PROJECT_VERSION}
|
||||
-D release=${PROJECT_VERSION}
|
||||
-D pygments_style=sphinx
|
||||
-D html_theme=nature
|
||||
-D html_logo=../res/icon_190.svg
|
||||
-b html
|
||||
-j 10
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/docs"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/docs"
|
||||
COMMAND "${NPM_EXECUTABLE}" run docs
|
||||
${docs_copy}
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
COMMENT "Generating documentation"
|
||||
)
|
||||
endif()
|
||||
|
||||
add_subdirectory(test)
|
|
@ -658,6 +658,7 @@
|
|||
"compile-once": "./node_modules/.bin/tsc -p ./",
|
||||
"postinstall": "node ./node_modules/vscode/bin/install",
|
||||
"lint": "node ./node_modules/tslint/bin/tslint -p . --fix",
|
||||
"lint:nofix": "node ./node_modules/tslint/bin/tslint -p .",
|
||||
"docs": "node ./node_modules/.bin/typedoc --mode modules --excludeExternals --out build/docs/dev --readme none src/"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -7,26 +7,97 @@ param(
|
|||
# Regex to match to run tests (Default is to run all tests)
|
||||
[Parameter()]
|
||||
[string]
|
||||
$TestRegex = "."
|
||||
$TestRegex = ".",
|
||||
# Target directory to copy documentation tree
|
||||
[Parameter()]
|
||||
[string]
|
||||
$DocDestination
|
||||
)
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$CMakeToolsVersion = "0.11.0"
|
||||
|
||||
# Import the utility modules
|
||||
Import-Module (Join-Path $PSScriptRoot "cmt.psm1")
|
||||
|
||||
# The root directory of our repository:
|
||||
$REPO_DIR = Split-Path $PSScriptRoot -Parent
|
||||
$SCRIPTS_DIR = Join-Path $REPO_DIR "scripts"
|
||||
|
||||
Write-Verbose "Repository directory is $REPO_DIR"
|
||||
# Sanity check for npm
|
||||
$npm = Find-Program npm
|
||||
if (! $npm) {
|
||||
throw "No 'npm' binary. Cannot build."
|
||||
}
|
||||
|
||||
# Install dependencies for the project
|
||||
Invoke-ChronicCommand "npm install" $npm install
|
||||
|
||||
# Now do the real compile
|
||||
Invoke-ChronicCommand "Compiling TypeScript" $npm run compile-once
|
||||
|
||||
# Run TSLint to check for silly mistakes
|
||||
Invoke-ChronicCommand "Running TSLint" $npm run lint:nofix
|
||||
|
||||
# Get the CMake binary that we will use to run our tests
|
||||
$cmake_binary = Install-TestCMake -Version $CMakeVersion
|
||||
Write-Host "cmake $cmake_binary"
|
||||
|
||||
Write-Verbose "Preparing test utilities..."
|
||||
# Prepare to run our tests
|
||||
Invoke-TestPreparation -CMakePath $cmake_binary
|
||||
|
||||
$bindir = Join-Path $REPO_DIR ".ci-build"
|
||||
Invoke-VSCodeTest "CMake Tools: Unit tests" `
|
||||
-TestsPath "$REPO_DIR/out/test/unit-tests" `
|
||||
-Workspace "$REPO_DIR/test/unit-tests/test-project-without-cmakelists"
|
||||
|
||||
Invoke-ExternalCommand $cmake_binary "-H$REPO_DIR" "-B$bindir"
|
||||
Invoke-ExternalCommand $cmake_binary --build $bindir
|
||||
Invoke-ExternalCommand -WorkDir $bindir ctest --output-on-failure -j4 -R $TestRegex "-C" Debug
|
||||
foreach ($name in @("vs-preferred-gen"; "successful-build"; "without-cmakelist-file"; )) {
|
||||
Invoke-VSCodeTest "CMake Tools: $name" `
|
||||
-TestsPath "$REPO_DIR/out/test/extension-tests/$name" `
|
||||
-Workspace "$REPO_DIR/test/extension-tests/$name/project-folder"
|
||||
}
|
||||
|
||||
$doc_build = Join-Path $REPO_DIR "build/docs"
|
||||
$sphinx = Find-Program sphinx-build
|
||||
if (! $sphinx) {
|
||||
Write-Warning "Install Sphinx to generate documentation"
|
||||
}
|
||||
else {
|
||||
$command = @(
|
||||
$sphinx;
|
||||
"-W"; # Warnings are errors
|
||||
"-q"; # Be quiet
|
||||
"-C";
|
||||
"-Dsource_suffix=.rst";
|
||||
"-Dmaster_doc=index";
|
||||
"-Dproject=CMake Tools";
|
||||
"-Dversion=$CMakeToolsVersion";
|
||||
"-Drelease=$CMakeToolsVersion";
|
||||
"-Dpygments_style=sphinx";
|
||||
"-Dhtml_theme=nature";
|
||||
"-Dhtml_logo=$REPO_DIR/res/icon_190.svg";
|
||||
"-bhtml";
|
||||
"-j10";
|
||||
"-a";
|
||||
"$REPO_DIR/docs";
|
||||
$doc_build
|
||||
)
|
||||
Invoke-ChronicCommand "Generating user documentation" @command
|
||||
}
|
||||
|
||||
Invoke-ChronicCommand "Generating developer documentation" $npm run docs
|
||||
|
||||
if ($DocDestination) {
|
||||
Write-Information "Copying documentation tree to $DocDestination"
|
||||
Remove-Item $DocDestination -Recurse -Force
|
||||
Copy-Item $doc_build -Destination $DocDestination -Recurse
|
||||
}
|
||||
|
||||
# Invoke-ExternalCommand $cmake_binary "-H$REPO_DIR" "-B$bindir"
|
||||
# Invoke-ExternalCommand $cmake_binary --build $bindir
|
||||
# Invoke-ExternalCommand -WorkDir $bindir ctest --output-on-failure -j4 -R $TestRegex "-C" Debug
|
||||
|
||||
$vsce = Find-Program vsce
|
||||
if (! $vsce) {
|
||||
Write-Warning "You don't have 'vsce' installed. We won't generate a .vsix package"
|
||||
}
|
||||
else {
|
||||
Invoke-ChronicCommand "Generating VSIX package" $vsce package
|
||||
}
|
||||
|
|
122
scripts/cmt.psm1
122
scripts/cmt.psm1
|
@ -1,3 +1,25 @@
|
|||
function Find-Program {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
# Name of the program to find
|
||||
[Parameter()]
|
||||
[string]
|
||||
$Name
|
||||
)
|
||||
|
||||
$msg = "Searching for program $Name"
|
||||
Write-Verbose $msg
|
||||
$results = @(Get-Command -Name $Name -CommandType Application -ErrorAction SilentlyContinue)
|
||||
if ($results.Length -eq 0) {
|
||||
Write-Verbose "$msg - Not found"
|
||||
return $null
|
||||
}
|
||||
$first = $results[0]
|
||||
$item = Get-Item $First.Path
|
||||
Write-Verbose "$msg - Found: ${item.FullName}"
|
||||
return $item
|
||||
}
|
||||
|
||||
function Invoke-ExternalCommand {
|
||||
[CmdletBinding(PositionalBinding = $false)]
|
||||
param(
|
||||
|
@ -12,17 +34,17 @@ function Invoke-ExternalCommand {
|
|||
# Command to execute
|
||||
[Parameter(ValueFromRemainingArguments = $True, Mandatory = $True)]
|
||||
[string[]]
|
||||
$Command
|
||||
$_Command,
|
||||
# Don't pipe output to the host console
|
||||
[Parameter()]
|
||||
[switch]
|
||||
$HideOutput
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$programs = (Get-Command -CommandType Application -Name $Command[0])
|
||||
if ($programs.Length -eq 0) {
|
||||
throw "No programs match the requested command"
|
||||
}
|
||||
$program = $programs[0].Path
|
||||
$arglist = $Command.Clone()
|
||||
$program = $_Command[0]
|
||||
$arglist = $_Command.Clone()
|
||||
$arglist = $arglist[1..$arglist.Length]
|
||||
|
||||
if (! $WorkDir) {
|
||||
|
@ -31,23 +53,72 @@ function Invoke-ExternalCommand {
|
|||
|
||||
Push-Location $WorkDir
|
||||
try {
|
||||
& $program @arglist | Out-Host
|
||||
$ErrorActionPreference = "Continue"
|
||||
if ($HideOutput) {
|
||||
$output = & $program @arglist 2>&1
|
||||
}
|
||||
else {
|
||||
& $program @arglist | Tee-Object -Variable output | Out-Host
|
||||
}
|
||||
$retc = $LASTEXITCODE
|
||||
}
|
||||
finally {
|
||||
$ErrorActionPreference = "Stop"
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
$stderr = $output | Where-Object { $_ -is [System.Management.Automation.ErrorRecord] }
|
||||
$stdout = $output | Where-Object { $_ -isnot [System.Management.Automation.ErrorRecord] }
|
||||
$stderr = $stderr -join "`n"
|
||||
$stdout = $stdout -join "`n"
|
||||
|
||||
if (! $PassThruExitCode) {
|
||||
if ($retc -ne 0) {
|
||||
throw "Executing program $program failed with exit code $retc"
|
||||
}
|
||||
}
|
||||
else {
|
||||
return $retc
|
||||
return @{
|
||||
ExitCode = $retc;
|
||||
Output = $stdout;
|
||||
Error = $stderr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-ChronicCommand {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
# Description for the command
|
||||
[Parameter(Mandatory)]
|
||||
[string]
|
||||
$Description,
|
||||
# The command to run
|
||||
[Parameter(ValueFromRemainingArguments, Mandatory)]
|
||||
[string[]]
|
||||
$_Command_
|
||||
)
|
||||
|
||||
$msg = "==> $Description"
|
||||
Write-Host $msg
|
||||
Write-Debug "About to execute $_Command_"
|
||||
$closure = @{}
|
||||
$measurement = Measure-Command {
|
||||
$result = Invoke-ExternalCommand -HideOutput -PassThruExitCode @_Command_
|
||||
$closure.Result = $result
|
||||
}
|
||||
$result = $closure.Result
|
||||
if ($result.ExitCode -ne 0) {
|
||||
Write-Host "$msg - Failed with status $($result.ExitCode)"
|
||||
Write-Host $result.Output
|
||||
Write-Error $result.Error
|
||||
throw "Subcommand failed!"
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host "$msg - Success [$([math]::round($measurement.TotalSeconds, 1)) seconds]"
|
||||
}
|
||||
|
||||
function Invoke-TestPreparation {
|
||||
param(
|
||||
# Path to CMake to use
|
||||
|
@ -60,8 +131,8 @@ function Invoke-TestPreparation {
|
|||
$fakebin_src = Join-Path $repo_dir "test/fakeOutputGenerator"
|
||||
$fakebin_build = Join-Path $fakebin_src "build"
|
||||
|
||||
Invoke-ExternalCommand $CMakePath "-H$fakebin_src" "-B$fakebin_build"
|
||||
Invoke-ExternalCommand $CMakePath --build $fakebin_build
|
||||
Invoke-ChronicCommand "Configuring test utilities" $CMakePath "-H$fakebin_src" "-B$fakebin_build"
|
||||
Invoke-ChronicCommand "Building test utilities" $CMakePath --build $fakebin_build
|
||||
|
||||
$fakebin_dest = Join-Path $repo_dir "test/fakebin"
|
||||
|
||||
|
@ -189,4 +260,33 @@ function Install-TestCMake ($Version) {
|
|||
Write-Host "Successfully created CMake installation for testing at $test_cmake_dir"
|
||||
& $cmake_bin --version | Write-Host
|
||||
return $cmake_bin
|
||||
}
|
||||
|
||||
function Invoke-VSCodeTest {
|
||||
[CmdletBinding(PositionalBinding = $false)]
|
||||
param(
|
||||
# Description for the test
|
||||
[Parameter(Position = 0, Mandatory)]
|
||||
[string]
|
||||
$Description,
|
||||
# Directory holding the test runner
|
||||
[Parameter(Mandatory)]
|
||||
[string]
|
||||
$TestsPath,
|
||||
# Directory to use as the workspace
|
||||
[Parameter(Mandatory)]
|
||||
[string]
|
||||
$Workspace
|
||||
)
|
||||
$ErrorActionPreference = "Stop"
|
||||
$node = Find-Program node
|
||||
if (! $node) {
|
||||
throw "Cannot run tests: no 'node' command found"
|
||||
}
|
||||
$repo_dir = Split-Path $PSScriptRoot -Parent
|
||||
$test_bin = Join-Path $repo_dir "/node_modules/vscode/bin/test"
|
||||
$env:CMT_TESTING = 1
|
||||
$env:CODE_TESTS_PATH = $TestsPath
|
||||
$env:CODE_TESTS_WORKSPACE = $Workspace
|
||||
Invoke-ChronicCommand "Executing VSCode test: $Description" $node $test_bin
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
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()
|
Загрузка…
Ссылка в новой задаче