Skip to content

Commit 8efc4e5

Browse files
authored
Add functionality to enable use with the VS Code CodeQL extension (#20)
* Add local version pinning This enables pinning a CodeQL version per working directory. * Add install stub command This installs a stub allowing the GH CodeQL extension to be used by the VS Code extension. * Add version override through environment variable The environment variable `GH_CODEQL_VERSION` can be used to override the global and local version specification. This is needed when we want to override the CodeQL version used by the VS Code extension, because the working directory used by the extension is `/` so we can't find any local version specification part of the project using CodeQL. With this override we can alias `code` to check for `.codeql-version` in PWD or the path passed as an argument and set `GH_CODEQL_VERSION`. * Update README with new commands * Add description of local version pinning * Add description of the `install-stub` command. * Address incorrect indentation * Add test for `install-stub` command * Ensure the latest version is avaible for the test * Add test for version override * Restore the channel after the nightly version test * Address spelling mistake in comment * Remove superfluous download step The selected version will be downloaded if not available. * Address spelling mistake in comment * Update install-stub command's descriptive comment Explain what the command does. * Address `jq` parser error The version override causes a CodeQL CLI download that outputs cURL outpuut which confuses the `jq` parser. By running the command twice we remediate the issue. * Add test for local pinned version modification This test validates if we properly handle a local pinned version modification without using the `set-local-version` command. * Address pinning persistence influencing other tests After each test using local pinning we unpin the version. * Update error message when installing stub When a directory doesn't exists, the user is asked to provide a different directory to install a stub. * Add permission check to install-stub command Check if we can write to the provided/default directory and return an error message if we can't. * Disable per directory pinning by default The command 'set-local-version' will show a warning when per directory pinning is disabled (the default) and explicitly asks the user to enable it. * Update how we support local version - Add explicit commands to enable/disable local version support. - Show a warning when a local version is specified, but local version support is disabled. - Show a warning when enabling local version support. - Show an error when a local version is set while local version support is disabled. * Address spelling mistake in test name * Improve error message 'local-version' command
1 parent 3b0cb32 commit 8efc4e5

File tree

3 files changed

+245
-4
lines changed

3 files changed

+245
-4
lines changed

.github/workflows/pr-checks.yml

Lines changed: 131 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
# Note we need to run a command before trying to parse the output below, or the
3333
# messages from the download will end up in the JSON that jq tries to parse
3434
gh codeql version
35-
35+
3636
INSTALLED=`gh codeql version --format json | jq -r '.version'`
3737
if [[ "v$INSTALLED" != $LATEST ]]; then
3838
echo "::error::Expected latest version of $LATEST to be installed, but found v$INSTALLED"
@@ -84,6 +84,103 @@ jobs:
8484
exit 1
8585
fi
8686
87+
- name: Check local version pinning
88+
shell: bash
89+
run: |
90+
# Enable local version support
91+
gh codeql local-version on
92+
gh codeql set-version latest
93+
# Get the latest installed version
94+
LATEST=`gh codeql version --format json | jq -r '.version'`
95+
# Set a local version
96+
gh codeql set-local-version 2.5.9
97+
VERSION=`gh codeql version --format json | jq -r '.version'`
98+
if [[ $VERSION != "2.5.9" ]]; then
99+
echo "::error::Expected version 2.5.9 but got $VERSION"
100+
exit 1
101+
fi
102+
103+
# Create a temp directory so we can change the working directory
104+
mkdir temp
105+
pushd temp
106+
OTHER_VERSION=`gh codeql version --format json | jq -r '.version'`
107+
108+
if [[ $OTHER_VERSION != $LATEST ]]; then
109+
echo "::error::Expected version $LATEST but got $OTHER_VERSION"
110+
exit 1
111+
fi
112+
popd
113+
rmdir temp
114+
gh codeql unset-local-version
115+
# Disable local version support
116+
gh codeql local-version off
117+
118+
- name: Check local version unpinning
119+
shell: bash
120+
run: |
121+
# Enable local version support
122+
gh codeql local-version on
123+
gh codeql set-version latest
124+
# Get the latest installed version
125+
LATEST=`gh codeql version --format json | jq -r '.version'`
126+
# Set a local version
127+
gh codeql set-local-version 2.5.9
128+
# Unset the local version
129+
gh codeql unset-local-version
130+
if [[ $VERSION == "2.5.9" ]]; then
131+
echo "::error::Expected $LATEST version but got 2.5.9"
132+
exit 1
133+
fi
134+
# Disable local version support
135+
gh codeql local-version off
136+
137+
- name: Check local version pinning modification
138+
shell: bash
139+
run: |
140+
# Enable local version support
141+
gh codeql local-version on
142+
gh codeql set-version latest
143+
# Get the latest installed version
144+
LATEST=`gh codeql version --format json | jq -r '.version'`
145+
# Set a local version
146+
gh codeql set-local-version 2.5.9
147+
VERSION=`gh codeql version --format json | jq -r '.version'`
148+
if [[ $VERSION != "2.5.9" ]]; then
149+
echo "::error::Expected version 2.5.9 but got $VERSION"
150+
exit 1
151+
fi
152+
153+
# Modify the pinned version without using the CLI
154+
echo v2.7.6 > .codeql-version
155+
# We run the command twice to prevent cURL output from causing a `jq` parser error.
156+
gh codeql version
157+
VERSION=`gh codeql version --format json | jq -r '.version'`
158+
if [[ $VERSION != "2.7.6" ]]; then
159+
echo "::error::Expected version 2.7.6 but got $VERSION"
160+
exit 1
161+
fi
162+
gh codeql unset-local-version
163+
# Disable local version support
164+
gh codeql local-version off
165+
166+
- name: Check local version pinning is disabled by default
167+
shell: bash
168+
run: |
169+
gh codeql set-version latest
170+
# Get the latest installed version
171+
LATEST=`gh codeql version --format json | jq -r '.version'`
172+
173+
# Modify the pinned version without using the CLI
174+
echo v2.7.6 > .codeql-version
175+
# We run the command twice to prevent cURL output from causing a `jq` parser error.
176+
gh codeql version
177+
VERSION=`gh codeql version --format json | jq -r '.version'`
178+
if [[ $VERSION = "2.7.6" ]]; then
179+
echo "::error::Expected version $LATEST but got $VERSION"
180+
exit 1
181+
fi
182+
rm .codeql-version
183+
87184
- name: Check getting nightly version
88185
shell: bash
89186
run: |
@@ -93,4 +190,36 @@ jobs:
93190
if [[ $VERSION != "2.6.0+202108311306" ]]; then
94191
echo "::error::Expected version 2.6.0+202108311306 but got $VERSION"
95192
exit 1
96-
fi
193+
fi
194+
gh codeql set-channel release
195+
196+
- name: Check version override
197+
shell: bash
198+
run: |
199+
gh codeql set-version latest
200+
# We run the command with a version override twice such that first run will download the CodeQL CLI
201+
# and the cURL output doesn't confuse the `jq` parser in the second run.
202+
# This implicit download is to test that we properly support the implicit download of a requested version if it is not present.
203+
GH_CODEQL_VERSION=v2.7.6 gh codeql version
204+
VERSION=`GH_CODEQL_VERSION=v2.7.6 gh codeql version --format json | jq -r '.version'`
205+
206+
if [[ $VERSION != "2.7.6" ]]; then
207+
echo "::error::Expected version 2.7.6 but got $VERSION"
208+
exit 1
209+
fi
210+
211+
- name: Check use of stub
212+
shell: bash
213+
run: |
214+
gh codeql set-version latest
215+
VERSION=`gh codeql version --format json | jq -r '.version'`
216+
217+
mkdir temp
218+
gh codeql install-stub temp
219+
OTHER_VERSION=`temp/codeql version --format json | jq -r '.version'`
220+
if [[ $OTHER_VERSION != $VERSION ]]; then
221+
echo "::error::Expected version $VERSION but got $OTHER_VERSION"
222+
exit 1
223+
fi
224+
225+
rm -r temp

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,15 @@ GitHub command-line wrapper for the CodeQL CLI.
1515
Usage:
1616
gh codeql set-channel [release|nightly] # default: release
1717
gh codeql set-version [version] # default: latest
18+
gh codeql set-local-version [version] # set the version for the current working directory, default: latest
19+
gh codeql unset-local-version # switch back to the global version
1820
gh codeql list-versions # list all available versions for current channel
1921
gh codeql list-installed # list installed versions for current channel
2022
gh codeql cleanup <version> # delete a specific downloaded version
2123
gh codeql cleanup-all # delete all installed versions for all channels
2224
gh codeql download [version] # download a specific version (default: latest)
2325
gh codeql debug [on|off] # enable/disable debug output for gh extension
26+
gh codeql install-stub [dir] # default: /usr/local/bin/
2427
gh codeql <anything else> # pass arguments to CodeQL CLI
2528

2629
Current channel: release.
@@ -39,12 +42,16 @@ You can list the installed versions from the current channel with `gh codeql lis
3942

4043
### Versions
4144

42-
The `gh codeql` command always works relative to a pinned version on the current channel. You can manually specify the pinned version using `gh codeql set-version`.
45+
The `gh codeql` command always works relative to a pinned version on the current channel. You can manually specify the pinned version using `gh codeql set-version`. To pin a version to a working directory you can use the command `gh codeql set-local-version` and `gh codeql` will always use that version when running in that working directory. To remove a pin from a working directory run `gh codeql unset-local-version` in that working directory.
4346

4447
You can download additional versions without pinning them (perhaps to prepare for local comparisons) using `gh codeql download`.
4548

4649
To upgrade, run `gh codeql set-version latest`, which will pin you to the current latest version.
4750

51+
### CodeQL stub
52+
53+
If you want to use the GitHub CLI managed CodeQL version directly in a terminal or use it with the Visual Studio Code CodeQL extension then you can install a stub using the command `gh codeql install-stub` that will install a Bash script called `codeql` that invokes the GitHub CLI. The default install directory is `/usr/local/bin/`, but you can change this by passing an existing directory.
54+
4855
## Development
4956

5057
This extension is newly released and under active development. Contributions are very welcome, for more information about how you can contribute, please check our [CONTRIBUTING.md](CONTRIBUTING.md) file. For a list of outstanding issues, please take a look at [our backlog](https://github.com/github/gh-codeql/issues). If you encounter a problem that does not already have an open issue associated with it, please open one there.

gh-codeql

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,58 @@ error() {
1111
exit 1
1212
}
1313

14+
warning() {
15+
echo "WARNING: $*" 1>&2
16+
}
17+
1418
rootdir="$(dirname "$0")"
1519
channel="$(gh config get extensions.codeql.channel 2> /dev/null)" || : # Suppress an error and return empty if the field doesn't exist
1620
version="$(gh config get extensions.codeql.version 2> /dev/null)" || : # Suppress an error and return empty if the field doesn't exist
1721

22+
# Handle local-version command first to prevent local version warning when enabling local version support if a local version is specified..
23+
if [ "$1" = "local-version" ] ; then
24+
if [ "$2" = "on" ] ; then
25+
warning "Local version support is disabled by default to remove the opportunity from untrusted git repositories to
26+
abuse older CodeQL CLIs. To disable local version support again run the command 'gh codeql local-version off'."
27+
gh config set extensions.codeql.local-version true 2> /dev/null # Ignore a warning about unrecognized custom keys
28+
elif [ "$2" = "off" ] ; then
29+
gh config set extensions.codeql.local-version false 2> /dev/null # Ignore a warning about unrecognized custom keys
30+
else
31+
error "Invalid local-version command: '$2'. Supported values are 'on' or 'off'."
32+
fi
33+
exit 0
34+
fi
35+
36+
local_version="$(gh config get extensions.codeql.local-version 2> /dev/null)" || : # Suppress an error and return empty if the field doesn't exist
37+
38+
if [ -e .codeql-version ]; then
39+
if [ "$local_version" = "true" ]; then
40+
version=$(<.codeql-version)
41+
else
42+
warning "Ignoring local version because local version support is off. Call the command 'gh codeql local-version on' to enable local version support. "
43+
fi
44+
fi
45+
46+
# The environment variable GH_CODEQL_VERSION overrides all specified versions.
47+
version=${GH_CODEQL_VERSION:-$version}
48+
1849
if [ -z "$1" ]; then
1950
cat <<EOF
2051
GitHub command-line wrapper for the CodeQL CLI.
2152
2253
Usage:
2354
gh codeql set-channel [release|nightly] # default: release
2455
gh codeql set-version [version] # default: latest
56+
gh codeql local-version [on|off] # enable/disable local version support
57+
gh codeql set-local-version [version] # set the version for the current working directory, default: latest
58+
gh codeql unset-local-version # switch back to the global version
2559
gh codeql list-versions # list all available versions for current channel
2660
gh codeql list-installed # list installed versions for current channel
2761
gh codeql cleanup <version> # delete a specific downloaded version
2862
gh codeql cleanup-all # delete all installed versions for all channels
2963
gh codeql download [version] # download a specific version (default: latest)
3064
gh codeql debug [on|off] # enable/disable debug output for gh extension
65+
gh codeql install-stub [dir] # install an executable script named 'codeql' that invokes 'gh codeql' with the passed arguments (default: /usr/local/bin/)
3166
gh codeql <anything else> # pass arguments to CodeQL CLI
3267
3368
Current channel: ${channel:-not specified}.
@@ -131,7 +166,7 @@ function download() {
131166
rm -rf "$tempdir"
132167
}
133168

134-
function set_version() {
169+
function validate_version() {
135170
local version="$1"
136171
if [ -z "$version" ]; then
137172
error "Version must be specified. Use 'latest' to automatically determine the latest version."
@@ -156,10 +191,49 @@ function set_version() {
156191
error "Unknown version: '$1'."
157192
fi
158193
fi
194+
echo "$version"
195+
}
196+
197+
function set_version() {
198+
local version=$(validate_version "$1")
199+
if [ -z "$version" ]; then
200+
exit 1
201+
fi
159202
download "$version"
160203
gh config set extensions.codeql.version "$version" 2> /dev/null # Ignore a warning about unrecognized custom keys
161204
}
162205

206+
function set_local_version() {
207+
local version=$(validate_version "$1")
208+
download "$version"
209+
echo "$version" > .codeql-version
210+
}
211+
212+
function install_stub() {
213+
local bindir="$1"
214+
if [ -z "$bindir" ]; then
215+
bindir="/usr/local/bin"
216+
fi
217+
218+
if [ ! -e "$bindir" ]; then
219+
error "The directory $bindir doesn't exist, please provide a different directory like 'gh codeql install-stub [dir]' to install a stub."
220+
fi
221+
222+
if [ -w "$bindir" ]; then
223+
224+
cat << "_codeql_stub" > "$bindir/codeql"
225+
#!/usr/bin/env bash
226+
227+
set -e
228+
exec -a codeql gh codeql "$@"
229+
_codeql_stub
230+
231+
chmod +x "$bindir/codeql"
232+
else
233+
error "Missing write permission on $bindir. Please provide a directory with write permissions to install a stub."
234+
fi
235+
}
236+
163237
# Handle the download command.
164238
if [ "$1" = "download" ]; then
165239
download "$2"
@@ -173,6 +247,31 @@ if [ "$1" = "set-version" ]; then
173247
exec "$rootdir/dist/$channel/$version/codeql" version
174248
fi
175249

250+
# Handle the set-local-version command
251+
if [ "$1" = "set-local-version" ]; then
252+
if [ "$local_version" = "true" ]; then
253+
set_local_version "$2"
254+
version="$(<.codeql-version)" || : # Supress an error and return empty if the file doesn't exist
255+
exec "$rootdir/dist/$channel/$version/codeql" version
256+
else
257+
error "$(cat << _message
258+
Local version support is disabled by default to remove the opportunity from untrusted git repositories to
259+
abuse older CodeQL CLIs. Enable local version support with the command 'gh codeql local-version on'.
260+
_message
261+
)"
262+
fi
263+
fi
264+
265+
# Handle the unset-local-version command
266+
if [ "$1" = "unset-local-version" ]; then
267+
if [ -e .codeql-version ]; then
268+
rm -f .codeql-version
269+
else
270+
warning "No local version specified."
271+
fi
272+
exit 0
273+
fi
274+
176275
# Handle the list-installed command.
177276
if [ "$1" = "list-installed" ]; then
178277
( cd "$rootdir/dist/$channel" ; find . -mindepth 1 -maxdepth 1 -type d | cut -c3- ; )
@@ -196,6 +295,12 @@ if [ "$1" = "cleanup-all" ]; then
196295
exit 0
197296
fi
198297

298+
# Handle the install-stub command
299+
if [ "$1" = "install-stub" ]; then
300+
install_stub "$2"
301+
exit 0
302+
fi
303+
199304
if [ -z "$version" ]; then
200305
set_version latest
201306
version="$(gh config get extensions.codeql.version 2> /dev/null)" || : # Suppress an error and return empty if the field doesn't exist

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy