Merge pull request #341 from vector-of-bool/feature/ci-refactor

CI + Build Refactor
This commit is contained in:
vector-of-bool 2018-03-17 18:16:47 -06:00 коммит произвёл GitHub
Родитель 617d464daa ef5fd06ab2
Коммит 0534ee4701
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
27 изменённых файлов: 717 добавлений и 169 удалений

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

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

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

@ -8,45 +8,35 @@ compiler:
- 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:
webhooks:
- https://webhooks.gitter.im/e/064f3494f67de1248aa0
email:
on_success: change
on_failure: always

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

@ -106,6 +106,43 @@
"${workspaceRoot}/out/test/extension-tests/successful-build/test/*"
],
"preLaunchTask": "npm",
"windows": {
"env": {
"CMT_TESTING": "1",
"CMT_QUIET_CONSOLE": "1",
"HasVs": "true"
}
},
"linux": {
"env": {
"CMT_TESTING": "1",
"CMT_QUIET_CONSOLE": "1",
"HasVs": "false"
}
}
// "smartStep": true
},
{
"name": "Launch Extension Tests (vs-preferred-gen)",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"${workspaceRoot}/test/extension-tests/vs-preferred-gen/project-folder",
"--extensionDevelopmentPath=${workspaceRoot}",
"--extensionTestsPath=${workspaceRoot}/out/test/extension-tests/vs-preferred-gen"
],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [
"${workspaceRoot}/out/*",
"${workspaceRoot}/out/src/*",
"${workspaceRoot}/out/test/*",
"${workspaceRoot}/out/test/extension-tests/vs-preferred-gen/*",
"${workspaceRoot}/out/test/extension-tests/vs-preferred-gen/test/*"
],
"preLaunchTask": "npm",
"windows": {
"env": {

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

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

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

@ -1,74 +0,0 @@
cmake_minimum_required(VERSION 3.7)
project(CMakeTools VERSION 0.11.0 LANGUAGES NONE)
find_program(NPM_EXECUTABLE npm)
find_program(VSCE_EXECUTABLE vsce)
find_program(SPHINX_EXECUTABLE sphinx-build)
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
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"
USES_TERMINAL
)
endif()

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

@ -1,18 +1,19 @@
version: 1.0.{build}-{branch}
image:
- Visual Studio 2017
- Visual Studio 2017 Preview
- Visual Studio 2015
- Visual Studio 2013
- Visual Studio 2017
- Visual Studio 2017 Preview
- Visual Studio 2015
- Visual Studio 2013
install:
- ps: Install-Product node 8.9.1 x64
- cmd: npm install --loglevel=error
- ps: Install-Product node 8.9.1 x64
build_script:
- cmd: npm run vscode:prepublish
- cmd: scripts/prepare_test.bat
test_script:
- cmd: |
node --version
scripts/run_tests.bat
scripts/run_extension_tests.bat
- pwsh: ./scripts/ci.ps1
notifications:
- provider: Webhook
url: https://webhooks.gitter.im/e/7a2944eb6940f46466b9
method: POST
on_build_success: true
on_build_failure: true
on_build_status_changed: true

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

@ -81,7 +81,7 @@ which will be passed onto CMake when configuring and to the compiler.
- *Supports substitution*
``cmake.configureEnvironment``
***************************
******************************
An object containing ``key : value`` pairs of environment variables,
which will be passed onto CMake *ONLY* when configuring.

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

@ -20,7 +20,7 @@
],
"publisher": "vector-of-bool",
"engines": {
"vscode": "^1.16.0"
"vscode": "^1.21.0"
},
"categories": [
"Other"
@ -658,7 +658,8 @@
"compile-once": "./node_modules/.bin/tsc -p ./",
"postinstall": "node ./node_modules/vscode/bin/install",
"lint": "node ./node_modules/tslint/bin/tslint -p . --fix",
"docs": "node ./node_modules/.bin/typedoc --mode modules --excludeExternals --out build/docs/dev --readme none src/"
"lint:nofix": "node ./node_modules/tslint/bin/tslint -p .",
"docs": "node ./node_modules/typedoc/bin/typedoc --mode modules --excludeExternals --out build/docs/dev --readme none src/"
},
"devDependencies": {
"@types/ajv": "^0.0.3",
@ -682,7 +683,7 @@
"tslint": "^5.9.1",
"typedoc": "^0.8.0",
"typescript": "~2.3.0",
"vscode": "~1.1.5"
"vscode": "1.1.13"
},
"dependencies": {
"Polymer": "1.6.1--",

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

@ -0,0 +1,112 @@
[CmdletBinding(SupportsShouldProcess)]
param(
# CMake Version to test with
[Parameter()]
[string]
$CMakeVersion = "3.10.0",
# Run the named tests
[Parameter()]
[string[]]
$Test,
# 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
if ($Test) {
foreach ($testname in $Test) {
Invoke-SmokeTest $testname
}
return
}
# Sanity check for npm
$npm = Find-Program npm
if (! $npm) {
throw "No 'npm' binary. Cannot build."
}
$out_dir = Join-Path $REPO_DIR out
if (Test-Path $out_dir) {
Write-Verbose "Removing out/ directory: $out_dir"
Remove-Item -Recurse $out_dir
}
# 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
# Prepare to run our tests
Invoke-TestPreparation -CMakePath $cmake_binary
Invoke-VSCodeTest "CMake Tools: Unit tests" `
-TestsPath "$REPO_DIR/out/test/unit-tests" `
-Workspace "$REPO_DIR/test/unit-tests/test-project-without-cmakelists"
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
}
$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
}

