Skip to content

Commit

Permalink
Featureful (coder#31)
Browse files Browse the repository at this point in the history
* Fix loading within the CLI

* Remove app

* Remove promise handle

* Add initial travis file

* Add libxkbfile dependency

* Add libxkbfile-dev

* Add build script

* Fix malformed bash statement

* Remove yarn from script

* Improve build script

* Extract upx before usage

* Only run upx if on linux

* Ensure resource directory exists

* Pack runnable binary

* Export binary with platform

* Improve build process

* Install upx before running install script

* Update typescript version before running nexe

* Add os.release() function for multi-platform support

* Update travis.yml to improve deployment

* Add on CI

* Update to v1.31.0

* Add libsecret

* Update build target

* Skip cleanup

* Fix built-in extensions

* Add basics for apps

* Create custom DNS server

* Fix forking within CLI. Fixes TS language features

* Fix filename resolve

* Fix default extensions path

* Add custom dialog

* Store workspace path

* Remove outfiles

* Cleanup

* Always authed outside of CLI

* Use location.host for client

* Remove useless app interface

* Remove debug file for building wordlist

* Use chromes tcp host

* Update patch

* Build browser app before packaging

* Replace all css containing file:// URLs, fix webviews

* Fix save

* Fix mkdir
  • Loading branch information
kylecarbs authored and code-asher committed Feb 21, 2019
1 parent bdd2408 commit 85d2225
Show file tree
Hide file tree
Showing 84 changed files with 5,204 additions and 264 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
lib
node_modules
dist
out
23 changes: 23 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
language: node_js
node_js:
- 8.9.3
matrix:
include:
- os: linux
dist: ubuntu
- os: osx
- os: windows
before_install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install libxkbfile-dev libsecret-1-dev;
fi
script:
- scripts/build.sh
deploy:
provider: releases
skip_cleanup: true
api_key:
secure: T/yqCIeqLifteriv8D3CnehNFzSBP309GZqeUfyx8Q+xSQEttA9Enxl+Qw9GkdedYTN4J56iucHIac6CwcvKSKIXqk80CeSEW0BNxZs5wIgv4rRMMy/GAX0NBWKNOkoGlH8M6VyQcM7eY2iGAn1EX755PHalk6rWwfsauRANOQyb2DXQBan5C0YUnogq2qcW1xkIwlXH7l0Ekbtego0f6QPv0rSyOcL1LKm6xk0Aq+xLNKJkT6TSL6xYpkPlZLjnql09Nspkqs6NehWlft2n09bHqAtjNnWw9OYCvxp8mdHeTE5uShuEqYPzdYU5LVFoE7wElI8uqS66noaA18ytZYGw2IrY6GZcn+wtR6WyM2+YXl2HclL1/Fs6Vn8+zwq2IBZchBNv3KJSn1dxiqLlD/s6YQyni17x/9FhtFoNUvsbY5zSC1xrnNQBQWFg0TRnoC9rPR+7hQtT1+5+CvRxpvcNWnPuA22919PFE79ejJulPmsnyF+YLs9c6APJgOpOO1f6fKt5Mcb02dubPqGcQ9NbqUUNTl4IUvEtjG0LnFAgEGerxAcsdnUTxzBVf0LJLlhRKW1BigUTbRwfUJL1DN0mWg9cg7fL5VqrogvNq3uRguxOsYr+bcHDbimQSAY3No3fAkTTqQSJh56Dx57/Un18KxuOTiRB9de1RtiudsI=
file: packages/server/cli-$TRAVIS_OS_NAME
on:
repo: codercom/vscode-online
all_branches: true
195 changes: 195 additions & 0 deletions build/tasks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
import { register, run } from "@coder/runner";
import * as fs from "fs";
import * as fse from "fs-extra";
import * as path from "path";
import * as zlib from "zlib";

const libPath = path.join(__dirname, "../lib");
const vscodePath = path.join(libPath, "vscode");
const pkgsPath = path.join(__dirname, "../packages");
const defaultExtensionsPath = path.join(libPath, "VSCode-linux-x64/resources/app/extensions");

const buildServerBinary = register("build:server:binary", async (runner) => {
await ensureInstalled();
await copyForDefaultExtensions();
await Promise.all([
buildBootstrapFork(),
buildWeb(),
buildDefaultExtensions(),
buildServerBundle(),
buildAppBrowser(),
]);

await buildServerBinaryPackage();
});

const buildServerBinaryPackage = register("build:server:binary:package", async (runner) => {
const cliPath = path.join(pkgsPath, "server");
runner.cwd = cliPath;
if (!fs.existsSync(path.join(cliPath, "out"))) {
throw new Error("Cannot build binary without web bundle built");
}
await buildServerBinaryCopy();
const resp = await runner.execute("npm", ["run", "build:nexe"]);
if (resp.exitCode !== 0) {
throw new Error(`Failed to package binary: ${resp.stderr}`);
}
});

const buildServerBinaryCopy = register("build:server:binary:copy", async (runner) => {
const cliPath = path.join(pkgsPath, "server");
const cliBuildPath = path.join(cliPath, "build");
fse.removeSync(cliBuildPath);
fse.mkdirpSync(path.join(cliBuildPath, "extensions"));
const bootstrapForkPath = path.join(pkgsPath, "vscode", "bin", "bootstrap-fork.js");
const webOutputPath = path.join(pkgsPath, "web", "out");
const browserAppOutputPath = path.join(pkgsPath, "app", "browser", "out");
const nodePtyModule = path.join(pkgsPath, "protocol", "node_modules", "node-pty", "build", "Release", "pty.node");

if (!fs.existsSync(nodePtyModule)) {
throw new Error("Could not find pty.node. Ensure all packages have been installed");
}
if (!fs.existsSync(webOutputPath)) {
throw new Error("Web bundle must be built");
}
if (!fs.existsSync(defaultExtensionsPath)) {
throw new Error("Default extensions must be built");
}
if (!fs.existsSync(bootstrapForkPath)) {
throw new Error("Bootstrap fork must exist");
}
fse.copySync(defaultExtensionsPath, path.join(cliBuildPath, "extensions"));
fs.writeFileSync(path.join(cliBuildPath, "bootstrap-fork.js.gz"), zlib.gzipSync(fs.readFileSync(bootstrapForkPath)));
const cpDir = (dir: string, subdir: "auth" | "unauth", rootPath: string): void => {
const stat = fs.statSync(dir);
if (stat.isDirectory()) {
const paths = fs.readdirSync(dir);
paths.forEach((p) => cpDir(path.join(dir, p), subdir, rootPath));
} else if (stat.isFile()) {
const newPath = path.join(cliBuildPath, "web", subdir, path.relative(rootPath, dir));
fse.mkdirpSync(path.dirname(newPath));
fs.writeFileSync(newPath + ".gz", zlib.gzipSync(fs.readFileSync(dir)));
} else {
// Nothing
}
};
cpDir(webOutputPath, "auth", webOutputPath);
cpDir(browserAppOutputPath, "unauth", browserAppOutputPath);
fse.mkdirpSync(path.join(cliBuildPath, "modules"));
fse.copySync(nodePtyModule, path.join(cliBuildPath, "modules", "pty.node"));
});

const buildServerBundle = register("build:server:bundle", async (runner) => {
const cliPath = path.join(pkgsPath, "server");
runner.cwd = cliPath;
await runner.execute("npm", ["run", "build:webpack"]);
});

const buildBootstrapFork = register("build:bootstrap-fork", async (runner) => {
await ensureInstalled();
await ensurePatched();

const vscodePkgPath = path.join(pkgsPath, "vscode");
runner.cwd = vscodePkgPath;
await runner.execute("npm", ["run", "build:bootstrap-fork"]);
});

const buildAppBrowser = register("build:app:browser", async (runner) => {
await ensureInstalled();

const appPath = path.join(pkgsPath, "app/browser");
runner.cwd = appPath;
fse.removeSync(path.join(appPath, "out"));
await runner.execute("npm", ["run", "build"]);
});

const buildWeb = register("build:web", async (runner) => {
await ensureInstalled();
await ensurePatched();

const webPath = path.join(pkgsPath, "web");
runner.cwd = webPath;
fse.removeSync(path.join(webPath, "out"));
await runner.execute("npm", ["run", "build"]);
});

const extDirPath = path.join("lib", "vscode-default-extensions");
const copyForDefaultExtensions = register("build:copy-vscode", async (runner) => {
if (!fs.existsSync(defaultExtensionsPath)) {
await ensureClean();
fse.removeSync(extDirPath);
fse.copySync(vscodePath, extDirPath);
}
});

const buildDefaultExtensions = register("build:default-extensions", async (runner) => {
if (!fs.existsSync(defaultExtensionsPath)) {
await copyForDefaultExtensions();
runner.cwd = extDirPath;
const resp = await runner.execute("npx", ["gulp", "vscode-linux-x64"]);
if (resp.exitCode !== 0) {
throw new Error(`Failed to build default extensions: ${resp.stderr}`);
}
}
});

const ensureInstalled = register("vscode:install", async (runner) => {
await ensureCloned();

runner.cwd = vscodePath;
const install = await runner.execute("yarn", []);
if (install.exitCode !== 0) {
throw new Error(`Failed to install vscode dependencies: ${install.stderr}`);
}
});

const ensureCloned = register("vscode:clone", async (runner) => {
if (fs.existsSync(vscodePath)) {
await ensureClean();
} else {
fs.mkdirSync(libPath);
runner.cwd = libPath;
const clone = await runner.execute("git", ["clone", "https://github.com/microsoft/vscode"]);
if (clone.exitCode !== 0) {
throw new Error(`Failed to clone: ${clone.exitCode}`);
}
}

runner.cwd = vscodePath;
const checkout = await runner.execute("git", ["checkout", "tags/1.31.0"]);
if (checkout.exitCode !== 0) {
throw new Error(`Failed to checkout: ${checkout.stderr}`);
}
});

const ensureClean = register("vscode:clean", async (runner) => {
runner.cwd = vscodePath;

const status = await runner.execute("git", ["status", "--porcelain"]);
if (status.stdout.trim() !== "") {
const clean = await runner.execute("git", ["clean", "-f", "-d", "-X"]);
if (clean.exitCode !== 0) {
throw new Error(`Failed to clean git repository: ${clean.stderr}`);
}
const removeUnstaged = await runner.execute("git", ["checkout", "--", "."]);
if (removeUnstaged.exitCode !== 0) {
throw new Error(`Failed to remove unstaged files: ${removeUnstaged.stderr}`);
}
}
});

const ensurePatched = register("vscode:patch", async (runner) => {
if (!fs.existsSync(vscodePath)) {
throw new Error("vscode must be cloned to patch");
}
await ensureClean();

runner.cwd = vscodePath;
const patchPath = path.join(__dirname, "../scripts/vscode.patch");
const apply = await runner.execute("git", ["apply", "--unidiff-zero", patchPath]);
if (apply.exitCode !== 0) {
throw new Error(`Failed to apply patches: ${apply.stderr}`);
}
});

run();
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@
"description": "Run VS Code remotely.",
"scripts": {
"build:rules": "cd ./rules && tsc -p .",
"vscode:clone": "mkdir -p ./lib && test -d ./lib/vscode || git clone https://github.com/Microsoft/vscode/ ./lib/vscode",
"vscode:install": "cd ./lib/vscode && git checkout tags/1.30.1 && yarn",
"vscode": "npm-run-all vscode:*",
"packages:install": "cd ./packages && yarn",
"postinstall": "npm-run-all --parallel vscode packages:install build:rules",
"start": "cd ./packages/server && yarn start",
"postinstall": "npm-run-all --parallel packages:install build:rules",
"start": "cd ./packages/server && yarn start",
"task": "ts-node -r tsconfig-paths/register build/tasks.ts",
"test": "cd ./packages && yarn test"
},
"devDependencies": {
"@types/fs-extra": "^5.0.4",
"@types/node": "^10.12.18",
"@types/trash": "^4.3.1",
"crypto-browserify": "^3.12.0",
"css-loader": "^2.1.0",
"file-loader": "^3.0.1",
"fork-ts-checker-webpack-plugin": "^0.5.2",
"fs-extra": "^7.0.1",
"happypack": "^5.0.1",
"html-webpack-plugin": "^3.2.0",
"http-browserify": "^1.7.0",
Expand All @@ -35,6 +35,7 @@
"style-loader": "^0.23.1",
"ts-loader": "^5.3.3",
"ts-node": "^7.0.1",
"tsconfig-paths": "^3.8.0",
"tslint": "^5.12.1",
"typescript": "^3.2.2",
"typescript-tslint-plugin": "^0.2.1",
Expand Down
10 changes: 10 additions & 0 deletions packages/app/browser/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "@coder/app",
"scripts": {
"start": "../../../node_modules/.bin/webpack-dev-server --config ./webpack.config.js",
"build": "../../../node_modules/.bin/webpack --config ./webpack.config.js"
},
"dependencies": {
"material-components-web": "^0.44.0"
}
}
43 changes: 43 additions & 0 deletions packages/app/browser/src/app.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1">
<title>Coder</title>
</head>

<body>
<div class="login">
<div class="back">
<- Back </div> <h4 class="title">AWS Cloud</h4>
<h2 class="subtitle">
Enter server password
</h2>
<div class="mdc-text-field">
<input type="password" id="password" class="mdc-text-field__input" required>
<label class="mdc-floating-label" for="password">Password</label>
<div class="mdc-line-ripple"></div>
</div>
<div class="mdc-text-field-helper-line">
<div class="mdc-text-field-helper-text">helper text</div>
</div>
<div class="mdc-form-field">
<div class="mdc-checkbox">
<input type="checkbox" class="mdc-checkbox__native-control" id="remember" />
<div class="mdc-checkbox__background">
<svg class="mdc-checkbox__checkmark" viewBox="0 0 24 24">
<path class="mdc-checkbox__checkmark-path" fill="none" d="M1.73,12.91 8.1,19.28 22.79,4.59" />
</svg>
<div class="mdc-checkbox__mixedmark"></div>
</div>
</div>
<label for="remember">Remember Me</label>
</div>
<button id="submit" class="mdc-button mdc-button--unelevated">
<span class="mdc-button__label">Enter IDE</span>
</button>
</div>
</div>
</body>

</html>
Loading

0 comments on commit 85d2225

Please sign in to comment.