Skip to content

Use upstream server #4414

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 29 commits into from
Nov 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
3c10163
Flesh out fixes to align with upstream.
GirlBossRush Oct 28, 2021
0e7eb7e
Update route handlers to better reflect fallback behavior.
GirlBossRush Oct 29, 2021
ad787bb
Bump vendor.
GirlBossRush Oct 29, 2021
19c9c23
Touch up build, tests.
GirlBossRush Oct 29, 2021
062ce32
bump vscode.
GirlBossRush Nov 4, 2021
2481711
Add platform to vscode-reh-web task
code-asher Nov 4, 2021
dde9a08
Fix issue where workspace args are not parsed.
GirlBossRush Nov 4, 2021
26733fd
Update CLI test.
GirlBossRush Nov 4, 2021
059893f
Update CLI tests.
GirlBossRush Nov 4, 2021
9945428
Fix issues surrounding opening files within code-server's terminal.
GirlBossRush Nov 4, 2021
93adec7
Bump vendor.
GirlBossRush Nov 4, 2021
28e0d78
Update VS Code
code-asher Nov 5, 2021
4cf13f4
Merge remote-tracking branch 'origin/main' into upstream-server-fixes
code-asher Nov 5, 2021
76e6ccc
Readd parent wrapper for hot reload.
GirlBossRush Nov 5, 2021
efada23
Allow more errors.
GirlBossRush Nov 5, 2021
1f7e8a1
Bump vscode.
GirlBossRush Nov 5, 2021
914aad2
Fix issues surrounding Coder link.
GirlBossRush Nov 5, 2021
a413abf
Add dir creation and fix cli
code-asher Nov 5, 2021
55d878e
Remove hardcoded VSCODE_DEV=1
code-asher Nov 8, 2021
d03c9f5
Fix mismatching commit between client and server
code-asher Nov 8, 2021
8244463
Mostly restore command-line parity
code-asher Nov 8, 2021
d5ed30f
Fix static endpoint not emitting 404s
code-asher Nov 8, 2021
30b9923
Update VS Code
code-asher Nov 8, 2021
a281ccd
Import missing logError
code-asher Nov 9, 2021
7d48b82
Fix 403 errors
code-asher Nov 9, 2021
fc94ac9
Add code-server version to about dialog
code-asher Nov 9, 2021
89cc5a9
Use user settings to disable welcome page
code-asher Nov 10, 2021
e022788
Update VS Code cache step with new build directories
code-asher Nov 10, 2021
c8f2b12
Merge branch 'main' into upstream-server-fixes
code-asher Nov 10, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,9 @@ jobs:
path: |
vendor/modules/code-oss-dev/.build
vendor/modules/code-oss-dev/out-build
vendor/modules/code-oss-dev/out-vscode-server
vendor/modules/code-oss-dev/out-vscode-server-min
key: vscode-server-build-${{ steps.vscode-rev.outputs.rev }}
vendor/modules/code-oss-dev/out-vscode-reh-web
vendor/modules/code-oss-dev/out-vscode-reh-web-min
key: vscode-reh-build-${{ steps.vscode-rev.outputs.rev }}