311
scripts/cmt.psm1 Normal file
Просмотреть файл

@ -0,0 +1,311 @@
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(
# Ignore the exit code and return it unchanged
[Parameter()]
[switch]
$PassThruExitCode,
# Directory in which to run the command
[Parameter()]
[string]
$WorkDir,
# Command to execute
[Parameter(ValueFromRemainingArguments = $True, Mandatory = $True)]
[string[]]
$_Command,
# Don't pipe output to the host console
[Parameter()]
[switch]
$HideOutput
)
$ErrorActionPreference = "Stop"
$program = $_Command[0]
$arglist = $_Command.Clone()
$arglist = $arglist[1..$arglist.Length]
if (! $WorkDir) {
$WorkDir = $PWD
}
Push-Location $WorkDir
try {
$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 @{
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
[string]
$CMakePath = "cmake"
)
$ErrorActionPreference = "Stop"
$repo_dir = Split-Path $PSScriptRoot -Parent
$fakebin_src = Join-Path $repo_dir "test/fakeOutputGenerator"
$fakebin_build = Join-Path $fakebin_src "build"
if (Test-Path $fakebin_build) {
Write-Verbose "Removing fakeOutputGenerator build dir: $fakebin_build"
Remove-Item $fakebin_build -Recurse
}
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"
if (Test-Path $fakebin_dest) {
Write-Verbose "Removing fakebin executable directory: $fakebin_dest"
Remove-Item $fakebin_dest -Recurse
}
New-Item $fakebin_dest -ItemType Directory -Force | Out-Null
$ext = if ($PSVersionTable.Platform -eq "Unix") { "" } else { ".exe" }
$in_binary = (Get-ChildItem $fakebin_build -Recurse -Filter "FakeOutputGenerator$ext").FullName
$targets = @("clang-0.25", "gcc-42.1", "gcc-666", "clang-8.1.0")
foreach ($target in $targets) {
Copy-Item $in_binary "$fakebin_dest/$target$ext"
}
Copy-Item $fakebin_src/configfiles/* -Destination $fakebin_dest -Recurse
}
function Get-RemoteFile ($Url, $Path) {
$ErrorActionPreference = "Stop"
# Ensure that the parent directory is present
Write-Debug "Downloading $Url to $Path"
$parent = Split-Path $Path -Parent
New-Item $parent -ItemType Directory -Force | Out-Null
# Only download if the file does not exist
if (! (Test-Path $Path -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) {
$ErrorActionPreference = "Stop"
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 "Unix") {
$cmake_bin = Join-Path $test_cmake_dir "bin/cmake"
}
else {
$cmake_bin = Join-Path $test_cmake_dir "bin/cmake.exe"
}
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: $Version"
}
$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"
if (Test-Path $tmpdir) {
Remove-Item $tmpdir -Recurse
}
New-Item $tmpdir -ItemType Directory -Force | Out-Null
if ($PSVersionTable.OS.StartsWith("Microsoft Windows")) {
$zip_url = "$cmake_files_url/cmake-$Version-win64-x64.zip"
$zip_file = Join-Path "$env:TEMP" "cmake-$Version.zip"
Write-Debug "Downloading $zip_url and saving it to $zip_file"
Get-RemoteFile -Url $zip_url -Path $zip_file
Expand-Archive $zip_file -DestinationPath $tmpdir
Copy-Item -Path "$tmpdir/cmake-$Version-win64-x64/" -Destination $test_cmake_dir -Recurse -Force
Remove-Item $tmpdir -Recurse
}
elseif ($PSVersionTable.OS.StartsWith("Linux")) {
# Install using the Linux self-extracting shell script executable
$installer_url = "$cmake_files_url/cmake-$Version-Linux-x86_64.sh"
$installer_file = "/tmp/cmake-$Version.sh"
Get-RemoteFile -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-$Version-Darwin-x86_64.tar.gz"
$installer_file = Join-Path $tmpdir "/cmake-$Version.tgz"
Get-RemoteFile -Url $installer_url -Path $installer_file
Push-Location /tmp
try {
& tar xf $installer_file
Copy-Item `
-Path "/tmp/cmake-$Version-Darwin-x86_64/CMake.app/Contents" `
-Destination $test_cmake_dir `
-Recurse
}
finally {
Pop-Location
}
}
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
$env:HasVs = if ($PSVersionTable.OS.StartsWith("Microsoft Windows")) { "true" } else { "false" }
Invoke-ChronicCommand "Executing VSCode test: $Description" $node $test_bin
}
function Invoke-SmokeTest($Name) {
$repo_dir = Split-Path $PSScriptRoot -Parent
if (! (Test-Path "$repo_dir/test/extension-tests/$Name")) {
throw "No such test with name '$Name'"
}
Invoke-VSCodeTest "CMake Tools: $Name" `
-TestsPath "$repo_dir/out/test/extension-tests/$Name" `
-Workspace "$repo_dir/test/extension-tests/$Name/project-folder"
}

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

@ -14,6 +14,8 @@ import * as util from './util';
const log = createLogger('cms-client');
const ENABLE_CMSERVER_PROTO_DEBUG = false;
const MESSAGE_WRAPPER_RE = /\[== "CMake Server" ==\[([^]*?)\]== "CMake Server" ==\]\s*([^]*)/;
export class StartupError extends global.Error {
@ -366,6 +368,7 @@ export interface ClientInit {
interface ClientInitPrivate extends ClientInit {
onHello: (m: HelloMessage) => Promise<void>;
onCrash: (retc: number, signal: string) => Promise<void>;
onPipeError(e: Error): Promise<void>;
tmpdir: string;
}
@ -418,7 +421,9 @@ export class CMakeServerClient {
throw new global.Error('Protocol error talking to CMake! Got this input: ' + input);
}
this._accInput = mat[2];
console.log(`Received message from cmake-server: ${mat[1]}`);
if (ENABLE_CMSERVER_PROTO_DEBUG) {
log.debug(`Received message from cmake-server: ${mat[1]}`);
}
const message: SomeMessage = JSON.parse(mat[1]);
this._onMessage(message);
}
@ -509,7 +514,9 @@ export class CMakeServerClient {
const cookie = cp.cookie = Math.random().toString();
const pr = new Promise((resolve, reject) => { this._promisesResolvers.set(cookie, {resolve, reject}); });
const msg = JSON.stringify(cp);
console.log(`Sending message to cmake-server: ${msg}`);
if (ENABLE_CMSERVER_PROTO_DEBUG) {
log.debug(`Sending message to cmake-server: ${msg}`);
}
this._pipe.write('\n[== "CMake Server" ==[\n');
this._pipe.write(msg);
this._pipe.write('\n]== "CMake Server" ==]\n');
@ -530,7 +537,9 @@ export class CMakeServerClient {
codemodel(params?: CodeModelParams): Promise<CodeModelContent> { return this.sendRequest('codemodel', params); }
private _onErrorData(data: Uint8Array) { log.error(`[cmake-server] ${data.toString()}`); }
private _onErrorData(data: Uint8Array) {
log.error(`Unexpected stderr/stdout data from CMake Server process: ${data.toString()}`);
}
public async shutdown() {
this._pipe.end();
@ -543,7 +552,7 @@ export class CMakeServerClient {
if (process.platform === 'win32') {
pipe_file = '\\\\?\\pipe\\' + pipe_file;
} else {
pipe_file = path.join(params.binaryDir, `.cmserver.${process.pid}`);
pipe_file = `/tmp/cmake-server-${Math.random()}`;
}
this._pipeFilePath = pipe_file;
const final_env = util.mergeEnvironment(process.env as proc.EnvironmentVariables, params.environment);
@ -555,12 +564,14 @@ export class CMakeServerClient {
child.stdout.on('data', this._onErrorData.bind(this));
child.stderr.on('data', this._onErrorData.bind(this));
setTimeout(() => {
const end_promise = new Promise<void>(resolve => {
const end_promise = new Promise<void>((resolve, reject) => {
const pipe = this._pipe = net.createConnection(pipe_file);
pipe.on('data', this._onMoreData.bind(this));
pipe.on('error', () => {
pipe.on('error', e => {
debugger;
pipe.end();
rollbar.takePromise('Pipe error from cmake-server', {pipe: pipe_file}, params.onPipeError(e));
reject(e);
});
pipe.on('end', () => {
pipe.end();
@ -601,6 +612,11 @@ export class CMakeServerClient {
reject(new StartupError(retc));
}
},
onPipeError: async e => {
if (!resolved) {
reject(e);
}
},
onHello: async (msg: HelloMessage) => {
// We've gotten the hello message. We need to commense handshake
try {

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

@ -122,12 +122,14 @@ export async function kitIfCompiler(bin: string, pr?: ProgressReporter): MaybeCo
pr.report({message: `Getting GCC version for ${bin}`});
const exec = await proc.execute(bin, ['-v']).result;
if (exec.retc != 0) {
log.debug('Bad GCC binary ("-v" returns non-zero)', bin);
return null;
}
const last_line = exec.stderr.trim().split('\n').reverse()[0];
const version_re = /^gcc version (.*?) .*/;
const version_match = version_re.exec(last_line);
if (version_match === null) {
log.debug('Bad GCC binary', bin, '-v output:', exec.stderr);
return null;
}
const version = version_match[1];
@ -159,12 +161,14 @@ export async function kitIfCompiler(bin: string, pr?: ProgressReporter): MaybeCo
pr.report({message: `Getting Clang version for ${bin}`});
const exec = await proc.execute(bin, ['-v']).result;
if (exec.retc != 0) {
log.debug('Bad Clang binary ("-v" returns non-zero)', bin);
return null;
}
const first_line = exec.stderr.split('\n')[0];
const version_re = /^clang version (.*?)[ -]/;
const version_re = /^(?:Apple LLVM|clang) version (.*?)[ -]/;
const version_match = version_re.exec(first_line);
if (version_match === null) {
log.debug('Bad Clang binary', bin, '-v output:', exec.stderr);
return null;
}
const version = version_match[1];

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

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

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

@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.0.0)
project(TestBuildProcess VERSION 0.1.0)
add_executable(TestBuildProcess main.cpp)
target_compile_features(TestBuildProcess PRIVATE cxx_std_11)
add_custom_command(
TARGET TestBuildProcess

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

@ -1,6 +1,5 @@
#include <iostream>
#include <string>
#include <cstdlib>
#ifndef _CMAKE_VERSION
#define _CMAKE_VERSION "0.0"
@ -24,9 +23,10 @@ std::string get_env_var(const std::string& key) {
int main(int, char**) {
std::cout << "{\n";
std::cout << " \"compiler\": \"" << getCompilerName() << "\",\n";
std::cout << " \"cookie\": \"passed-cookie\",\n";
std::cout << " \"cmake-version\": \"" << _CMAKE_VERSION << "\",\n";
std::cout << " \"configure-env\": \"" << get_env_var("_CONFIGURE_ENV") << "\",\n";
std::cout << " \"build-env\": \"" << get_env_var("_BUILD_ENV") << "\",\n";
std::cout << " \"env\": \"" << get_env_var("_ENV") << "\"\n";
std::cout << "}\n";
}
}

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

@ -14,12 +14,13 @@ 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 build_loc = 'build';
const exe_res = 'output.txt';
testEnv
= new DefaultEnvironment('test/extension-tests/successful-build/project-folder', build_loc, exe_res);
cmt = await CMakeTools.create(testEnv.vsContext);
// This test will use all on the same kit.
@ -48,7 +49,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 +58,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 +66,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 () => {

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

@ -16,12 +16,9 @@ suite('[Environment]', 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');
testEnv = new DefaultEnvironment('test/extension-tests/successful-build/project-folder', 'build', 'output.txt');
cmt = await CMakeTools.create(testEnv.vsContext);
// This test will use all on the same kit.

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

@ -17,12 +17,9 @@ suite('[Variable Substitution]', 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');
testEnv = new DefaultEnvironment('test/extension-tests/successful-build/project-folder', 'build', 'output.txt');
cmt = await CMakeTools.create(testEnv.vsContext);
// This test will use all on the same kit.

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

@ -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,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}"
)

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

@ -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,81 @@
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/vs-preferred-gen/project-folder',
'build',
'output.txt',
'^Visual ?Studio');
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');
});
});

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