- name: Build vscode
if: steps.cache-vscode.outputs.cache-hit != 'true'
Expand Down
4 changes: 2 additions & 2 deletions ci/build/build-release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ EOF
bundle_vscode() {
mkdir -p "$VSCODE_OUT_PATH"
rsync "$VSCODE_SRC_PATH/yarn.lock" "$VSCODE_OUT_PATH"
rsync "$VSCODE_SRC_PATH/out-vscode-server${MINIFY:+-min}/" "$VSCODE_OUT_PATH/out"
rsync "$VSCODE_SRC_PATH/out-vscode-reh-web${MINIFY:+-min}/" "$VSCODE_OUT_PATH/out"

rsync "$VSCODE_SRC_PATH/.build/extensions/" "$VSCODE_OUT_PATH/extensions"
if [ "$KEEP_MODULES" = 0 ]; then
Expand All @@ -88,7 +88,7 @@ bundle_vscode() {
cat << EOF
{
"enableTelemetry": true,
"commit": "$(git rev-parse HEAD)",
"commit": "$(cd "$VSCODE_SRC_PATH" && git rev-parse HEAD)",
"quality": "stable",
"date": $(jq -n 'now | todate')
}
Expand Down
5 changes: 2 additions & 3 deletions ci/build/build-vscode.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ main() {

cd vendor/modules/code-oss-dev

# extensions-ci compiles extensions and includes their media.
# compile-web compiles web extensions. TODO: Unsure if used.
yarn gulp extensions-ci compile-web "vscode-server${MINIFY:+-min}"
# Any platform works since we have our own packaging step (for now).
yarn gulp "vscode-reh-web-linux-x64${MINIFY:+-min}"
}

main "$@"
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"lint": "./ci/dev/lint.sh",
"test": "echo 'Run yarn test:unit or yarn test:e2e' && exit 1",
"ci": "./ci/dev/ci.sh",
"watch": "VSCODE_IPC_HOOK_CLI= NODE_OPTIONS='--max_old_space_size=32384 --trace-warnings' ts-node ./ci/dev/watch.ts",
"watch": "VSCODE_DEV=1 VSCODE_IPC_HOOK_CLI= NODE_OPTIONS='--max_old_space_size=32384 --trace-warnings' ts-node ./ci/dev/watch.ts",
"icons": "./ci/dev/gen_icons.sh",
"coverage": "codecov"
},
Expand Down
147 changes: 97 additions & 50 deletions src/node/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@ import { promises as fs } from "fs"
import yaml from "js-yaml"
import * as os from "os"
import * as path from "path"
import { canConnect, generateCertificate, generatePassword, humanPath, paths, isNodeJSErrnoException } from "./util"
import {
canConnect,
generateCertificate,
generatePassword,
humanPath,
paths,
isNodeJSErrnoException,
isFile,
} from "./util"

const DEFAULT_SOCKET_PATH = path.join(os.tmpdir(), "vscode-ipc")

Expand Down Expand Up @@ -31,53 +39,53 @@ export enum LogLevel {

export class OptionalString extends Optional<string> {}

export interface Args
extends Pick<
CodeServerLib.NativeParsedArgs,
| "_"
| "user-data-dir"
| "enable-proposed-api"
| "extensions-dir"
| "builtin-extensions-dir"
| "extra-extensions-dir"
| "extra-builtin-extensions-dir"
| "ignore-last-opened"
| "locale"
| "log"
| "verbose"
| "install-source"
| "list-extensions"
| "install-extension"
| "uninstall-extension"
| "locate-extension"
// | "telemetry"
> {
/**
* Arguments that the user explicitly provided on the command line. All
* arguments must be optional.
*
* For arguments with defaults see DefaultedArgs.
*/
export interface UserProvidedArgs {
config?: string
auth?: AuthType
password?: string
"hashed-password"?: string
cert?: OptionalString
"cert-host"?: string
"cert-key"?: string
"disable-telemetry"?: boolean
"disable-update-check"?: boolean
enable?: string[]
help?: boolean
host?: string
port?: number
json?: boolean
log?: LogLevel
open?: boolean
port?: number
"bind-addr"?: string
socket?: string
version?: boolean
force?: boolean
"show-versions"?: boolean
"proxy-domain"?: string[]
"reuse-window"?: boolean
"new-window"?: boolean

"ignore-last-opened"?: boolean
link?: OptionalString
verbose?: boolean
/* Positional arguments. */
_?: string[]

// VS Code flags.
"disable-telemetry"?: boolean
force?: boolean
"user-data-dir"?: string
"enable-proposed-api"?: string[]
"extensions-dir"?: string
"builtin-extensions-dir"?: string
"install-extension"?: string[]
"uninstall-extension"?: string[]
"list-extensions"?: boolean
"locate-extension"?: string[]
"show-versions"?: boolean
category?: string
}

interface Option<T> {
Expand Down Expand Up @@ -121,7 +129,7 @@ type Options<T> = {
[P in keyof T]: Option<OptionType<T[P]>>
}

const options: Options<Required<Args>> = {
const options: Options<Required<UserProvidedArgs>> = {
auth: { type: AuthType, description: "The type of authentication to use." },
password: {
type: "string",
Expand Down Expand Up @@ -178,12 +186,10 @@ const options: Options<Required<Args>> = {
"user-data-dir": { type: "string", path: true, description: "Path to the user data directory." },
"extensions-dir": { type: "string", path: true, description: "Path to the extensions directory." },
"builtin-extensions-dir": { type: "string", path: true },
"extra-extensions-dir": { type: "string[]", path: true },
"extra-builtin-extensions-dir": { type: "string[]", path: true },
"list-extensions": { type: "boolean", description: "List installed VS Code extensions." },
force: { type: "boolean", description: "Avoid prompts when installing VS Code extensions." },
"install-source": { type: "string" },
"locate-extension": { type: "string[]" },
category: { type: "string" },
"install-extension": {
type: "string[]",
description:
Expand Down Expand Up @@ -214,7 +220,6 @@ const options: Options<Required<Args>> = {
description: "Force to open a file or folder in an already opened window.",
},

locale: { type: "string" },
log: { type: LogLevel },
verbose: { type: "boolean", short: "vvv", description: "Enable verbose logging." },

Expand Down Expand Up @@ -271,12 +276,16 @@ export function splitOnFirstEquals(str: string): string[] {
return split
}

/**
* Parse arguments into UserProvidedArgs. This should not go beyond checking
* that arguments are valid types and have values when required.
*/
export const parse = (
argv: string[],
opts?: {
configFile?: string
},
): Args => {
): UserProvidedArgs => {
const error = (msg: string): Error => {
if (opts?.configFile) {
msg = `error reading ${opts.configFile}: ${msg}`
Expand All @@ -285,7 +294,7 @@ export const parse = (
return new Error(msg)
}

const args: Args = { _: [] }
const args: UserProvidedArgs = {}
let ended = false

for (let i = 0; i < argv.length; ++i) {
Expand All @@ -299,17 +308,17 @@ export const parse = (

// Options start with a dash and require a value if non-boolean.
if (!ended && arg.startsWith("-")) {
let key: keyof Args | undefined
let key: keyof UserProvidedArgs | undefined
let value: string | undefined
if (arg.startsWith("--")) {
const split = splitOnFirstEquals(arg.replace(/^--/, ""))
key = split[0] as keyof Args
key = split[0] as keyof UserProvidedArgs
value = split[1]
} else {
const short = arg.replace(/^-/, "")
const pair = Object.entries(options).find(([, v]) => v.short === short)
if (pair) {
key = pair[0] as keyof Args
key = pair[0] as keyof UserProvidedArgs
}
}

Expand Down Expand Up @@ -384,6 +393,10 @@ export const parse = (
}

// Everything else goes into _.
if (typeof args._ === "undefined") {
args._ = []
}

args._.push(arg)
}

Expand All @@ -397,6 +410,11 @@ export const parse = (
return args
}

/**
* User-provided arguments with defaults. The distinction between user-provided
* args and defaulted args exists so we can tell the difference between end
* values and what the user actually provided on the command line.
*/
export interface DefaultedArgs extends ConfigArgs {
auth: AuthType
cert?: {
Expand All @@ -410,14 +428,18 @@ export interface DefaultedArgs extends ConfigArgs {
usingEnvHashedPassword: boolean
"extensions-dir": string
"user-data-dir": string
/* Positional arguments. */
_: []
folder: string
workspace: string
}

/**
* Take CLI and config arguments (optional) and return a single set of arguments
* with the defaults set. Arguments from the CLI are prioritized over config
* arguments.
*/
export async function setDefaults(cliArgs: Args, configArgs?: ConfigArgs): Promise<DefaultedArgs> {
export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: ConfigArgs): Promise<DefaultedArgs> {
const args = Object.assign({}, configArgs || {}, cliArgs)

if (!args["user-data-dir"]) {
Expand Down Expand Up @@ -472,7 +494,7 @@ export async function setDefaults(cliArgs: Args, configArgs?: ConfigArgs): Promi
args.auth = AuthType.Password
}

const addr = bindAddrFromAllSources(configArgs || { _: [] }, cliArgs)
const addr = bindAddrFromAllSources(configArgs || {}, cliArgs)
args.host = addr.host
args.port = addr.port

Expand Down Expand Up @@ -513,8 +535,29 @@ export async function setDefaults(cliArgs: Args, configArgs?: ConfigArgs): Promi
const proxyDomains = new Set((args["proxy-domain"] || []).map((d) => d.replace(/^\*\./, "")))
args["proxy-domain"] = Array.from(proxyDomains)

if (typeof args._ === "undefined") {
args._ = []
}

let workspace = ""
let folder = ""
if (args._.length) {
const lastEntry = path.resolve(process.cwd(), args._[args._.length - 1])
const entryIsFile = await isFile(lastEntry)

if (entryIsFile && path.extname(lastEntry) === ".code-workspace") {
workspace = lastEntry
args._.pop()
} else if (!entryIsFile) {
folder = lastEntry
args._.pop()
}
}

return {
...args,
workspace,
folder,
usingEnvPassword,
usingEnvHashedPassword,
} as DefaultedArgs // TODO: Technically no guarantee this is fulfilled.
Expand All @@ -539,7 +582,7 @@ cert: false
`
}

interface ConfigArgs extends Args {
interface ConfigArgs extends UserProvidedArgs {
config: string
}

Expand Down Expand Up @@ -581,7 +624,7 @@ export async function readConfigFile(configPath?: string): Promise<ConfigArgs> {
*/
export function parseConfigFile(configFile: string, configPath: string): ConfigArgs {
if (!configFile) {
return { _: [], config: configPath }
return { config: configPath }
}

const config = yaml.load(configFile, {
Expand Down Expand Up @@ -628,7 +671,7 @@ interface Addr {
* This function creates the bind address
* using the CLI args.
*/
export function bindAddrFromArgs(addr: Addr, args: Args): Addr {
export function bindAddrFromArgs(addr: Addr, args: UserProvidedArgs): Addr {
addr = { ...addr }
if (args["bind-addr"]) {
addr = parseBindAddr(args["bind-addr"])
Expand All @@ -646,7 +689,7 @@ export function bindAddrFromArgs(addr: Addr, args: Args): Addr {
return addr
}

function bindAddrFromAllSources(...argsConfig: Args[]): Addr {
function bindAddrFromAllSources(...argsConfig: UserProvidedArgs[]): Addr {
let addr: Addr = {
host: "localhost",
port: 8080,
Expand Down Expand Up @@ -683,30 +726,34 @@ export async function readSocketPath(path: string): Promise<string | undefined>
/**
* Determine if it looks like the user is trying to open a file or folder in an
* existing instance. The arguments here should be the arguments the user
* explicitly passed on the command line, not defaults or the configuration.
* explicitly passed on the command line, *NOT DEFAULTS* or the configuration.
*/
export const shouldOpenInExistingInstance = async (args: Args): Promise<string | undefined> => {
export const shouldOpenInExistingInstance = async (args: UserProvidedArgs): Promise<string | undefined> => {
// Always use the existing instance if we're running from VS Code's terminal.
if (process.env.VSCODE_IPC_HOOK_CLI) {
logger.debug("Found VSCODE_IPC_HOOK_CLI")
return process.env.VSCODE_IPC_HOOK_CLI
}

// If these flags are set then assume the user is trying to open in an
// existing instance since these flags have no effect otherwise.
const openInFlagCount = ["reuse-window", "new-window"].reduce((prev, cur) => {
return args[cur as keyof Args] ? prev + 1 : prev
return args[cur as keyof UserProvidedArgs] ? prev + 1 : prev
}, 0)
if (openInFlagCount > 0) {
logger.debug("Found --reuse-window or --new-window")
return readSocketPath(DEFAULT_SOCKET_PATH)
}

// It's possible the user is trying to spawn another instance of code-server.
// Check if any unrelated flags are set (check against one because `_` always
// exists), that a file or directory was passed, and that the socket is
// active.
if (Object.keys(args).length === 1 && args._.length > 0) {
// 1. Check if any unrelated flags are set (this should only run when
// code-server is invoked exactly like this: `code-server my-file`).
// 2. That a file or directory was passed.
// 3. That the socket is active.
if (Object.keys(args).length === 1 && typeof args._ !== "undefined" && args._.length > 0) {
const socketPath = await readSocketPath(DEFAULT_SOCKET_PATH)
if (socketPath && (await canConnect(socketPath))) {
logger.debug("Found existing code-server socket")
return socketPath
}
}
Expand Down
1 change: 1 addition & 0 deletions src/node/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export function getPackageJson(relativePath: string): JSONSchemaForNPMPackageJso

const pkg = getPackageJson("../../package.json")

export const pkgName = pkg.name || "code-server"
export const version = pkg.version || "development"
export const commit = pkg.commit || "development"
export const rootPath = path.resolve(__dirname, "../..")
Expand Down
Loading