@ -0,0 +1,4 @@
Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

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

@ -3,20 +3,12 @@
#include <string>
std::string generateConfigFilename(std::string inputFileName) {
static const int EXT_LENGTH = 4;
static const char* CONFIG_EXTENSION = ".cfg";
std::string configFilePath = inputFileName;
if (configFilePath.length() > EXT_LENGTH) {
int extPosition = configFilePath.length() - EXT_LENGTH;
std::string fileEnd = configFilePath.substr(extPosition, EXT_LENGTH);
if (fileEnd[0] == '.') {
configFilePath = configFilePath.replace(extPosition, 4, CONFIG_EXTENSION);
} else {
configFilePath.append(CONFIG_EXTENSION);
}
}
return configFilePath;
#ifdef _WIN32
const std::string nameNoExt = (inputFileName.rfind(".exe") == inputFileName.size() - 4) ? inputFileName.substr(0, inputFileName.length() - 4) : inputFileName;
#else
const std::string nameNoExt = inputFileName;
#endif
return nameNoExt + ".cfg";
}
int main(int argc, char** argv) {

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

@ -16,13 +16,17 @@ export class DefaultEnvironment {
public vsContext: FakeContextDefinition = new FakeContextDefinition();
setting: CMakeToolsSettingFile = new CMakeToolsSettingFile(this.sandbox);
public constructor(projectRoot: string,
buildLocation: string = 'build',
executableResult: string = 'output.txt',
defaultkitRegExp = '^VisualStudio') {
public constructor(projectRoot: string, buildLocation: string, executableResult: string, defaultkitRegExp?: string) {
this.projectFolder = new ProjectRootHelper(projectRoot, buildLocation);
this.result = new TestProgramResult(this.projectFolder.buildDirectory.location, executableResult);
if (!defaultkitRegExp) {
if (process.platform == 'win32') {
defaultkitRegExp = '^Visual ?Studio';
} else {
defaultkitRegExp = '.';
}
}
this.kitSelection = new SelectKitPickerHandle(defaultkitRegExp);
this.setupShowQuickPickerStub([this.kitSelection]);

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

@ -42,7 +42,7 @@ suite('Kits scan test', async () => {
test('Detect system kits never throws',
async () => {
// Don't care about the result, just check that we don't throw during the test
await expect(kit.scanForKits()).to.eventually.not.be.rejected;
await kit.scanForKits();
})
// Compiler detection can run a little slow
.timeout(12000);
@ -65,6 +65,15 @@ suite('Kits scan test', async () => {
expect(compkit!.name).to.eq('Clang 0.25');
});
test('Detect an Apple-Clang compiler file', async () => {
const compiler = path.join(fakebin, 'clang-8.1.0');
const compkit = await kit.kitIfCompiler(compiler);
expect(compkit).to.not.be.null;
expect(compkit!.compilers).has.property('C').eq(compiler);
expect(compkit!.compilers).to.not.have.property('CXX');
expect(compkit!.name).to.eq('Clang 8.1.0');
});
test('Detect non-compiler program', async () => {
const program = path.join(fakebin, 'gcc-666');
const nil = await kit.kitIfCompiler(program);
@ -90,18 +99,18 @@ suite('Kits scan test', async () => {
await fs.rmdir(path_with_compilername);
}
});
test('Scan folder with compiler name', async () => {
test('Scan directory with compiler name', async () => {
await fs.mkdir(path_with_compilername);
// Scan the directory with fake compilers in it
const kits = await kit.scanDirForCompilerKits(fakebin);
expect(kits.length).to.eq(2);
expect(kits.length).to.eq(3);
});
test('Scan file with compiler name', async () => {
await fs.writeFile(path_with_compilername, '');
// Scan the directory with fake compilers in it
const kits = await kit.scanDirForCompilerKits(fakebin);
expect(kits.length).to.eq(2);
expect(kits.length).to.eq(3);
});
});
@ -185,7 +194,7 @@ suite('Kits scan test', async () => {
const kitFile = await readValidKitFile(path_rescan_kit);
const nonVSKits = kitFile.filter(item => item.visualStudio == null);
expect(nonVSKits.length).to.be.eq(2);
expect(nonVSKits.length).to.be.eq(3);
}).timeout(10000);
test('check check combination of scan and old kits', async () => {