mirror of
https://github.com/enso-org/enso.git
synced 2025-01-05 12:53:11 +03:00
Introducing single config for prettier and applying it across the codebase. (#3141)
This commit is contained in:
parent
22cefa7659
commit
e18322e802
@ -13,5 +13,5 @@ distribution/lib/Standard/Database/*/THIRD-PARTY
|
|||||||
built-distribution/
|
built-distribution/
|
||||||
THIRD-PARTY
|
THIRD-PARTY
|
||||||
|
|
||||||
# GUI has its own config in the subdirectory.
|
gui/dist/
|
||||||
gui/
|
**/scala-parser.js
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"printWidth": 80,
|
|
||||||
"proseWrap": "always"
|
|
||||||
}
|
|
@ -1,5 +1,4 @@
|
|||||||
overrides:
|
overrides:
|
||||||
|
|
||||||
- files: "*.[j|t]s"
|
- files: "*.[j|t]s"
|
||||||
options:
|
options:
|
||||||
printWidth: 100
|
printWidth: 100
|
11
gui/.github/ISSUE_TEMPLATE/bug-report.md
vendored
11
gui/.github/ISSUE_TEMPLATE/bug-report.md
vendored
@ -1,10 +1,9 @@
|
|||||||
---
|
---
|
||||||
name: Bug Report
|
name: Bug Report
|
||||||
about: Report a bug in Enso IDE.
|
about: Report a bug in Enso IDE.
|
||||||
title: ''
|
title: ""
|
||||||
labels: 'Type: Bug'
|
labels: "Type: Bug"
|
||||||
assignees: ''
|
assignees: ""
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
@ -13,22 +12,26 @@ the bug! It may have been fixed since.
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
### What did you do?
|
### What did you do?
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
If possible, provide a recipe for reproducing the bug.
|
If possible, provide a recipe for reproducing the bug.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### What did you expect to see?
|
### What did you expect to see?
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
- A description of the results you expected to get from the recipe above.
|
- A description of the results you expected to get from the recipe above.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### What did you see instead?
|
### What did you see instead?
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
- A description of what actually happens when you perform these steps.
|
- A description of what actually happens when you perform these steps.
|
||||||
- Please include any error output if relevant.
|
- Please include any error output if relevant.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### Enso Version
|
### Enso Version
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
- Please include the version of Enso IDE you are using here.
|
- Please include the version of Enso IDE you are using here.
|
||||||
-->
|
-->
|
||||||
|
11
gui/.github/ISSUE_TEMPLATE/epic.md
vendored
11
gui/.github/ISSUE_TEMPLATE/epic.md
vendored
@ -1,30 +1,33 @@
|
|||||||
---
|
---
|
||||||
name: Epic
|
name: Epic
|
||||||
about: Create a new epic for Enso IDE development.
|
about: Create a new epic for Enso IDE development.
|
||||||
title: ''
|
title: ""
|
||||||
labels: ''
|
labels: ""
|
||||||
assignees: ''
|
assignees: ""
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Summary
|
### Summary
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
- This section should summarise the work we want to accomplish during the epic.
|
- This section should summarise the work we want to accomplish during the epic.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### Value
|
### Value
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
- A description of the value this epic brings to users.
|
- A description of the value this epic brings to users.
|
||||||
- The motivation behind this epic.
|
- The motivation behind this epic.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### Specification
|
### Specification
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
- The high-level requirements of the epic.
|
- The high-level requirements of the epic.
|
||||||
- Any performance requirements for the epic.
|
- Any performance requirements for the epic.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### Acceptance Criteria & Test Cases
|
### Acceptance Criteria & Test Cases
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
- The high-level acceptance criteria for the epic.
|
- The high-level acceptance criteria for the epic.
|
||||||
- The test plan for the epic.
|
- The test plan for the epic.
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
---
|
---
|
||||||
name: Feature Request
|
name: Feature Request
|
||||||
about: Request a new feature in Enso IDE.
|
about: Request a new feature in Enso IDE.
|
||||||
title: ''
|
title: ""
|
||||||
labels: 'Type: Enhancement'
|
labels: "Type: Enhancement"
|
||||||
assignees: ''
|
assignees: ""
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
@ -13,11 +12,13 @@ has been implemented.
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
### General Summary
|
### General Summary
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
- Describe the feature you are requesting.
|
- Describe the feature you are requesting.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### Motivation
|
### Motivation
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
- A description of the motivation for adding this feature to Enso IDE.
|
- A description of the motivation for adding this feature to Enso IDE.
|
||||||
- Ideally this would include use-cases that support the feature.
|
- Ideally this would include use-cases that support the feature.
|
||||||
|
11
gui/.github/ISSUE_TEMPLATE/task.md
vendored
11
gui/.github/ISSUE_TEMPLATE/task.md
vendored
@ -1,30 +1,33 @@
|
|||||||
---
|
---
|
||||||
name: Task
|
name: Task
|
||||||
about: Create a new development task for Enso IDE.
|
about: Create a new development task for Enso IDE.
|
||||||
title: ''
|
title: ""
|
||||||
labels: ''
|
labels: ""
|
||||||
assignees: ''
|
assignees: ""
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Summary
|
### Summary
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
- A summary of the task.
|
- A summary of the task.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### Value
|
### Value
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
- This section should describe the value of this task.
|
- This section should describe the value of this task.
|
||||||
- This value can be for users, to the team, etc.
|
- This value can be for users, to the team, etc.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### Specification
|
### Specification
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
- Detailed requirements for the feature.
|
- Detailed requirements for the feature.
|
||||||
- The performance requirements for the feature.
|
- The performance requirements for the feature.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### Acceptance Criteria & Test Cases
|
### Acceptance Criteria & Test Cases
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
- Any criteria that must be satisfied for the task to be accepted.
|
- Any criteria that must be satisfied for the task to be accepted.
|
||||||
- The test plan for the feature, related to the acceptance criteria.
|
- The test plan for the feature, related to the acceptance criteria.
|
||||||
|
13
gui/.github/PULL_REQUEST_TEMPLATE.md
vendored
13
gui/.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,24 +1,31 @@
|
|||||||
### Pull Request Description
|
### Pull Request Description
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
- Please describe the nature of your PR here, as well as the motivation for it.
|
- Please describe the nature of your PR here, as well as the motivation for it.
|
||||||
- If it fixes an open issue, please mention that issue number here.
|
- If it fixes an open issue, please mention that issue number here.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### Important Notes
|
### Important Notes
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
- Mention important elements of the design.
|
- Mention important elements of the design.
|
||||||
- Mention any notable changes to APIs.
|
- Mention any notable changes to APIs.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### Checklist
|
### Checklist
|
||||||
|
|
||||||
Please include the following checklist in your PR:
|
Please include the following checklist in your PR:
|
||||||
|
|
||||||
- [ ] The `CHANGELOG.md` was updated with the changes introduced in this PR.
|
- [ ] The `CHANGELOG.md` was updated with the changes introduced in this PR.
|
||||||
- [ ] The documentation has been updated if necessary.
|
- [ ] The documentation has been updated if necessary.
|
||||||
- [ ] All code conforms to the [Rust](https://github.com/enso-org/enso/blob/develop/docs/style-guide/rust.md) style guide.
|
- [ ] All code conforms to the
|
||||||
|
[Rust](https://github.com/enso-org/enso/blob/develop/docs/style-guide/rust.md)
|
||||||
|
style guide.
|
||||||
- [ ] All code has automatic tests where possible.
|
- [ ] All code has automatic tests where possible.
|
||||||
- [ ] All code has been profiled where possible.
|
- [ ] All code has been profiled where possible.
|
||||||
- [ ] All code has been manually tested in the IDE.
|
- [ ] All code has been manually tested in the IDE.
|
||||||
- [ ] All code has been manually tested in the "debug/interface" scene.
|
- [ ] All code has been manually tested in the "debug/interface" scene.
|
||||||
- [ ] All code has been manually tested by the PR owner against our [test scenarios](https://airtable.com/shr7KPRypRpanF7TO).
|
- [ ] All code has been manually tested by the PR owner against our
|
||||||
- [ ] All code has been manually tested by at least one reviewer against our [test scenarios](https://airtable.com/shr7KPRypRpanF7TO).
|
[test scenarios](https://airtable.com/shr7KPRypRpanF7TO).
|
||||||
|
- [ ] All code has been manually tested by at least one reviewer against our
|
||||||
|
[test scenarios](https://airtable.com/shr7KPRypRpanF7TO).
|
||||||
|
6
gui/.github/workflows/docs.yml
vendored
6
gui/.github/workflows/docs.yml
vendored
@ -5,7 +5,7 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- develop
|
- develop
|
||||||
paths:
|
paths:
|
||||||
- 'docs/**'
|
- "docs/**"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
checkout:
|
checkout:
|
||||||
@ -13,8 +13,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
repository: 'enso-org/enso-org.github.io'
|
repository: "enso-org/enso-org.github.io"
|
||||||
ref: 'sources'
|
ref: "sources"
|
||||||
token: ${{ secrets.ENSO_PAT }}
|
token: ${{ secrets.ENSO_PAT }}
|
||||||
- name: set identity email
|
- name: set identity email
|
||||||
run: git config --global user.email "actions@github.com"
|
run: git config --global user.email "actions@github.com"
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
**/lib/**/*.js
|
|
||||||
**/target/*
|
|
@ -4,11 +4,13 @@ const exec = require('child_process').exec
|
|||||||
|
|
||||||
function download(url) {
|
function download(url) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
https.get(url,(res) => {
|
https
|
||||||
let data = ""
|
.get(url, res => {
|
||||||
res.on("data", (chunk) => data += chunk)
|
let data = ''
|
||||||
res.on("end", () => resolve(data))
|
res.on('data', chunk => (data += chunk))
|
||||||
}).on("error", (error) => reject(error))
|
res.on('end', () => resolve(data))
|
||||||
|
})
|
||||||
|
.on('error', error => reject(error))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,7 +39,7 @@ function run(cmd,args) {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
console.log(`Calling '${cmd} ${args.join(' ')}'`)
|
console.log(`Calling '${cmd} ${args.join(' ')}'`)
|
||||||
let proc = spawn(cmd, args, { stdio: 'inherit', shell: true })
|
let proc = spawn(cmd, args, { stdio: 'inherit', shell: true })
|
||||||
proc.on('exit', (code) => {
|
proc.on('exit', code => {
|
||||||
if (code) process.exit(code)
|
if (code) process.exit(code)
|
||||||
resolve(out)
|
resolve(out)
|
||||||
})
|
})
|
||||||
@ -49,19 +51,25 @@ function run_read(cmd,args) {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let proc = spawn(cmd, args, { shell: true })
|
let proc = spawn(cmd, args, { shell: true })
|
||||||
proc.stderr.pipe(process.stderr)
|
proc.stderr.pipe(process.stderr)
|
||||||
proc.stdout.on('data', (data) => { out += data })
|
proc.stdout.on('data', data => {
|
||||||
proc.on('exit', (code) => {
|
out += data
|
||||||
if (code) process.exit(code);
|
})
|
||||||
|
proc.on('exit', code => {
|
||||||
|
if (code) process.exit(code)
|
||||||
resolve(out)
|
resolve(out)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function check_version(name, required, cfg) {
|
async function check_version(name, required, cfg) {
|
||||||
if (!cfg) { cfg = {} }
|
if (!cfg) {
|
||||||
|
cfg = {}
|
||||||
|
}
|
||||||
let version = await run_read(name, ['--version'])
|
let version = await run_read(name, ['--version'])
|
||||||
version = version.trim()
|
version = version.trim()
|
||||||
if (cfg.preprocess) { version = cfg.preprocess(version) }
|
if (cfg.preprocess) {
|
||||||
|
version = cfg.preprocess(version)
|
||||||
|
}
|
||||||
if (cfg.silent !== true) {
|
if (cfg.silent !== true) {
|
||||||
console.log(`Checking if '${name}' version is '${required}'.`)
|
console.log(`Checking if '${name}' version is '${required}'.`)
|
||||||
}
|
}
|
||||||
@ -96,12 +104,21 @@ async function get_node_lts_version() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!newest) {
|
if (!newest) {
|
||||||
throw "Cannot fetch the info about node LTS version."
|
throw 'Cannot fetch the info about node LTS version.'
|
||||||
}
|
}
|
||||||
let node = newest.version
|
let node = newest.version
|
||||||
let npm = newest.npm
|
let npm = newest.npm
|
||||||
return [node, npm]
|
return [node, npm]
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {section,run,run_read,check_version,get_npm_info,get_npm_lts_version_of,with_cwd,
|
module.exports = {
|
||||||
get_node_dist_index,get_node_lts_version}
|
section,
|
||||||
|
run,
|
||||||
|
run_read,
|
||||||
|
check_version,
|
||||||
|
get_npm_info,
|
||||||
|
get_npm_lts_version_of,
|
||||||
|
with_cwd,
|
||||||
|
get_node_dist_index,
|
||||||
|
get_node_lts_version,
|
||||||
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
const path = require('path')
|
const path = require('path')
|
||||||
const os = require('os')
|
const os = require('os')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =============
|
// =============
|
||||||
// === Paths ===
|
// === Paths ===
|
||||||
// =============
|
// =============
|
||||||
@ -59,7 +57,7 @@ function get_project_manager_extension() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
paths.get_project_manager_path = function (root) {
|
paths.get_project_manager_path = function (root) {
|
||||||
let base_path = path.join(root, 'enso', 'bin',)
|
let base_path = path.join(root, 'enso', 'bin')
|
||||||
const extension = get_project_manager_extension()
|
const extension = get_project_manager_extension()
|
||||||
return path.join(base_path, 'project-manager') + extension
|
return path.join(base_path, 'project-manager') + extension
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,6 @@ const paths = require('./paths')
|
|||||||
const semver = require('semver')
|
const semver = require('semver')
|
||||||
const config = require('../config')
|
const config = require('../config')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =================
|
// =================
|
||||||
// === Constants ===
|
// === Constants ===
|
||||||
// =================
|
// =================
|
||||||
@ -17,8 +15,6 @@ const CHANGELOG_FILE_NAME = 'CHANGELOG.md'
|
|||||||
const CHANGELOG_FILE = path.join(paths.root, CHANGELOG_FILE_NAME)
|
const CHANGELOG_FILE = path.join(paths.root, CHANGELOG_FILE_NAME)
|
||||||
const ENGINE_VERSION = config.engineVersion
|
const ENGINE_VERSION = config.engineVersion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ===============
|
// ===============
|
||||||
// === Version ===
|
// === Version ===
|
||||||
// ===============
|
// ===============
|
||||||
@ -26,7 +22,7 @@ const ENGINE_VERSION = config.engineVersion
|
|||||||
class NextReleaseVersion {
|
class NextReleaseVersion {
|
||||||
/// Version used for config files when building the package with "next version" in changelog.
|
/// Version used for config files when building the package with "next version" in changelog.
|
||||||
toString() {
|
toString() {
|
||||||
return "0.0.0"
|
return '0.0.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
isPrerelease() {
|
isPrerelease() {
|
||||||
@ -46,19 +42,39 @@ class Version {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lt(that) {
|
lt(that) {
|
||||||
if (this.major < that.major) { return true }
|
if (this.major < that.major) {
|
||||||
if (this.minor < that.minor) { return true }
|
return true
|
||||||
if (this.patch < that.patch) { return true }
|
}
|
||||||
if (this.tag === 'alpha' && that.tag === 'beta') { return true }
|
if (this.minor < that.minor) {
|
||||||
if (this.tag === 'alpha' && that.tag === 'rc') { return true }
|
return true
|
||||||
if (this.tag === 'beta' && that.tag === 'rc') { return true }
|
}
|
||||||
if (this.tagVersion < that.tagVersion) { return true }
|
if (this.patch < that.patch) {
|
||||||
if (this.rcTagVersion < that.rcTagVersion) { return true }
|
return true
|
||||||
|
}
|
||||||
|
if (this.tag === 'alpha' && that.tag === 'beta') {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (this.tag === 'alpha' && that.tag === 'rc') {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (this.tag === 'beta' && that.tag === 'rc') {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (this.tagVersion < that.tagVersion) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (this.rcTagVersion < that.rcTagVersion) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
isPrerelease() {
|
isPrerelease() {
|
||||||
if (this.tag) { return true } else { return false }
|
if (this.tag) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toString() {
|
toString() {
|
||||||
@ -73,8 +89,6 @@ class Version {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ======================
|
// ======================
|
||||||
// === ChangelogEntry ===
|
// === ChangelogEntry ===
|
||||||
// ======================
|
// ======================
|
||||||
@ -94,14 +108,14 @@ class ChangelogEntry {
|
|||||||
assert_is_unstable() {
|
assert_is_unstable() {
|
||||||
this.assert_is_newest_version_defined()
|
this.assert_is_newest_version_defined()
|
||||||
if (!this.isPrerelease()) {
|
if (!this.isPrerelease()) {
|
||||||
throw "Assertion failed. The version is stable."
|
throw 'Assertion failed. The version is stable.'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_is_stable() {
|
assert_is_stable() {
|
||||||
this.assert_is_newest_version_defined()
|
this.assert_is_newest_version_defined()
|
||||||
if (this.isPrerelease()) {
|
if (this.isPrerelease()) {
|
||||||
throw "Assertion failed. The version is unstable."
|
throw 'Assertion failed. The version is unstable.'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,8 +124,6 @@ class ChangelogEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =================
|
// =================
|
||||||
// === Changelog ===
|
// === Changelog ===
|
||||||
// =================
|
// =================
|
||||||
@ -131,9 +143,9 @@ class Changelog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function changelogSections() {
|
function changelogSections() {
|
||||||
let text = '\n' + fss.readFileSync(CHANGELOG_FILE,"utf8")
|
let text = '\n' + fss.readFileSync(CHANGELOG_FILE, 'utf8')
|
||||||
let chunks = text.split(/\r?\n#(?!#)/)
|
let chunks = text.split(/\r?\n#(?!#)/)
|
||||||
return chunks.filter((s) => s != '')
|
return chunks.filter(s => s != '')
|
||||||
}
|
}
|
||||||
|
|
||||||
function changelogEntries() {
|
function changelogEntries() {
|
||||||
@ -145,16 +157,25 @@ function changelogEntries() {
|
|||||||
let header = section.substring(0, splitPoint)
|
let header = section.substring(0, splitPoint)
|
||||||
let body = section.substring(splitPoint).trim()
|
let body = section.substring(splitPoint).trim()
|
||||||
if (firstSection && header.startsWith(' Next Release')) {
|
if (firstSection && header.startsWith(' Next Release')) {
|
||||||
let version = new NextReleaseVersion
|
let version = new NextReleaseVersion()
|
||||||
entries.push(new ChangelogEntry(version, body))
|
entries.push(new ChangelogEntry(version, body))
|
||||||
} else {
|
} else {
|
||||||
let headerReg = /^ Enso (?<major>[0-9]+)\.(?<minor>[0-9]+)\.(?<patch>[0-9]+)(-(?<tag>alpha|beta|rc)\.(?<tagVersion>[0-9]+))?(.(?<rcTag>rc)\.(?<rcTagVersion>[0-9]+))? \((?<year>[0-9][0-9][0-9][0-9])-(?<month>[0-9][0-9])-(?<day>[0-9][0-9])\)/
|
let headerReg =
|
||||||
|
/^ Enso (?<major>[0-9]+)\.(?<minor>[0-9]+)\.(?<patch>[0-9]+)(-(?<tag>alpha|beta|rc)\.(?<tagVersion>[0-9]+))?(.(?<rcTag>rc)\.(?<rcTagVersion>[0-9]+))? \((?<year>[0-9][0-9][0-9][0-9])-(?<month>[0-9][0-9])-(?<day>[0-9][0-9])\)/
|
||||||
let match = header.match(headerReg)
|
let match = header.match(headerReg)
|
||||||
if (!match) {
|
if (!match) {
|
||||||
throw `Improper changelog entry header: '${header}'. See the 'CHANGELOG_TEMPLATE.md' for details.`
|
throw `Improper changelog entry header: '${header}'. See the 'CHANGELOG_TEMPLATE.md' for details.`
|
||||||
}
|
}
|
||||||
let grps = match.groups
|
let grps = match.groups
|
||||||
let version = new Version(grps.major,grps.minor,grps.patch,grps.tag,grps.tagVersion,grps.rcTag,grps.rcTagVersion)
|
let version = new Version(
|
||||||
|
grps.major,
|
||||||
|
grps.minor,
|
||||||
|
grps.patch,
|
||||||
|
grps.tag,
|
||||||
|
grps.tagVersion,
|
||||||
|
grps.rcTag,
|
||||||
|
grps.rcTagVersion
|
||||||
|
)
|
||||||
entries.push(new ChangelogEntry(version, body))
|
entries.push(new ChangelogEntry(version, body))
|
||||||
}
|
}
|
||||||
firstSection = false
|
firstSection = false
|
||||||
@ -179,15 +200,13 @@ function changelogEntries() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function changelog() {
|
function changelog() {
|
||||||
return new Changelog
|
return new Changelog()
|
||||||
}
|
}
|
||||||
|
|
||||||
function currentVersion() {
|
function currentVersion() {
|
||||||
return changelog().currentVersion()
|
return changelog().currentVersion()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ===============
|
// ===============
|
||||||
// === Exports ===
|
// === Exports ===
|
||||||
// ===============
|
// ===============
|
||||||
|
168
gui/build/run.js
168
gui/build/run.js
@ -9,7 +9,7 @@ const ncp = require('ncp').ncp
|
|||||||
const os = require('os')
|
const os = require('os')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const paths = require('./paths')
|
const paths = require('./paths')
|
||||||
const prettier = require("prettier")
|
const prettier = require('prettier')
|
||||||
const release = require('./release')
|
const release = require('./release')
|
||||||
const stream = require('stream')
|
const stream = require('stream')
|
||||||
const workflow = require('./workflow')
|
const workflow = require('./workflow')
|
||||||
@ -18,17 +18,15 @@ const zlib = require('zlib')
|
|||||||
const { promisify } = require('util')
|
const { promisify } = require('util')
|
||||||
const pipe = promisify(stream.pipeline)
|
const pipe = promisify(stream.pipeline)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ==============
|
// ==============
|
||||||
// === Errors ===
|
// === Errors ===
|
||||||
// ==============
|
// ==============
|
||||||
|
|
||||||
process.on('unhandledRejection', error => { throw(error) })
|
process.on('unhandledRejection', error => {
|
||||||
|
throw error
|
||||||
|
})
|
||||||
process.chdir(paths.root)
|
process.chdir(paths.root)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ========================
|
// ========================
|
||||||
// === Global Variables ===
|
// === Global Variables ===
|
||||||
// ========================
|
// ========================
|
||||||
@ -41,8 +39,6 @@ let cargoArgs = undefined
|
|||||||
// command line args get parsed.
|
// command line args get parsed.
|
||||||
let targetArgs = undefined
|
let targetArgs = undefined
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =============
|
// =============
|
||||||
// === Utils ===
|
// === Utils ===
|
||||||
// =============
|
// =============
|
||||||
@ -57,8 +53,10 @@ async function gzip(input, output) {
|
|||||||
/// Copy files and directories.
|
/// Copy files and directories.
|
||||||
async function copy(src, tgt) {
|
async function copy(src, tgt) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
ncp(src,tgt,(err) => {
|
ncp(src, tgt, err => {
|
||||||
if (err) { reject(`${err}`) }
|
if (err) {
|
||||||
|
reject(`${err}`)
|
||||||
|
}
|
||||||
resolve()
|
resolve()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -74,7 +72,6 @@ async function run(command,args) {
|
|||||||
await cmd.run(command, args)
|
await cmd.run(command, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Defines a new command argument builder.
|
/// Defines a new command argument builder.
|
||||||
function command(docs) {
|
function command(docs) {
|
||||||
return { docs }
|
return { docs }
|
||||||
@ -103,8 +100,6 @@ function run_project_manager() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ================
|
// ================
|
||||||
// === Commands ===
|
// === Commands ===
|
||||||
// ================
|
// ================
|
||||||
@ -112,7 +107,6 @@ function run_project_manager() {
|
|||||||
const DEFAULT_CRATE = 'ide'
|
const DEFAULT_CRATE = 'ide'
|
||||||
let commands = {}
|
let commands = {}
|
||||||
|
|
||||||
|
|
||||||
// === Clean ===
|
// === Clean ===
|
||||||
|
|
||||||
commands.clean = command(`Clean all build artifacts`)
|
commands.clean = command(`Clean all build artifacts`)
|
||||||
@ -130,7 +124,6 @@ commands.clean.rust = async function() {
|
|||||||
await run_cargo('cargo', ['clean'])
|
await run_cargo('cargo', ['clean'])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// === Check ===
|
// === Check ===
|
||||||
|
|
||||||
commands.check = command(`Fast check if project builds (only Rust target)`)
|
commands.check = command(`Fast check if project builds (only Rust target)`)
|
||||||
@ -138,15 +131,14 @@ commands.check.rust = async function() {
|
|||||||
await run_cargo('cargo', ['check'])
|
await run_cargo('cargo', ['check'])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// === Build ===
|
// === Build ===
|
||||||
|
|
||||||
commands.build = command(`Build the sources in release mode`)
|
commands.build = command(`Build the sources in release mode`)
|
||||||
commands.build.options = {
|
commands.build.options = {
|
||||||
'crate': {
|
crate: {
|
||||||
describe: 'Target crate to build',
|
describe: 'Target crate to build',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
commands.build.js = async function () {
|
commands.build.js = async function () {
|
||||||
await installJsDeps()
|
await installJsDeps()
|
||||||
@ -158,8 +150,19 @@ commands.build.rust = async function(argv) {
|
|||||||
let crate = argv.crate || DEFAULT_CRATE
|
let crate = argv.crate || DEFAULT_CRATE
|
||||||
let crate_sfx = crate ? ` '${crate}'` : ``
|
let crate_sfx = crate ? ` '${crate}'` : ``
|
||||||
console.log(`Building WASM target${crate_sfx}.`)
|
console.log(`Building WASM target${crate_sfx}.`)
|
||||||
let args = ['build','--target','web','--out-dir',paths.dist.wasm.root,'--out-name','ide',crate]
|
let args = [
|
||||||
if (argv.dev) { args.push('--dev') }
|
'build',
|
||||||
|
'--target',
|
||||||
|
'web',
|
||||||
|
'--out-dir',
|
||||||
|
paths.dist.wasm.root,
|
||||||
|
'--out-name',
|
||||||
|
'ide',
|
||||||
|
crate,
|
||||||
|
]
|
||||||
|
if (argv.dev) {
|
||||||
|
args.push('--dev')
|
||||||
|
}
|
||||||
await run_cargo('wasm-pack', args)
|
await run_cargo('wasm-pack', args)
|
||||||
await patch_file(paths.dist.wasm.glue, js_workaround_patcher)
|
await patch_file(paths.dist.wasm.glue, js_workaround_patcher)
|
||||||
await fs.rename(paths.dist.wasm.mainRaw, paths.dist.wasm.main)
|
await fs.rename(paths.dist.wasm.mainRaw, paths.dist.wasm.main)
|
||||||
@ -173,10 +176,10 @@ commands.build.rust = async function(argv) {
|
|||||||
|
|
||||||
console.log('Checking the resulting WASM size.')
|
console.log('Checking the resulting WASM size.')
|
||||||
let stats = fss.statSync(paths.dist.wasm.mainOptGz)
|
let stats = fss.statSync(paths.dist.wasm.mainOptGz)
|
||||||
let limit = 4.60
|
let limit = 4.6
|
||||||
let size = Math.round(100 * stats.size / 1024 / 1024) / 100
|
let size = Math.round((100 * stats.size) / 1024 / 1024) / 100
|
||||||
if (size > limit) {
|
if (size > limit) {
|
||||||
throw(`Output file size exceeds the limit (${size}MB > ${limit}MB).`)
|
throw `Output file size exceeds the limit (${size}MB > ${limit}MB).`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -186,7 +189,7 @@ function js_workaround_patcher(code) {
|
|||||||
code = code.replace(/if \(\(typeof URL.*}\);/gs, 'return imports')
|
code = code.replace(/if \(\(typeof URL.*}\);/gs, 'return imports')
|
||||||
code = code.replace(/if \(typeof module.*let result/gs, 'let result')
|
code = code.replace(/if \(typeof module.*let result/gs, 'let result')
|
||||||
code = code.replace(/export default init;/gs, 'export default init')
|
code = code.replace(/export default init;/gs, 'export default init')
|
||||||
code += '\nexport function after_load\(w,m\) { wasm = w; init.__wbindgen_wasm_module = m;}'
|
code += '\nexport function after_load(w,m) { wasm = w; init.__wbindgen_wasm_module = m;}'
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,7 +199,6 @@ async function patch_file(path,patcher) {
|
|||||||
await fs.writeFile(path, patched_code)
|
await fs.writeFile(path, patched_code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// === Start ===
|
// === Start ===
|
||||||
|
|
||||||
commands.start = command(`Build and start desktop client`)
|
commands.start = command(`Build and start desktop client`)
|
||||||
@ -211,14 +213,17 @@ commands.start.js = async function (argv) {
|
|||||||
// The backend path is being prepended here, as appending would be incorrect.
|
// The backend path is being prepended here, as appending would be incorrect.
|
||||||
// That is because `targetArgs` might include `-- …` and appended args could
|
// That is because `targetArgs` might include `-- …` and appended args could
|
||||||
// end up being passed to the spawned backend process.
|
// end up being passed to the spawned backend process.
|
||||||
const args = ['--backend-path', paths.get_project_manager_path(paths.dist.bin)].concat(targetArgs)
|
const args = ['--backend-path', paths.get_project_manager_path(paths.dist.bin)].concat(
|
||||||
if (argv.dev) { args.push('--dev') }
|
targetArgs
|
||||||
|
)
|
||||||
|
if (argv.dev) {
|
||||||
|
args.push('--dev')
|
||||||
|
}
|
||||||
await cmd.with_cwd(paths.js.root, async () => {
|
await cmd.with_cwd(paths.js.root, async () => {
|
||||||
await run('npm', ['run', 'start', '--'].concat(args))
|
await run('npm', ['run', 'start', '--'].concat(args))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// === Test ===
|
// === Test ===
|
||||||
|
|
||||||
commands.test = command(`Run test suites`)
|
commands.test = command(`Run test suites`)
|
||||||
@ -230,12 +235,19 @@ commands.test.rust = async function(argv) {
|
|||||||
|
|
||||||
if (argv.wasm) {
|
if (argv.wasm) {
|
||||||
console.log(`Running Rust WASM test suite.`)
|
console.log(`Running Rust WASM test suite.`)
|
||||||
let args = ['run','--manifest-path=test/Cargo.toml','--bin','test_all','--','--headless','--chrome']
|
let args = [
|
||||||
|
'run',
|
||||||
|
'--manifest-path=test/Cargo.toml',
|
||||||
|
'--bin',
|
||||||
|
'test_all',
|
||||||
|
'--',
|
||||||
|
'--headless',
|
||||||
|
'--chrome',
|
||||||
|
]
|
||||||
await run_cargo('cargo', args)
|
await run_cargo('cargo', args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// === Lint ===
|
// === Lint ===
|
||||||
|
|
||||||
commands.lint = command(`Lint the codebase`)
|
commands.lint = command(`Lint the codebase`)
|
||||||
@ -244,23 +256,21 @@ commands.lint.rust = async function() {
|
|||||||
await run_cargo('cargo', ['fmt', '--', '--check'])
|
await run_cargo('cargo', ['fmt', '--', '--check'])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// === TomlFmt ===
|
// === TomlFmt ===
|
||||||
|
|
||||||
commands['toml-fmt'] = command(`Lint the codebase`)
|
commands['toml-fmt'] = command(`Lint the codebase`)
|
||||||
commands['toml-fmt'].rust = async function () {
|
commands['toml-fmt'].rust = async function () {
|
||||||
console.log("Looking for all TOML files.")
|
console.log('Looking for all TOML files.')
|
||||||
let files = glob.sync(paths.rust.root + "/**/*.toml", {cwd:paths.root});
|
let files = glob.sync(paths.rust.root + '/**/*.toml', { cwd: paths.root })
|
||||||
console.log(`Found ${files.length} entries. Running auto-formatter.`)
|
console.log(`Found ${files.length} entries. Running auto-formatter.`)
|
||||||
for (let file of files) {
|
for (let file of files) {
|
||||||
console.log(` Formatting '${file}'.`)
|
console.log(` Formatting '${file}'.`)
|
||||||
let text = fss.readFileSync(file, "utf8")
|
let text = fss.readFileSync(file, 'utf8')
|
||||||
let out = prettier.format(text, { parser: 'toml' })
|
let out = prettier.format(text, { parser: 'toml' })
|
||||||
fss.writeFileSync(file, out)
|
fss.writeFileSync(file, out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// === Watch ===
|
// === Watch ===
|
||||||
|
|
||||||
commands.watch = command(`Start a file-watch utility and run interactive mode`)
|
commands.watch = command(`Start a file-watch utility and run interactive mode`)
|
||||||
@ -279,7 +289,7 @@ commands.watch.common = async function(argv) {
|
|||||||
// Run build processes.
|
// Run build processes.
|
||||||
|
|
||||||
await cmd.with_cwd(paths.rust.root, async () => {
|
await cmd.with_cwd(paths.rust.root, async () => {
|
||||||
return commands.build.rust(argv);
|
return commands.build.rust(argv)
|
||||||
})
|
})
|
||||||
await cmd.with_cwd(paths.js.root, async () => {
|
await cmd.with_cwd(paths.js.root, async () => {
|
||||||
// Among other things, this will call the build script of the project-manager package. But
|
// Among other things, this will call the build script of the project-manager package. But
|
||||||
@ -305,14 +315,13 @@ commands.watch.common = async function(argv) {
|
|||||||
return cmd.run('cargo', args)
|
return cmd.run('cargo', args)
|
||||||
})
|
})
|
||||||
const js_process = cmd.with_cwd(paths.js.root, async () => {
|
const js_process = cmd.with_cwd(paths.js.root, async () => {
|
||||||
return run('npm',['run','watch']);
|
return run('npm', ['run', 'watch'])
|
||||||
})
|
})
|
||||||
|
|
||||||
await rust_process
|
await rust_process
|
||||||
await js_process
|
await js_process
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// === Dist ===
|
// === Dist ===
|
||||||
|
|
||||||
commands.dist = command(`Build the sources and create distribution packages`)
|
commands.dist = command(`Build the sources and create distribution packages`)
|
||||||
@ -327,7 +336,6 @@ commands.dist.js = async function() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// === CI Gen ===
|
// === CI Gen ===
|
||||||
|
|
||||||
/// The command is used by CI to generate the file `CURRENT_RELEASE_CHANGELOG.json`, which contains
|
/// The command is used by CI to generate the file `CURRENT_RELEASE_CHANGELOG.json`, which contains
|
||||||
@ -339,7 +347,7 @@ commands['ci-gen'].rust = async function(argv) {
|
|||||||
let body = entry.body
|
let body = entry.body
|
||||||
let version = entry.version.toString()
|
let version = entry.version.toString()
|
||||||
let prerelease = entry.isPrerelease()
|
let prerelease = entry.isPrerelease()
|
||||||
let obj = {version,body,prerelease};
|
let obj = { version, body, prerelease }
|
||||||
let json = JSON.stringify(obj)
|
let json = JSON.stringify(obj)
|
||||||
fss.writeFileSync(path.join(paths.root, 'CURRENT_RELEASE_CHANGELOG.json'), json)
|
fss.writeFileSync(path.join(paths.root, 'CURRENT_RELEASE_CHANGELOG.json'), json)
|
||||||
}
|
}
|
||||||
@ -356,8 +364,6 @@ commands['assert-version-stable'].rust = async function(argv) {
|
|||||||
let entry = release.changelog().newestEntry().assert_is_stable()
|
let entry = release.changelog().newestEntry().assert_is_stable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ===========================
|
// ===========================
|
||||||
// === Command Line Parser ===
|
// === Command Line Parser ===
|
||||||
// ===========================
|
// ===========================
|
||||||
@ -370,7 +376,7 @@ For example, 'run start -- --dev -- --debug-scene shapes' will pass '--dev' to c
|
|||||||
and '--debug-scene shapes' to the output binary.`
|
and '--debug-scene shapes' to the output binary.`
|
||||||
|
|
||||||
let optParser = yargs
|
let optParser = yargs
|
||||||
.scriptName("")
|
.scriptName('')
|
||||||
.usage(usage)
|
.usage(usage)
|
||||||
.help()
|
.help()
|
||||||
.parserConfiguration({ 'populate--': true })
|
.parserConfiguration({ 'populate--': true })
|
||||||
@ -379,22 +385,22 @@ let optParser = yargs
|
|||||||
optParser.options('rust', {
|
optParser.options('rust', {
|
||||||
describe: 'Run the Rust target',
|
describe: 'Run the Rust target',
|
||||||
type: 'bool',
|
type: 'bool',
|
||||||
default : true
|
default: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
optParser.options('js', {
|
optParser.options('js', {
|
||||||
describe: 'Run the JavaScript target',
|
describe: 'Run the JavaScript target',
|
||||||
type: 'bool',
|
type: 'bool',
|
||||||
default : true
|
default: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
optParser.options('release', {
|
optParser.options('release', {
|
||||||
describe : "Enable all optimizations",
|
describe: 'Enable all optimizations',
|
||||||
type: 'bool',
|
type: 'bool',
|
||||||
})
|
})
|
||||||
|
|
||||||
optParser.options('dev', {
|
optParser.options('dev', {
|
||||||
describe : "Optimize for fast builds",
|
describe: 'Optimize for fast builds',
|
||||||
type: 'bool',
|
type: 'bool',
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -415,7 +421,7 @@ let commandList = Object.keys(commands)
|
|||||||
commandList.sort()
|
commandList.sort()
|
||||||
for (let command of commandList) {
|
for (let command of commandList) {
|
||||||
let config = commands[command]
|
let config = commands[command]
|
||||||
optParser.command(command,config.docs,(args) => {
|
optParser.command(command, config.docs, args => {
|
||||||
for (let option in config.options) {
|
for (let option in config.options) {
|
||||||
args.options(option, config.options[option])
|
args.options(option, config.options[option])
|
||||||
}
|
}
|
||||||
@ -425,18 +431,16 @@ for (let command of commandList) {
|
|||||||
args.options('native', {
|
args.options('native', {
|
||||||
describe: 'Run native tests',
|
describe: 'Run native tests',
|
||||||
type: 'bool',
|
type: 'bool',
|
||||||
default : true
|
default: true,
|
||||||
})
|
})
|
||||||
args.options('wasm', {
|
args.options('wasm', {
|
||||||
describe: 'Run WASM tests',
|
describe: 'Run WASM tests',
|
||||||
type: 'bool',
|
type: 'bool',
|
||||||
default : true
|
default: true,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ======================
|
// ======================
|
||||||
// === Package Config ===
|
// === Package Config ===
|
||||||
// ======================
|
// ======================
|
||||||
@ -445,24 +449,24 @@ function defaultConfig() {
|
|||||||
return {
|
return {
|
||||||
version: `${release.currentVersion()}`,
|
version: `${release.currentVersion()}`,
|
||||||
author: {
|
author: {
|
||||||
name: "Enso Team",
|
name: 'Enso Team',
|
||||||
email: "contact@enso.org"
|
email: 'contact@enso.org',
|
||||||
},
|
},
|
||||||
homepage: "https://github.com/enso-org/ide",
|
homepage: 'https://github.com/enso-org/ide',
|
||||||
repository: {
|
repository: {
|
||||||
type: "git",
|
type: 'git',
|
||||||
url: "git@github.com:enso-org/ide.git"
|
url: 'git@github.com:enso-org/ide.git',
|
||||||
},
|
},
|
||||||
bugs: {
|
bugs: {
|
||||||
url: "https://github.com/enso-org/ide/issues"
|
url: 'https://github.com/enso-org/ide/issues',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processPackageConfigs() {
|
async function processPackageConfigs() {
|
||||||
let files = []
|
let files = []
|
||||||
files = files.concat(glob.sync(paths.js.root + "/package.js", {cwd:paths.root}))
|
files = files.concat(glob.sync(paths.js.root + '/package.js', { cwd: paths.root }))
|
||||||
files = files.concat(glob.sync(paths.js.root + "/lib/*/package.js", {cwd:paths.root}))
|
files = files.concat(glob.sync(paths.js.root + '/lib/*/package.js', { cwd: paths.root }))
|
||||||
for (file of files) {
|
for (file of files) {
|
||||||
let dirPath = path.dirname(file)
|
let dirPath = path.dirname(file)
|
||||||
let outPath = path.join(dirPath, 'package.json')
|
let outPath = path.join(dirPath, 'package.json')
|
||||||
@ -471,14 +475,14 @@ async function processPackageConfigs() {
|
|||||||
let fn = new Function('require', 'paths', modSrc)
|
let fn = new Function('require', 'paths', modSrc)
|
||||||
let mod = fn(require, paths)
|
let mod = fn(require, paths)
|
||||||
let config = mod.config
|
let config = mod.config
|
||||||
if (!config) { throw(`Package config '${file}' do not export 'module.config'.`) }
|
if (!config) {
|
||||||
|
throw `Package config '${file}' do not export 'module.config'.`
|
||||||
|
}
|
||||||
config = Object.assign(defaultConfig(), config)
|
config = Object.assign(defaultConfig(), config)
|
||||||
fs.writeFile(outPath, JSON.stringify(config, undefined, 4))
|
fs.writeFile(outPath, JSON.stringify(config, undefined, 4))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ============
|
// ============
|
||||||
// === Main ===
|
// === Main ===
|
||||||
// ============
|
// ============
|
||||||
@ -493,11 +497,7 @@ async function updateBuildVersion (argv) {
|
|||||||
config = JSON.parse(configFile)
|
config = JSON.parse(configFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
let commitHashCmd = await cmd.run_read('git', [
|
let commitHashCmd = await cmd.run_read('git', ['rev-parse', '--short', 'HEAD'])
|
||||||
'rev-parse',
|
|
||||||
'--short',
|
|
||||||
'HEAD'
|
|
||||||
])
|
|
||||||
let commitHash = commitHashCmd.trim()
|
let commitHash = commitHashCmd.trim()
|
||||||
|
|
||||||
if (config.buildVersion !== commitHash || config.target !== target) {
|
if (config.buildVersion !== commitHash || config.target !== target) {
|
||||||
@ -506,7 +506,6 @@ async function updateBuildVersion (argv) {
|
|||||||
await fs.mkdir(paths.dist.root, { recursive: true })
|
await fs.mkdir(paths.dist.root, { recursive: true })
|
||||||
await fs.writeFile(configPath, JSON.stringify(config, undefined, 2))
|
await fs.writeFile(configPath, JSON.stringify(config, undefined, 2))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function installJsDeps() {
|
async function installJsDeps() {
|
||||||
@ -556,12 +555,13 @@ async function runCommand(command, argv) {
|
|||||||
console.error(`Invalid command '${command}'.`)
|
console.error(`Invalid command '${command}'.`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if(cargoArgs === undefined) { cargoArgs = [] }
|
if (cargoArgs === undefined) {
|
||||||
|
cargoArgs = []
|
||||||
|
}
|
||||||
let index = cargoArgs.indexOf('--')
|
let index = cargoArgs.indexOf('--')
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
targetArgs = []
|
targetArgs = []
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
targetArgs = cargoArgs.slice(index + 1)
|
targetArgs = cargoArgs.slice(index + 1)
|
||||||
cargoArgs = cargoArgs.slice(0, index)
|
cargoArgs = cargoArgs.slice(0, index)
|
||||||
}
|
}
|
||||||
@ -575,14 +575,26 @@ async function runCommand(command, argv) {
|
|||||||
let jsCmd = () => cmd.with_cwd(paths.js.root, async () => await config.js(argv))
|
let jsCmd = () => cmd.with_cwd(paths.js.root, async () => await config.js(argv))
|
||||||
if (config.parallel) {
|
if (config.parallel) {
|
||||||
let promises = []
|
let promises = []
|
||||||
if (do_common ) { promises.push(commonCmd()) }
|
if (do_common) {
|
||||||
if (do_rust) { promises.push(rustCmd()) }
|
promises.push(commonCmd())
|
||||||
if (do_js) { promises.push(jsCmd()) }
|
}
|
||||||
|
if (do_rust) {
|
||||||
|
promises.push(rustCmd())
|
||||||
|
}
|
||||||
|
if (do_js) {
|
||||||
|
promises.push(jsCmd())
|
||||||
|
}
|
||||||
await Promise.all(promises)
|
await Promise.all(promises)
|
||||||
} else {
|
} else {
|
||||||
if (do_common) { await commonCmd() }
|
if (do_common) {
|
||||||
if (do_rust) { await rustCmd() }
|
await commonCmd()
|
||||||
if (do_js) { await jsCmd() }
|
}
|
||||||
|
if (do_rust) {
|
||||||
|
await rustCmd()
|
||||||
|
}
|
||||||
|
if (do_js) {
|
||||||
|
await jsCmd()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmd.section(command)
|
cmd.section(command)
|
||||||
|
@ -129,8 +129,8 @@ let installClippy = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let installFmt = {
|
let installFmt = {
|
||||||
name: "Install Clippy",
|
name: 'Install Clippy',
|
||||||
run: "rustup component add rustfmt"
|
run: 'rustup component add rustfmt',
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install fixed version to avoid upgrading to a breaking version.
|
// Install fixed version to avoid upgrading to a breaking version.
|
||||||
@ -424,8 +424,7 @@ let assertReleaseDoNotExists = [
|
|||||||
|
|
||||||
assertNoSquashCommitForRelease = {
|
assertNoSquashCommitForRelease = {
|
||||||
name: `Fail if squash commit to the 'unstable' or the 'stable' branch.`,
|
name: `Fail if squash commit to the 'unstable' or the 'stable' branch.`,
|
||||||
run:
|
run: 'if [[ "${{ github.base_ref }}" == "unstable" || "${{ github.base_ref }}" == "stable" ]]; then exit 1; fi',
|
||||||
'if [[ "${{ github.base_ref }}" == "unstable" || "${{ github.base_ref }}" == "stable" ]]; then exit 1; fi',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let assertions = list(
|
let assertions = list(
|
||||||
|
@ -1,72 +1,96 @@
|
|||||||
# Next Release
|
# Next Release
|
||||||
This update contains major performance improvements and exposes new privacy user settings. We will
|
|
||||||
work towards stabilizing it in the next weeks in order to make these updates be shipped in a stable
|
|
||||||
release before the end of the year.
|
|
||||||
|
|
||||||
|
This update contains major performance improvements and exposes new privacy user
|
||||||
|
settings. We will work towards stabilizing it in the next weeks in order to make
|
||||||
|
these updates be shipped in a stable release before the end of the year.
|
||||||
|
|
||||||
<br/>![New Features](/docs/assets/tags/new_features.svg)
|
<br/>![New Features](/docs/assets/tags/new_features.svg)
|
||||||
|
|
||||||
#### Visual Environment
|
#### Visual Environment
|
||||||
- [You can now launch missiles directly from the GUI][79270]. It was technically possible since
|
|
||||||
version 3.0.0-alpha.7, but it was never exposed as a button.
|
- [You can now launch missiles directly from the GUI][79270]. It was technically
|
||||||
- [The graph editor stops shaking and running away when you are pasting JavaScript code][79271].
|
possible since version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||||
|
- [The graph editor stops shaking and running away when you are pasting
|
||||||
|
JavaScript code][79271].
|
||||||
|
|
||||||
#### Runtime
|
#### Runtime
|
||||||
- [The JiT compiler got new optimizations and produces code up to 10x faster than C++][79272].
|
|
||||||
- [You do not need to keep your computer in -20°C to prevent the engine from crashing anymore][79273].
|
- [The JiT compiler got new optimizations and produces code up to 10x faster
|
||||||
|
than C++][79272].
|
||||||
|
- [You do not need to keep your computer in -20°C to prevent the engine from
|
||||||
|
crashing anymore][79273].
|
||||||
|
|
||||||
#### Libraries
|
#### Libraries
|
||||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
|
||||||
- [The Regexp library exposes now methods to test the expressions directly on humans][79275].
|
|
||||||
|
|
||||||
|
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||||
|
- [The Regexp library exposes now methods to test the expressions directly on
|
||||||
|
humans][79275].
|
||||||
|
|
||||||
<br/>![Bug Fixes](/docs/assets/tags/bug_fixes.svg)
|
<br/>![Bug Fixes](/docs/assets/tags/bug_fixes.svg)
|
||||||
|
|
||||||
#### Visual Environment
|
#### Visual Environment
|
||||||
- [You can now launch missiles directly from the GUI][79270]. It was technically possible since
|
|
||||||
version 3.0.0-alpha.7, but it was never exposed as a button.
|
- [You can now launch missiles directly from the GUI][79270]. It was technically
|
||||||
- [The graph editor stops shaking and running away when you are pasting JavaScript code][79271].
|
possible since version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||||
|
- [The graph editor stops shaking and running away when you are pasting
|
||||||
|
JavaScript code][79271].
|
||||||
|
|
||||||
#### Runtime
|
#### Runtime
|
||||||
- [The JiT compiler got new optimizations and produces code up to 10x faster than C++][79272].
|
|
||||||
- [You do not need to keep your computer in -20°C to prevent the engine from crashing anymore][79273].
|
- [The JiT compiler got new optimizations and produces code up to 10x faster
|
||||||
|
than C++][79272].
|
||||||
|
- [You do not need to keep your computer in -20°C to prevent the engine from
|
||||||
|
crashing anymore][79273].
|
||||||
|
|
||||||
#### Libraries
|
#### Libraries
|
||||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
|
||||||
- [The Regexp library exposes now methods to test the expressions directly on humans][79275].
|
|
||||||
|
|
||||||
|
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||||
|
- [The Regexp library exposes now methods to test the expressions directly on
|
||||||
|
humans][79275].
|
||||||
|
|
||||||
<br/>![New Learning Resources](/docs/assets/tags/new_learning_resources.svg)
|
<br/>![New Learning Resources](/docs/assets/tags/new_learning_resources.svg)
|
||||||
|
|
||||||
#### Visual Environment
|
#### Visual Environment
|
||||||
- [You can now launch missiles directly from the GUI][79270]. It was technically possible since
|
|
||||||
version 3.0.0-alpha.7, but it was never exposed as a button.
|
- [You can now launch missiles directly from the GUI][79270]. It was technically
|
||||||
- [The graph editor stops shaking and running away when you are pasting JavaScript code][79271].
|
possible since version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||||
|
- [The graph editor stops shaking and running away when you are pasting
|
||||||
|
JavaScript code][79271].
|
||||||
|
|
||||||
#### Runtime
|
#### Runtime
|
||||||
- [The JiT compiler got new optimizations and produces code up to 10x faster than C++][79272].
|
|
||||||
- [You do not need to keep your computer in -20°C to prevent the engine from crashing anymore][79273].
|
- [The JiT compiler got new optimizations and produces code up to 10x faster
|
||||||
|
than C++][79272].
|
||||||
|
- [You do not need to keep your computer in -20°C to prevent the engine from
|
||||||
|
crashing anymore][79273].
|
||||||
|
|
||||||
#### Libraries
|
#### Libraries
|
||||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
|
||||||
- [The Regexp library exposes now methods to test the expressions directly on humans][79275].
|
|
||||||
|
|
||||||
|
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||||
|
- [The Regexp library exposes now methods to test the expressions directly on
|
||||||
|
humans][79275].
|
||||||
|
|
||||||
<br/>![Release Notes](/docs/assets/tags/release_notes.svg)
|
<br/>![Release Notes](/docs/assets/tags/release_notes.svg)
|
||||||
|
|
||||||
#### Visual Environment
|
#### Visual Environment
|
||||||
- [You can now launch missiles directly from the GUI][79270]. It was technically possible since
|
|
||||||
version 3.0.0-alpha.7, but it was never exposed as a button.
|
- [You can now launch missiles directly from the GUI][79270]. It was technically
|
||||||
- [The graph editor stops shaking and running away when you are pasting JavaScript code][79271].
|
possible since version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||||
|
- [The graph editor stops shaking and running away when you are pasting
|
||||||
|
JavaScript code][79271].
|
||||||
|
|
||||||
#### Runtime
|
#### Runtime
|
||||||
- [The JiT compiler got new optimizations and produces code up to 10x faster than C++][79272].
|
|
||||||
- [You do not need to keep your computer in -20°C to prevent the engine from crashing anymore][79273].
|
- [The JiT compiler got new optimizations and produces code up to 10x faster
|
||||||
|
than C++][79272].
|
||||||
|
- [You do not need to keep your computer in -20°C to prevent the engine from
|
||||||
|
crashing anymore][79273].
|
||||||
|
|
||||||
#### Libraries
|
#### Libraries
|
||||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
|
||||||
- [The Regexp library exposes now methods to test the expressions directly on humans][79275].
|
|
||||||
|
|
||||||
|
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||||
|
- [The Regexp library exposes now methods to test the expressions directly on
|
||||||
|
humans][79275].
|
||||||
|
|
||||||
[79270]: http://github.com/ticket
|
[79270]: http://github.com/ticket
|
||||||
[79271]: http://github.com/ticket
|
[79271]: http://github.com/ticket
|
||||||
@ -74,79 +98,102 @@ release before the end of the year.
|
|||||||
[79273]: http://github.com/ticket
|
[79273]: http://github.com/ticket
|
||||||
[79274]: http://github.com/ticket
|
[79274]: http://github.com/ticket
|
||||||
[79275]: http://github.com/ticket
|
[79275]: http://github.com/ticket
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Enso 47.0.0-alpha.8 (2049-01-22)
|
# Enso 47.0.0-alpha.8 (2049-01-22)
|
||||||
This update contains major performance improvements and exposes new privacy user settings. We will
|
|
||||||
work towards stabilizing it in the next weeks in order to make these updates be shipped in a stable
|
|
||||||
release before the end of the year.
|
|
||||||
|
|
||||||
|
This update contains major performance improvements and exposes new privacy user
|
||||||
|
settings. We will work towards stabilizing it in the next weeks in order to make
|
||||||
|
these updates be shipped in a stable release before the end of the year.
|
||||||
|
|
||||||
<br/>![New Features](/docs/assets/tags/new_features.svg)
|
<br/>![New Features](/docs/assets/tags/new_features.svg)
|
||||||
|
|
||||||
#### Visual Environment
|
#### Visual Environment
|
||||||
- [You can now launch missiles directly from the GUI][79270]. It was technically possible since
|
|
||||||
version 3.0.0-alpha.7, but it was never exposed as a button.
|
- [You can now launch missiles directly from the GUI][79270]. It was technically
|
||||||
- [The graph editor stops shaking and running away when you are pasting JavaScript code][79271].
|
possible since version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||||
|
- [The graph editor stops shaking and running away when you are pasting
|
||||||
|
JavaScript code][79271].
|
||||||
|
|
||||||
#### Runtime
|
#### Runtime
|
||||||
- [The JiT compiler got new optimizations and produces code up to 10x faster than C++][79272].
|
|
||||||
- [You do not need to keep your computer in -20°C to prevent the engine from crashing anymore][79273].
|
- [The JiT compiler got new optimizations and produces code up to 10x faster
|
||||||
|
than C++][79272].
|
||||||
|
- [You do not need to keep your computer in -20°C to prevent the engine from
|
||||||
|
crashing anymore][79273].
|
||||||
|
|
||||||
#### Libraries
|
#### Libraries
|
||||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
|
||||||
- [The Regexp library exposes now methods to test the expressions directly on humans][79275].
|
|
||||||
|
|
||||||
|
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||||
|
- [The Regexp library exposes now methods to test the expressions directly on
|
||||||
|
humans][79275].
|
||||||
|
|
||||||
<br/>![Bug Fixes](/docs/assets/tags/bug_fixes.svg)
|
<br/>![Bug Fixes](/docs/assets/tags/bug_fixes.svg)
|
||||||
|
|
||||||
#### Visual Environment
|
#### Visual Environment
|
||||||
- [You can now launch missiles directly from the GUI][79270]. It was technically possible since
|
|
||||||
version 3.0.0-alpha.7, but it was never exposed as a button.
|
- [You can now launch missiles directly from the GUI][79270]. It was technically
|
||||||
- [The graph editor stops shaking and running away when you are pasting JavaScript code][79271].
|
possible since version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||||
|
- [The graph editor stops shaking and running away when you are pasting
|
||||||
|
JavaScript code][79271].
|
||||||
|
|
||||||
#### Runtime
|
#### Runtime
|
||||||
- [The JiT compiler got new optimizations and produces code up to 10x faster than C++][79272].
|
|
||||||
- [You do not need to keep your computer in -20°C to prevent the engine from crashing anymore][79273].
|
- [The JiT compiler got new optimizations and produces code up to 10x faster
|
||||||
|
than C++][79272].
|
||||||
|
- [You do not need to keep your computer in -20°C to prevent the engine from
|
||||||
|
crashing anymore][79273].
|
||||||
|
|
||||||
#### Libraries
|
#### Libraries
|
||||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
|
||||||
- [The Regexp library exposes now methods to test the expressions directly on humans][79275].
|
|
||||||
|
|
||||||
|
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||||
|
- [The Regexp library exposes now methods to test the expressions directly on
|
||||||
|
humans][79275].
|
||||||
|
|
||||||
<br/>![New Learning Resources](/docs/assets/tags/new_learning_resources.svg)
|
<br/>![New Learning Resources](/docs/assets/tags/new_learning_resources.svg)
|
||||||
|
|
||||||
#### Visual Environment
|
#### Visual Environment
|
||||||
- [You can now launch missiles directly from the GUI][79270]. It was technically possible since
|
|
||||||
version 3.0.0-alpha.7, but it was never exposed as a button.
|
- [You can now launch missiles directly from the GUI][79270]. It was technically
|
||||||
- [The graph editor stops shaking and running away when you are pasting JavaScript code][79271].
|
possible since version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||||
|
- [The graph editor stops shaking and running away when you are pasting
|
||||||
|
JavaScript code][79271].
|
||||||
|
|
||||||
#### Runtime
|
#### Runtime
|
||||||
- [The JiT compiler got new optimizations and produces code up to 10x faster than C++][79272].
|
|
||||||
- [You do not need to keep your computer in -20°C to prevent the engine from crashing anymore][79273].
|
- [The JiT compiler got new optimizations and produces code up to 10x faster
|
||||||
|
than C++][79272].
|
||||||
|
- [You do not need to keep your computer in -20°C to prevent the engine from
|
||||||
|
crashing anymore][79273].
|
||||||
|
|
||||||
#### Libraries
|
#### Libraries
|
||||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
|
||||||
- [The Regexp library exposes now methods to test the expressions directly on humans][79275].
|
|
||||||
|
|
||||||
|
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||||
|
- [The Regexp library exposes now methods to test the expressions directly on
|
||||||
|
humans][79275].
|
||||||
|
|
||||||
<br/>![Release Notes](/docs/assets/tags/release_notes.svg)
|
<br/>![Release Notes](/docs/assets/tags/release_notes.svg)
|
||||||
|
|
||||||
#### Visual Environment
|
#### Visual Environment
|
||||||
- [You can now launch missiles directly from the GUI][79270]. It was technically possible since
|
|
||||||
version 3.0.0-alpha.7, but it was never exposed as a button.
|
- [You can now launch missiles directly from the GUI][79270]. It was technically
|
||||||
- [The graph editor stops shaking and running away when you are pasting JavaScript code][79271].
|
possible since version 3.0.0-alpha.7, but it was never exposed as a button.
|
||||||
|
- [The graph editor stops shaking and running away when you are pasting
|
||||||
|
JavaScript code][79271].
|
||||||
|
|
||||||
#### Runtime
|
#### Runtime
|
||||||
- [The JiT compiler got new optimizations and produces code up to 10x faster than C++][79272].
|
|
||||||
- [You do not need to keep your computer in -20°C to prevent the engine from crashing anymore][79273].
|
- [The JiT compiler got new optimizations and produces code up to 10x faster
|
||||||
|
than C++][79272].
|
||||||
|
- [You do not need to keep your computer in -20°C to prevent the engine from
|
||||||
|
crashing anymore][79273].
|
||||||
|
|
||||||
#### Libraries
|
#### Libraries
|
||||||
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
|
||||||
- [The Regexp library exposes now methods to test the expressions directly on humans][79275].
|
|
||||||
|
|
||||||
|
- [The new JSON library allows you to parse 2Gb files in 50ms][79274].
|
||||||
|
- [The Regexp library exposes now methods to test the expressions directly on
|
||||||
|
humans][79275].
|
||||||
|
|
||||||
[79270]: http://github.com/ticket
|
[79270]: http://github.com/ticket
|
||||||
[79271]: http://github.com/ticket
|
[79271]: http://github.com/ticket
|
||||||
@ -154,9 +201,9 @@ release before the end of the year.
|
|||||||
[79273]: http://github.com/ticket
|
[79273]: http://github.com/ticket
|
||||||
[79274]: http://github.com/ticket
|
[79274]: http://github.com/ticket
|
||||||
[79275]: http://github.com/ticket
|
[79275]: http://github.com/ticket
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Enso 47.0.0-alpha.7 (2049-01-07)
|
# Enso 47.0.0-alpha.7 (2049-01-07)
|
||||||
|
|
||||||
...
|
...
|
||||||
|
@ -7,7 +7,7 @@ tags: [doc-index]
|
|||||||
|
|
||||||
# Enso IDE documentation
|
# Enso IDE documentation
|
||||||
|
|
||||||
* [**Contributing guidelines**](./contributing/README.md) - helpful
|
- [**Contributing guidelines**](./contributing/README.md) - helpful instructions
|
||||||
instructions for anyone who wants to contribute.
|
for anyone who wants to contribute.
|
||||||
* [**Product specification**](./product/README.md) - a specification from
|
- [**Product specification**](./product/README.md) - a specification from the
|
||||||
the user perspective.
|
user perspective.
|
||||||
|
@ -7,8 +7,9 @@ tags: [contributing]
|
|||||||
|
|
||||||
# Enso IDE Contributing Documentation
|
# Enso IDE Contributing Documentation
|
||||||
|
|
||||||
This directory contains helpful resources for anyone who wants to start Enso IDE development. The
|
This directory contains helpful resources for anyone who wants to start Enso IDE
|
||||||
main guideline is available [here](../CONTRIBUTING.md).
|
development. The main guideline is available [here](../CONTRIBUTING.md).
|
||||||
|
|
||||||
* [**Enso Team Process**](./process.md) - the development cycle in the core Enso IDE team.
|
- [**Enso Team Process**](./process.md) - the development cycle in the core Enso
|
||||||
* [**Style Guide**](./style-guide.md) - Our coding standards.
|
IDE team.
|
||||||
|
- [**Style Guide**](./style-guide.md) - Our coding standards.
|
||||||
|
@ -7,16 +7,21 @@ tags: [contributing]
|
|||||||
|
|
||||||
# Enso IDE Team Process
|
# Enso IDE Team Process
|
||||||
|
|
||||||
This document specify our core team workflow, described as a lifecycle of a task:
|
This document specify our core team workflow, described as a lifecycle of a
|
||||||
|
task:
|
||||||
|
|
||||||
* A newly created task should be appropriately described, but not estimated yet - it will be during
|
- A newly created task should be appropriately described, but not estimated
|
||||||
Backlog Refinement meeting. The task is put in "New Tasks" column.
|
yet - it will be during Backlog Refinement meeting. The task is put in "New
|
||||||
* At the beginning of the sprint team leads put to the "To Refine" column all tasks which will be
|
Tasks" column.
|
||||||
refined during the next Backlog refinement.
|
- At the beginning of the sprint team leads put to the "To Refine" column all
|
||||||
* Each team member should read the descriptions of tasks in "To Refine" column and ask questions
|
tasks which will be refined during the next Backlog refinement.
|
||||||
and raise all concerns. All the conversation should be recorded in the issue's comments.
|
- Each team member should read the descriptions of tasks in "To Refine" column
|
||||||
* During Backlog Refinement we confirm that the task description is clear and estimate it. The
|
and ask questions and raise all concerns. All the conversation should be
|
||||||
estimate is expressed in work days of one person, and should include the review process. The task
|
recorded in the issue's comments.
|
||||||
is then moved to the "Backlog" column. If it turns out that there is no agreement about the task's
|
- During Backlog Refinement we confirm that the task description is clear and
|
||||||
scope and estimation, it may be postponed to the next Backlog Refinement.
|
estimate it. The estimate is expressed in work days of one person, and should
|
||||||
* During Planning meeting the team decides which tasks are took into next sprint and assign them.
|
include the review process. The task is then moved to the "Backlog" column. If
|
||||||
|
it turns out that there is no agreement about the task's scope and estimation,
|
||||||
|
it may be postponed to the next Backlog Refinement.
|
||||||
|
- During Planning meeting the team decides which tasks are took into next sprint
|
||||||
|
and assign them.
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
# Repository Structure Overview
|
# Repository Structure Overview
|
||||||
|
|
||||||
* `build` - Helper JS scripts used by `run` script in the main directory.
|
- `build` - Helper JS scripts used by `run` script in the main directory.
|
||||||
* `docs` - Documentation.
|
- `docs` - Documentation.
|
||||||
* `src/js` - The JS part of IDE application.
|
- `src/js` - The JS part of IDE application.
|
||||||
* `src/rust` - All Rust crates.
|
- `src/rust` - All Rust crates.
|
||||||
|
|
||||||
## Crates
|
## Crates
|
||||||
|
|
||||||
@ -11,15 +11,15 @@ The crates structure is currently in process of refactoring, and there are still
|
|||||||
places where code does not fit the crate it is placed. The work is tracked in
|
places where code does not fit the crate it is placed. The work is tracked in
|
||||||
#448 epic.
|
#448 epic.
|
||||||
|
|
||||||
The detailed description of each crate is placed in its documentation at top
|
The detailed description of each crate is placed in its documentation at top of
|
||||||
of its `lib.rs` file.
|
its `lib.rs` file.
|
||||||
|
|
||||||
There are two main parts of our codebase: **EnsoGL library** and the **Enso
|
There are two main parts of our codebase: **EnsoGL library** and the **Enso IDE
|
||||||
IDE application**. The crates used in common by those parts are put in `src
|
application**. The crates used in common by those parts are put in
|
||||||
/rust/lib`, and should be documented at the top of their `lib.rs` file.
|
`src /rust/lib`, and should be documented at the top of their `lib.rs` file.
|
||||||
|
|
||||||
Other crates usually contains code shared by those two. The one noteworthy
|
Other crates usually contains code shared by those two. The one noteworthy is
|
||||||
is the **prelude** crate (`src/rust/prelude`) which gathers the commonly used
|
the **prelude** crate (`src/rust/prelude`) which gathers the commonly used
|
||||||
imports across all crates in our repository.
|
imports across all crates in our repository.
|
||||||
|
|
||||||
### EnsoGL (`src/rust/ensogl`)
|
### EnsoGL (`src/rust/ensogl`)
|
||||||
@ -28,16 +28,16 @@ EnsoGL is a library providing fast 2D vector rendering engine with a rich set of
|
|||||||
primitives and high-level GUI components. Its structure will be described after
|
primitives and high-level GUI components. Its structure will be described after
|
||||||
the planned refactoring in #598.
|
the planned refactoring in #598.
|
||||||
|
|
||||||
|
|
||||||
### Enso IDE (`src/rust/ide`)
|
### Enso IDE (`src/rust/ide`)
|
||||||
|
|
||||||
The Enso IDE crate contains entry point function of application, and
|
The Enso IDE crate contains entry point function of application, and integrates
|
||||||
integrates two main parts of it:
|
two main parts of it:
|
||||||
* IDE View (`src/rust/ide/lib/view`) - The visual part of IDE. It contains
|
|
||||||
no logic and connections to backend - instead it delivers FRP endpoints to
|
- IDE View (`src/rust/ide/lib/view`) - The visual part of IDE. It contains no
|
||||||
be integrated with controllers. That design allow us to measure of vis-part
|
logic and connections to backend - instead it delivers FRP endpoints to be
|
||||||
only performance.
|
integrated with controllers. That design allow us to measure of vis-part only
|
||||||
* IDE Controllers (`src/rust/ide/lib/controller`) - The logic part of IDE,
|
performance.
|
||||||
that is synchronizing graph a text and communication with Engine. It
|
- IDE Controllers (`src/rust/ide/lib/controller`) - The logic part of IDE, that
|
||||||
should not know anything about visual part. In the future we may consider
|
is synchronizing graph a text and communication with Engine. It should not
|
||||||
creating some sort of CLI for automatic integration tests.
|
know anything about visual part. In the future we may consider creating some
|
||||||
|
sort of CLI for automatic integration tests.
|
||||||
|
@ -4,16 +4,16 @@ layout: style-guide title: Rust Style Guide category: style-guide tags: [style-g
|
|||||||
|
|
||||||
# Rust Style Guide
|
# Rust Style Guide
|
||||||
|
|
||||||
We are using `rustfmt` for the basic formatting of our rust code, which is also checked on CI. We
|
We are using `rustfmt` for the basic formatting of our rust code, which is also
|
||||||
have some additional guidelines for imports, naming, sections within files and naming which are
|
checked on CI. We have some additional guidelines for imports, naming, sections
|
||||||
documented here.
|
within files and naming which are documented here.
|
||||||
|
|
||||||
## Styling rules
|
## Styling rules
|
||||||
|
|
||||||
### Imports
|
### Imports
|
||||||
|
|
||||||
Imports should be divided into 4 groups separated by blank lines. Items in the groups should be
|
Imports should be divided into 4 groups separated by blank lines. Items in the
|
||||||
sorted alphabetically.
|
groups should be sorted alphabetically.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
// Group 1: sub-module definitions.
|
// Group 1: sub-module definitions.
|
||||||
@ -40,12 +40,14 @@ use nalgebra::Vector3;
|
|||||||
|
|
||||||
### Sections
|
### Sections
|
||||||
|
|
||||||
Source files should be divided into sections. Section headers should be placed before each new "
|
Source files should be divided into sections. Section headers should be placed
|
||||||
concept" defined in a file. By "concept" we normally mean a structure with related implementations.
|
before each new " concept" defined in a file. By "concept" we normally mean a
|
||||||
In case related implementations use some helper structs with very small implementations, these
|
structure with related implementations. In case related implementations use some
|
||||||
helper structs may be defined in the same section. Moreover, the code in each section should be
|
helper structs with very small implementations, these helper structs may be
|
||||||
divided into sub-sections, grouping related definitions. At least one section should be defined in a
|
defined in the same section. Moreover, the code in each section should be
|
||||||
file (if there is at least one struct definition as well). For example:
|
divided into sub-sections, grouping related definitions. At least one section
|
||||||
|
should be defined in a file (if there is at least one struct definition as
|
||||||
|
well). For example:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
// =================
|
// =================
|
||||||
@ -141,10 +143,11 @@ impl<OnChange: Callback0> HierarchicalTransform<OnChange> {
|
|||||||
|
|
||||||
### Multiline Expressions
|
### Multiline Expressions
|
||||||
|
|
||||||
Most (preferably all) expressions should be single line. Multiline expressions are hard to read and
|
Most (preferably all) expressions should be single line. Multiline expressions
|
||||||
introduce noise in the code. Often, it is also an indicator of code that is not properly refactored.
|
are hard to read and introduce noise in the code. Often, it is also an indicator
|
||||||
Try to refactor parts of multiline expressions to well-named variables, and divide them to several
|
of code that is not properly refactored. Try to refactor parts of multiline
|
||||||
single-line expressions.
|
expressions to well-named variables, and divide them to several single-line
|
||||||
|
expressions.
|
||||||
|
|
||||||
Example of poorly formatted code:
|
Example of poorly formatted code:
|
||||||
|
|
||||||
@ -172,9 +175,9 @@ pub fn new() -> Self {
|
|||||||
|
|
||||||
### Getters and Setters
|
### Getters and Setters
|
||||||
|
|
||||||
Getters do not have the `get_` prefix, while setters do. If a setter is provided (method with
|
Getters do not have the `get_` prefix, while setters do. If a setter is provided
|
||||||
the `set_` prefix), a `mut` accessor should be provided as well. The correct way of defining getters
|
(method with the `set_` prefix), a `mut` accessor should be provided as well.
|
||||||
and setters is presented below:
|
The correct way of defining getters and setters is presented below:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
fn field(&self) -> &Type {
|
fn field(&self) -> &Type {
|
||||||
@ -192,13 +195,14 @@ fn set_field(&mut self, val: Type) {
|
|||||||
|
|
||||||
### Trait exporting
|
### Trait exporting
|
||||||
|
|
||||||
All names should be designed to be used in a qualified fashion. However, this makes one situation
|
All names should be designed to be used in a qualified fashion. However, this
|
||||||
tricky. In order to use methods defined in a trait, it has to be in scope. Consider a trait
|
makes one situation tricky. In order to use methods defined in a trait, it has
|
||||||
`display::Object`. We want to use it as function bound like `fn test<T:display::Object>(t:T) {...}`,
|
to be in scope. Consider a trait `display::Object`. We want to use it as
|
||||||
and we also want to use methods defined in this trait (so it has to be in scope). In such a case,
|
function bound like `fn test<T:display::Object>(t:T) {...}`, and we also want to
|
||||||
`Clippy` warns that `display::Object` is unnecessary qualification and could be replaced simply by
|
use methods defined in this trait (so it has to be in scope). In such a case,
|
||||||
`Object`, which is not what we want. Thus, in order to export traits, please always rename them
|
`Clippy` warns that `display::Object` is unnecessary qualification and could be
|
||||||
using the following convention:
|
replaced simply by `Object`, which is not what we want. Thus, in order to export
|
||||||
|
traits, please always rename them using the following convention:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
/// Common traits.
|
/// Common traits.
|
||||||
@ -209,5 +213,6 @@ pub mod traits {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Having such a definition, we can import traits to scope using `use display::object::traits::*`, and
|
Having such a definition, we can import traits to scope using
|
||||||
we would not have any warning about unnecessary qualification anymore.
|
`use display::object::traits::*`, and we would not have any warning about
|
||||||
|
unnecessary qualification anymore.
|
||||||
|
@ -10,6 +10,6 @@ This section contains detailed specification of Enso IDE from the user
|
|||||||
perspective. The implementation is documented in rust code and in the crate's
|
perspective. The implementation is documented in rust code and in the crate's
|
||||||
`docs` directory.
|
`docs` directory.
|
||||||
|
|
||||||
* [**List of Shortcuts**](./shortcuts.md)
|
- [**List of Shortcuts**](./shortcuts.md)
|
||||||
* [**Visualizations**](./visualizations.md)
|
- [**Visualizations**](./visualizations.md)
|
||||||
* [**Searcher in Graph Editor**](./searcher.md)
|
- [**Searcher in Graph Editor**](./searcher.md)
|
||||||
|
@ -10,12 +10,13 @@ tags: [product]
|
|||||||
### Behaviour
|
### Behaviour
|
||||||
|
|
||||||
The Searcher Panel can be brought to the screen in two different ways:
|
The Searcher Panel can be brought to the screen in two different ways:
|
||||||
* when user starts to edit node's expression - the node becomes Searcher input
|
|
||||||
|
- when user starts to edit node's expression - the node becomes Searcher input
|
||||||
and panel appears below,
|
and panel appears below,
|
||||||
* when user press tab with mouse over Graph Editor Panel - the new Searcher
|
- when user press tab with mouse over Graph Editor Panel - the new Searcher
|
||||||
input appears with Searcher panel below. Additionally, if there is exactly
|
input appears with Searcher panel below. Additionally, if there is exactly one
|
||||||
one node selected, the connection is displayed between the selected node
|
node selected, the connection is displayed between the selected node and the
|
||||||
and the Searcher input.
|
Searcher input.
|
||||||
|
|
||||||
### Suggestion of Node Expressions
|
### Suggestion of Node Expressions
|
||||||
|
|
||||||
@ -27,7 +28,7 @@ connected to selection. The current implementation can be found in
|
|||||||
|
|
||||||
### Suggestion Database
|
### Suggestion Database
|
||||||
|
|
||||||
The `search/completion` method of Language Server returns a list of keys to
|
The `search/completion` method of Language Server returns a list of keys to the
|
||||||
the Suggestion Database instead of the whole entries. The database is
|
Suggestion Database instead of the whole entries. The database is retrieved by
|
||||||
retrieved by IDE on Project opening, and keeps it up to date. The Database
|
IDE on Project opening, and keeps it up to date. The Database is implemented in
|
||||||
is implemented in `ide::model::suggestion_database` module.
|
`ide::model::suggestion_database` module.
|
||||||
|
@ -8,29 +8,34 @@ tags: [product,ui]
|
|||||||
## General Assumptions
|
## General Assumptions
|
||||||
|
|
||||||
#### The <kbd>meta</kbd> key.
|
#### The <kbd>meta</kbd> key.
|
||||||
The <kbd>meta</kbd> key was introduced to make the shortcuts consistent across platforms.
|
|
||||||
It is defined as <kbd>command</kbd> on macOS, and as <kbd>ctrl</kbd> on Windows and Linux.
|
The <kbd>meta</kbd> key was introduced to make the shortcuts consistent across
|
||||||
|
platforms. It is defined as <kbd>command</kbd> on macOS, and as <kbd>ctrl</kbd>
|
||||||
|
on Windows and Linux.
|
||||||
|
|
||||||
#### Keyboard-only Workflow
|
#### Keyboard-only Workflow
|
||||||
The GUI and all shortcuts were designed in a way to allow both efficient mouse-only as well as
|
|
||||||
keyboard-only workflows. In most cases, there is a relation between mouse and keyboard shortcuts,
|
The GUI and all shortcuts were designed in a way to allow both efficient
|
||||||
namely, the `left-mouse-button` corresponds to `enter`. For example, stepping into a node is done
|
mouse-only as well as keyboard-only workflows. In most cases, there is a
|
||||||
by either double clicking the node, or just pressing the enter key.
|
relation between mouse and keyboard shortcuts, namely, the `left-mouse-button`
|
||||||
|
corresponds to `enter`. For example, stepping into a node is done by either
|
||||||
|
double clicking the node, or just pressing the enter key.
|
||||||
|
|
||||||
#### Missing / not working shortcuts
|
#### Missing / not working shortcuts
|
||||||
Some of the shortcuts presented below are marked with the :warning: icon, which means, that they are
|
|
||||||
planned, but not yet implemented. Feel free to contribute and help us implement them!
|
|
||||||
|
|
||||||
Shortcuts marked with the :bangbang: icon should work, but are reported to be broken and require
|
|
||||||
further investigation.
|
|
||||||
|
|
||||||
|
Some of the shortcuts presented below are marked with the :warning: icon, which
|
||||||
|
means, that they are planned, but not yet implemented. Feel free to contribute
|
||||||
|
and help us implement them!
|
||||||
|
|
||||||
|
Shortcuts marked with the :bangbang: icon should work, but are reported to be
|
||||||
|
broken and require further investigation.
|
||||||
|
|
||||||
## Graph Editor
|
## Graph Editor
|
||||||
|
|
||||||
#### General Shortcuts
|
#### General Shortcuts
|
||||||
|
|
||||||
| Shortcut | Action |
|
| Shortcut | Action |
|
||||||
| -------- | ------ |
|
| ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| <kbd>cmd</kbd>+<kbd>alt</kbd>+<kbd>shift</kbd>+<kbd>t</kbd> | Toggle light/dark application style. Currently doesn't work properly, as the Theme Switcher is not created yet. (https://github.com/enso-org/ide/issues/795) |
|
| <kbd>cmd</kbd>+<kbd>alt</kbd>+<kbd>shift</kbd>+<kbd>t</kbd> | Toggle light/dark application style. Currently doesn't work properly, as the Theme Switcher is not created yet. (https://github.com/enso-org/ide/issues/795) |
|
||||||
| <kbd>ctrl</kbd>+<kbd>`</kbd> | Show Code Editor. Please note that the Code Editor implementation is in a very early stage and you should not use it. Even just openning it can cause errors in the IDE. Do not try using the graph editor while having the code editor tab openned. |
|
| <kbd>ctrl</kbd>+<kbd>`</kbd> | Show Code Editor. Please note that the Code Editor implementation is in a very early stage and you should not use it. Even just openning it can cause errors in the IDE. Do not try using the graph editor while having the code editor tab openned. |
|
||||||
| <kbd>cmd</kbd>+<kbd>o</kbd> | Open project |
|
| <kbd>cmd</kbd>+<kbd>o</kbd> | Open project |
|
||||||
@ -43,36 +48,36 @@ further investigation.
|
|||||||
| <kbd>ctrl</kbd>+<kbd>w</kbd> | Close the application (Windows, Linux) |
|
| <kbd>ctrl</kbd>+<kbd>w</kbd> | Close the application (Windows, Linux) |
|
||||||
| :warning: <kbd>ctrl</kbd>+<kbd>p</kbd> | Toggle profiling mode |
|
| :warning: <kbd>ctrl</kbd>+<kbd>p</kbd> | Toggle profiling mode |
|
||||||
|
|
||||||
|
|
||||||
#### Navigation
|
#### Navigation
|
||||||
| Shortcut | Action |
|
|
||||||
| -------- | ------ |
|
|
||||||
| Drag gesture (two fingers) | Pan the scene.
|
|
||||||
| Pinch gesture (two fingers) | Zoom the scene.
|
|
||||||
| <kbd>MMB</kbd> drag | Pan the scene.
|
|
||||||
| <kbd>RMB</kbd> drag | Zoom the scene.
|
|
||||||
| <kbd>LMB</kbd> double press node name | Step into the node.
|
|
||||||
| :warning: <kbd>LMB</kbd> double press background | Step out of the current node.
|
|
||||||
| <kbd>enter</kbd> | Step in the last selected node.
|
|
||||||
| <kbd>alt</kbd>+<kbd>enter</kbd> | Step out of the current node.
|
|
||||||
|
|
||||||
|
| Shortcut | Action |
|
||||||
|
| ------------------------------------------------ | ------------------------------- |
|
||||||
|
| Drag gesture (two fingers) | Pan the scene. |
|
||||||
|
| Pinch gesture (two fingers) | Zoom the scene. |
|
||||||
|
| <kbd>MMB</kbd> drag | Pan the scene. |
|
||||||
|
| <kbd>RMB</kbd> drag | Zoom the scene. |
|
||||||
|
| <kbd>LMB</kbd> double press node name | Step into the node. |
|
||||||
|
| :warning: <kbd>LMB</kbd> double press background | Step out of the current node. |
|
||||||
|
| <kbd>enter</kbd> | Step in the last selected node. |
|
||||||
|
| <kbd>alt</kbd>+<kbd>enter</kbd> | Step out of the current node. |
|
||||||
|
|
||||||
#### Node Layout
|
#### Node Layout
|
||||||
|
|
||||||
| Shortcut | Action |
|
| Shortcut | Action |
|
||||||
| -------- | ------ |
|
| ------------------------------------------ | ----------------------------------------------------------------- |
|
||||||
| <kbd>LMB</kbd> drag non-selected node name | Move the node to new position (dragging do not modify selection). |
|
| <kbd>LMB</kbd> drag non-selected node name | Move the node to new position (dragging do not modify selection). |
|
||||||
| <kbd>LMB</kbd> drag selected node name | Move all selected nodes the node to new positions. |
|
| <kbd>LMB</kbd> drag selected node name | Move all selected nodes the node to new positions. |
|
||||||
|
|
||||||
|
|
||||||
#### Node Selection
|
#### Node Selection
|
||||||
|
|
||||||
| Shortcut | Action |
|
| Shortcut | Action |
|
||||||
| --- | --- |
|
| ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
|
||||||
| <kbd>LMB</kbd> click node name | Deselect all nodes. Select the target node. |
|
| <kbd>LMB</kbd> click node name | Deselect all nodes. Select the target node. |
|
||||||
| <kbd>LMB</kbd> click background | Deselect all nodes. |
|
| <kbd>LMB</kbd> click background | Deselect all nodes. |
|
||||||
| :warning: <kbd>LMB</kbd> drag background | Select nodes using selection-box. |
|
| :warning: <kbd>LMB</kbd> drag background | Select nodes using selection-box. |
|
||||||
| <kbd>shift</kbd> + <kbd>LMB</kbd> click node name | Add / remove node to the selection group. |
|
| <kbd>shift</kbd> + <kbd>LMB</kbd> click node name | Add / remove node to the selection group. |
|
||||||
| :warning: <kbd>shift</kbd> + <kbd>LMB</kbd> drag background | Add / remove nodes to the selection group. |
|
| :warning: <kbd>shift</kbd> + <kbd>LMB</kbd> drag background | Add / remove nodes to the selection group. |
|
||||||
| :warning: <kbd>*-arrow</kbd> | Select node on the right side of the newest selected node. |
|
| :warning: <kbd>\*-arrow</kbd> | Select node on the right side of the newest selected node. |
|
||||||
| :warning: <kbd>cmd</kbd> + <kbd>a</kbd> | Select all nodes. |
|
| :warning: <kbd>cmd</kbd> + <kbd>a</kbd> | Select all nodes. |
|
||||||
| :warning: <kbd>escape</kbd> | Deselect all nodes (if not in a mode, like edit mode). |
|
| :warning: <kbd>escape</kbd> | Deselect all nodes (if not in a mode, like edit mode). |
|
||||||
| <kbd>shift</kbd> + <kbd>ctrl</kbd> + <kbd>LMB</kbd> click node name | Add node to the selection group. |
|
| <kbd>shift</kbd> + <kbd>ctrl</kbd> + <kbd>LMB</kbd> click node name | Add node to the selection group. |
|
||||||
@ -82,10 +87,10 @@ further investigation.
|
|||||||
| <kbd>shift</kbd> + <kbd>ctrl</kbd> + <kbd>alt</kbd> + <kbd>LMB</kbd> click node name | Inverse node selection. |
|
| <kbd>shift</kbd> + <kbd>ctrl</kbd> + <kbd>alt</kbd> + <kbd>LMB</kbd> click node name | Inverse node selection. |
|
||||||
| :warning: <kbd>shift</kbd> + <kbd>ctrl</kbd> + <kbd>alt</kbd> + <kbd>LMB</kbd> drag background | Inverse nodes selection. |
|
| :warning: <kbd>shift</kbd> + <kbd>ctrl</kbd> + <kbd>alt</kbd> + <kbd>LMB</kbd> drag background | Inverse nodes selection. |
|
||||||
|
|
||||||
|
|
||||||
#### Node Editing
|
#### Node Editing
|
||||||
|
|
||||||
| Shortcut | Action |
|
| Shortcut | Action |
|
||||||
| -------- | ------ |
|
| ------------------------------------------------ | -------------------------------------------- |
|
||||||
| <kbd>tab</kbd> | Show / hide node searcher. |
|
| <kbd>tab</kbd> | Show / hide node searcher. |
|
||||||
| <kbd>backspace</kbd> or <kbd>delete</kbd> | Remove selected nodes. |
|
| <kbd>backspace</kbd> or <kbd>delete</kbd> | Remove selected nodes. |
|
||||||
| <kbd>cmd</kbd>+<kbd>g</kbd> | Collapse (group) selected nodes. |
|
| <kbd>cmd</kbd>+<kbd>g</kbd> | Collapse (group) selected nodes. |
|
||||||
@ -93,27 +98,27 @@ further investigation.
|
|||||||
| <kbd>meta</kbd>+<kbd>enter</kbd> | Start editing node expression. |
|
| <kbd>meta</kbd>+<kbd>enter</kbd> | Start editing node expression. |
|
||||||
| <kbd>enter</kbd> or <kbd>LMB</kbd> on suggestion | Pick selected suggestion and commit editing. |
|
| <kbd>enter</kbd> or <kbd>LMB</kbd> on suggestion | Pick selected suggestion and commit editing. |
|
||||||
|
|
||||||
|
|
||||||
#### Visualization
|
#### Visualization
|
||||||
|
|
||||||
| Shortcut | Action |
|
| Shortcut | Action |
|
||||||
| -------- | ------ |
|
| ----------------------------------------- | ------------------------------------------------------------- |
|
||||||
| <kbd>space</kbd> | Toggle visualization visibility of the selected node. |
|
| <kbd>space</kbd> | Toggle visualization visibility of the selected node. |
|
||||||
| <kbd>space</kbd> hold | Preview visualization of the selected node (hide on release). |
|
| <kbd>space</kbd> hold | Preview visualization of the selected node (hide on release). |
|
||||||
| :warning: <kbd>space</kbd> double press | Toggle visualization fullscreen mode |
|
| :warning: <kbd>space</kbd> double press | Toggle visualization fullscreen mode |
|
||||||
| <kbd>ctrl</kbd> + <kbd>space</kbd> | Cycle visualizations of the selected node. |
|
| <kbd>ctrl</kbd> + <kbd>space</kbd> | Cycle visualizations of the selected node. |
|
||||||
| :bangbang: <kbd>cmd</kbd> + <kbd>\\</kbd> | Toggle documentation view visibility |
|
| :bangbang: <kbd>cmd</kbd> + <kbd>\\</kbd> | Toggle documentation view visibility |
|
||||||
|
|
||||||
|
|
||||||
#### Visualizations Implementations
|
#### Visualizations Implementations
|
||||||
|
|
||||||
| Shortcut | Action |
|
| Shortcut | Action |
|
||||||
| -------- | ------ |
|
| ------------------------------ | -------------------------------------------------- |
|
||||||
| <kbd>meta</kbd> + <kbd>a</kbd> | Show all points if available in visualization. |
|
| <kbd>meta</kbd> + <kbd>a</kbd> | Show all points if available in visualization. |
|
||||||
| <kbd>meta</kbd> + <kbd>z</kbd> | Zoom into selection if available in visualization. |
|
| <kbd>meta</kbd> + <kbd>z</kbd> | Zoom into selection if available in visualization. |
|
||||||
|
|
||||||
|
|
||||||
#### Debug
|
#### Debug
|
||||||
|
|
||||||
| Shortcut | Action |
|
| Shortcut | Action |
|
||||||
| -------- | ------ |
|
| ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
| <kbd>ctrl</kbd> + <kbd>alt</kbd> + <kbd>shift</kbd> + <kbd>i</kbd> | Open the developer console. |
|
| <kbd>ctrl</kbd> + <kbd>alt</kbd> + <kbd>shift</kbd> + <kbd>i</kbd> | Open the developer console. |
|
||||||
| <kbd>ctrl</kbd> + <kbd>alt</kbd> + <kbd>shift</kbd> + <kbd>r</kbd> | Reload the visual interface. |
|
| <kbd>ctrl</kbd> + <kbd>alt</kbd> + <kbd>shift</kbd> + <kbd>r</kbd> | Reload the visual interface. |
|
||||||
| <kbd>ctrl</kbd> + <kbd>alt</kbd> + <kbd>0 - 10</kbd> | Switch between debug rendering modes (0 is the normal mode). |
|
| <kbd>ctrl</kbd> + <kbd>alt</kbd> + <kbd>0 - 10</kbd> | Switch between debug rendering modes (0 is the normal mode). |
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
# What is a Self-XSS scam?
|
# What is a Self-XSS scam?
|
||||||
|
|
||||||
A Self-XSS scam tricks you into compromising your account by claiming to provide a way to log into
|
A Self-XSS scam tricks you into compromising your account by claiming to provide
|
||||||
someone else's account, or some other kind of reward, after pasting a special code or link into your
|
a way to log into someone else's account, or some other kind of reward, after
|
||||||
web browser. Never copy and paste scripts into the developer console.
|
pasting a special code or link into your web browser. Never copy and paste
|
||||||
|
scripts into the developer console.
|
||||||
|
|
||||||
This kind of scam can often include malicious software and can give the attacker access to your
|
This kind of scam can often include malicious software and can give the attacker
|
||||||
account and your data. Read the following article to learn more:
|
access to your account and your data. Read the following article to learn more:
|
||||||
https://en.wikipedia.org/wiki/Self-XSS.
|
https://en.wikipedia.org/wiki/Self-XSS.
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
"hoist": true
|
"hoist": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages": [
|
"packages": ["lib/*"],
|
||||||
"lib/*"
|
|
||||||
],
|
|
||||||
"version": "0.0.0"
|
"version": "0.0.0"
|
||||||
}
|
}
|
||||||
|
@ -12,27 +12,27 @@ function get_build_config() {
|
|||||||
const build = get_build_config()
|
const build = get_build_config()
|
||||||
|
|
||||||
let config = {
|
let config = {
|
||||||
name: "Enso",
|
name: 'Enso',
|
||||||
description: "Enso Data Processing Environment.",
|
description: 'Enso Data Processing Environment.',
|
||||||
main: "index.js",
|
main: 'index.js',
|
||||||
|
|
||||||
dependencies: {
|
dependencies: {
|
||||||
"create-servers": "^3.1.0",
|
'create-servers': '^3.1.0',
|
||||||
"electron-is-dev": "^1.1.0",
|
'electron-is-dev': '^1.1.0',
|
||||||
"enso-studio-common": "1.0.0",
|
'enso-studio-common': '1.0.0',
|
||||||
"enso-studio-content": "1.0.0",
|
'enso-studio-content': '1.0.0',
|
||||||
"enso-studio-icons": "1.0.0",
|
'enso-studio-icons': '1.0.0',
|
||||||
"yargs": "^15.3.0"
|
yargs: '^15.3.0',
|
||||||
},
|
},
|
||||||
|
|
||||||
devDependencies: {
|
devDependencies: {
|
||||||
"compression-webpack-plugin": "^3.1.0",
|
'compression-webpack-plugin': '^3.1.0',
|
||||||
"copy-webpack-plugin": "^5.1.1",
|
'copy-webpack-plugin': '^5.1.1',
|
||||||
"devtron": "^1.4.0",
|
devtron: '^1.4.0',
|
||||||
"electron": "11.1.1",
|
electron: '11.1.1',
|
||||||
"electron-builder": "^22.10.5",
|
'electron-builder': '^22.10.5',
|
||||||
"crypto-js": "4.0.0",
|
'crypto-js': '4.0.0',
|
||||||
"electron-notarize" : "1.0.0",
|
'electron-notarize': '1.0.0',
|
||||||
},
|
},
|
||||||
|
|
||||||
scripts: {
|
scripts: {
|
||||||
@ -76,18 +76,14 @@ config.build = {
|
|||||||
icon: `${paths.dist.root}/icons/png`,
|
icon: `${paths.dist.root}/icons/png`,
|
||||||
category: 'Development',
|
category: 'Development',
|
||||||
},
|
},
|
||||||
files: [
|
files: [{ from: paths.dist.content, to: '.' }],
|
||||||
{ from: paths.dist.content, to: '.' }
|
extraResources: [{ from: paths.dist.bin, to: '.', filter: ['!**.tar.gz', '!**.zip'] }],
|
||||||
],
|
|
||||||
extraResources: [
|
|
||||||
{ from: paths.dist.bin, to: '.' , filter: ["!**.tar.gz", "!**.zip"]}
|
|
||||||
],
|
|
||||||
fileAssociations: [
|
fileAssociations: [
|
||||||
{
|
{
|
||||||
ext: 'enso',
|
ext: 'enso',
|
||||||
name: 'Enso Source File',
|
name: 'Enso Source File',
|
||||||
role: 'Editor',
|
role: 'Editor',
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
directories: {
|
directories: {
|
||||||
output: paths.dist.client,
|
output: paths.dist.client,
|
||||||
@ -100,7 +96,7 @@ config.build = {
|
|||||||
// are handled by us. More info:
|
// are handled by us. More info:
|
||||||
// https://github.com/electron-userland/electron-builder/issues/2851
|
// https://github.com/electron-userland/electron-builder/issues/2851
|
||||||
// https://github.com/electron-userland/electron-builder/issues/2900
|
// https://github.com/electron-userland/electron-builder/issues/2900
|
||||||
differentialPackage: false
|
differentialPackage: false,
|
||||||
},
|
},
|
||||||
dmg: {
|
dmg: {
|
||||||
// Disables "block map" generation during electron building. Block maps
|
// Disables "block map" generation during electron building. Block maps
|
||||||
@ -116,7 +112,7 @@ config.build = {
|
|||||||
// notarised application it will still be detected as trusted.
|
// notarised application it will still be detected as trusted.
|
||||||
// For more details see step (4) at
|
// For more details see step (4) at
|
||||||
// https://kilianvalkhof.com/2019/electron/notarizing-your-electron-application/
|
// https://kilianvalkhof.com/2019/electron/notarizing-your-electron-application/
|
||||||
sign: false
|
sign: false,
|
||||||
},
|
},
|
||||||
publish: [],
|
publish: [],
|
||||||
afterAllArtifactBuild: 'tasks/computeHashes.js',
|
afterAllArtifactBuild: 'tasks/computeHashes.js',
|
||||||
|
@ -17,16 +17,12 @@ import paths from '../../../../../build/paths'
|
|||||||
const child_process = require('child_process')
|
const child_process = require('child_process')
|
||||||
const fss = require('fs')
|
const fss = require('fs')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =============
|
// =============
|
||||||
// === Paths ===
|
// === Paths ===
|
||||||
// =============
|
// =============
|
||||||
|
|
||||||
const root = Electron.app.getAppPath()
|
const root = Electron.app.getAppPath()
|
||||||
const resources = path.join(root, "..")
|
const resources = path.join(root, '..')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// FIXME default options parsed wrong
|
// FIXME default options parsed wrong
|
||||||
// https://github.com/yargs/yargs/issues/1590
|
// https://github.com/yargs/yargs/issues/1590
|
||||||
@ -40,8 +36,6 @@ let windowCfg = {
|
|||||||
height: 900,
|
height: 900,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =============
|
// =============
|
||||||
// === Utils ===
|
// === Utils ===
|
||||||
// =============
|
// =============
|
||||||
@ -50,8 +44,7 @@ function capitalizeFirstLetter(string) {
|
|||||||
return string.charAt(0).toUpperCase() + string.slice(1)
|
return string.charAt(0).toUpperCase() + string.slice(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
const execFile = util.promisify(child_process.execFile);
|
const execFile = util.promisify(child_process.execFile)
|
||||||
|
|
||||||
|
|
||||||
// The list of hosts that the app can access. They are required for
|
// The list of hosts that the app can access. They are required for
|
||||||
// user authentication to work.
|
// user authentication to work.
|
||||||
@ -77,7 +70,7 @@ Arguments that follow the two dashes (\`--\`) will be passed to the backend proc
|
|||||||
if IDE spawns backend, i.e. if '--backend false' has not been set.`
|
if IDE spawns backend, i.e. if '--backend false' has not been set.`
|
||||||
|
|
||||||
let optParser = yargs
|
let optParser = yargs
|
||||||
.scriptName("")
|
.scriptName('')
|
||||||
.usage(usage)
|
.usage(usage)
|
||||||
.epilogue(epilogue)
|
.epilogue(epilogue)
|
||||||
.help()
|
.help()
|
||||||
@ -85,7 +78,6 @@ let optParser = yargs
|
|||||||
.parserConfiguration({ 'populate--': true })
|
.parserConfiguration({ 'populate--': true })
|
||||||
.strict()
|
.strict()
|
||||||
|
|
||||||
|
|
||||||
// === Config Options ===
|
// === Config Options ===
|
||||||
|
|
||||||
let configOptionsGroup = 'Config Options:'
|
let configOptionsGroup = 'Config Options:'
|
||||||
@ -137,7 +129,7 @@ optParser.options('verbose', {
|
|||||||
group: debugOptionsGroup,
|
group: debugOptionsGroup,
|
||||||
describe: `Increase logs verbosity. Affects both IDE and the backend.`,
|
describe: `Increase logs verbosity. Affects both IDE and the backend.`,
|
||||||
default: false,
|
default: false,
|
||||||
type : `boolean`
|
type: `boolean`,
|
||||||
})
|
})
|
||||||
|
|
||||||
optParser.options('entry-point', {
|
optParser.options('entry-point', {
|
||||||
@ -156,7 +148,6 @@ optParser.options('devtron', {
|
|||||||
describe: 'Install the Devtron Developer Tools extension',
|
describe: 'Install the Devtron Developer Tools extension',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// === Style Options ===
|
// === Style Options ===
|
||||||
|
|
||||||
let styleOptionsGroup = 'Style Options:'
|
let styleOptionsGroup = 'Style Options:'
|
||||||
@ -164,36 +155,35 @@ let styleOptionsGroup = 'Style Options:'
|
|||||||
optParser.options('frame', {
|
optParser.options('frame', {
|
||||||
group: styleOptionsGroup,
|
group: styleOptionsGroup,
|
||||||
describe: 'Draw window frame. Defaults to `false` on MacOS and `true` otherwise.',
|
describe: 'Draw window frame. Defaults to `false` on MacOS and `true` otherwise.',
|
||||||
type : `boolean`
|
type: `boolean`,
|
||||||
})
|
})
|
||||||
|
|
||||||
optParser.options('vibrancy', {
|
optParser.options('vibrancy', {
|
||||||
group: styleOptionsGroup,
|
group: styleOptionsGroup,
|
||||||
describe: 'Use the vibrancy effect',
|
describe: 'Use the vibrancy effect',
|
||||||
default: false,
|
default: false,
|
||||||
type : `boolean`
|
type: `boolean`,
|
||||||
})
|
})
|
||||||
|
|
||||||
optParser.options('window-size', {
|
optParser.options('window-size', {
|
||||||
group: styleOptionsGroup,
|
group: styleOptionsGroup,
|
||||||
describe: `Set the window size [${windowCfg.width}x${windowCfg.height}]`,
|
describe: `Set the window size [${windowCfg.width}x${windowCfg.height}]`,
|
||||||
requiresArg : true
|
requiresArg: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
optParser.options('theme', {
|
optParser.options('theme', {
|
||||||
group: styleOptionsGroup,
|
group: styleOptionsGroup,
|
||||||
describe: 'Use the provided theme. Defaults to `light`.',
|
describe: 'Use the provided theme. Defaults to `light`.',
|
||||||
type : `string`
|
type: `string`,
|
||||||
})
|
})
|
||||||
|
|
||||||
optParser.options('node-labels', {
|
optParser.options('node-labels', {
|
||||||
group: styleOptionsGroup,
|
group: styleOptionsGroup,
|
||||||
describe: 'Show node labels. Defaults to `true`.',
|
describe: 'Show node labels. Defaults to `true`.',
|
||||||
default: true,
|
default: true,
|
||||||
type : `boolean`
|
type: `boolean`,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// === Other Options ===
|
// === Other Options ===
|
||||||
|
|
||||||
optParser.options('info', {
|
optParser.options('info', {
|
||||||
@ -205,19 +195,19 @@ optParser.options('version', {
|
|||||||
})
|
})
|
||||||
|
|
||||||
optParser.options('crash-report-host', {
|
optParser.options('crash-report-host', {
|
||||||
describe : 'The address of the server that will receive crash reports. ' +
|
describe:
|
||||||
|
'The address of the server that will receive crash reports. ' +
|
||||||
'Consists of a hostname, optionally followed by a ":" and a port number',
|
'Consists of a hostname, optionally followed by a ":" and a port number',
|
||||||
requiresArg: true,
|
requiresArg: true,
|
||||||
default : cfg.defaultLogServerHost
|
default: cfg.defaultLogServerHost,
|
||||||
})
|
})
|
||||||
|
|
||||||
optParser.options('data-gathering', {
|
optParser.options('data-gathering', {
|
||||||
describe: 'Enable the sharing of any usage data',
|
describe: 'Enable the sharing of any usage data',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
default : true
|
default: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// === Parsing ===
|
// === Parsing ===
|
||||||
|
|
||||||
function parseCmdArgs() {
|
function parseCmdArgs() {
|
||||||
@ -232,7 +222,7 @@ let args = parseCmdArgs()
|
|||||||
// borderless on Mac. See https://github.com/enso-org/ide/issues/1101 and
|
// borderless on Mac. See https://github.com/enso-org/ide/issues/1101 and
|
||||||
// https://github.com/electron/electron/issues/3647 for details.
|
// https://github.com/electron/electron/issues/3647 for details.
|
||||||
if (args.frame === undefined) {
|
if (args.frame === undefined) {
|
||||||
args.frame = (process.platform !== 'darwin')
|
args.frame = process.platform !== 'darwin'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.theme === undefined) {
|
if (args.theme === undefined) {
|
||||||
@ -251,8 +241,6 @@ if (args.windowSize) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ==================
|
// ==================
|
||||||
// === Debug Info ===
|
// === Debug Info ===
|
||||||
// ==================
|
// ==================
|
||||||
@ -289,11 +277,9 @@ async function getDebugInfo() {
|
|||||||
async function printDebugInfo() {
|
async function printDebugInfo() {
|
||||||
let info = await getDebugInfo()
|
let info = await getDebugInfo()
|
||||||
console.log(JSON.stringify(info, undefined, 4))
|
console.log(JSON.stringify(info, undefined, 4))
|
||||||
process.exit();
|
process.exit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ================
|
// ================
|
||||||
// === Security ===
|
// === Security ===
|
||||||
// ================
|
// ================
|
||||||
@ -307,7 +293,9 @@ async function printDebugInfo() {
|
|||||||
/// security features. Follow the link to learn more:
|
/// security features. Follow the link to learn more:
|
||||||
/// https://www.electronjs.org/docs/tutorial/security#11-verify-webview-options-before-creation
|
/// https://www.electronjs.org/docs/tutorial/security#11-verify-webview-options-before-creation
|
||||||
function secureWebPreferences(webPreferences) {
|
function secureWebPreferences(webPreferences) {
|
||||||
if(!webPreferences) { webPreferences = {} }
|
if (!webPreferences) {
|
||||||
|
webPreferences = {}
|
||||||
|
}
|
||||||
delete webPreferences.preload
|
delete webPreferences.preload
|
||||||
delete webPreferences.preloadURL
|
delete webPreferences.preloadURL
|
||||||
delete webPreferences.nodeIntegration
|
delete webPreferences.nodeIntegration
|
||||||
@ -335,7 +323,6 @@ Electron.app.on('web-contents-created', (event,contents) => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// === Prevent Navigation ===
|
// === Prevent Navigation ===
|
||||||
|
|
||||||
/// Navigation is a common attack vector. If an attacker can convince your app to navigate away from
|
/// Navigation is a common attack vector. If an attacker can convince your app to navigate away from
|
||||||
@ -352,7 +339,6 @@ Electron.app.on('web-contents-created', (event,contents) => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// === Disable New Windows Creation ===
|
// === Disable New Windows Creation ===
|
||||||
|
|
||||||
/// Much like navigation, the creation of new webContents is a common attack vector. Attackers
|
/// Much like navigation, the creation of new webContents is a common attack vector. Attackers
|
||||||
@ -367,8 +353,6 @@ Electron.app.on('web-contents-created', (event,contents) => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =======================
|
// =======================
|
||||||
// === Project Manager ===
|
// === Project Manager ===
|
||||||
// =======================
|
// =======================
|
||||||
@ -395,7 +379,9 @@ function projectManagerPath() {
|
|||||||
*/
|
*/
|
||||||
async function execProjectManager(args) {
|
async function execProjectManager(args) {
|
||||||
let binPath = projectManagerPath()
|
let binPath = projectManagerPath()
|
||||||
return await execFile(binPath,args).catch(function(err) {throw err})
|
return await execFile(binPath, args).catch(function (err) {
|
||||||
|
throw err
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -414,11 +400,11 @@ function spawnProjectManager(args) {
|
|||||||
let stdout = 'inherit'
|
let stdout = 'inherit'
|
||||||
let stderr = 'inherit'
|
let stderr = 'inherit'
|
||||||
let opts = {
|
let opts = {
|
||||||
stdio: [stdin,stdout,stderr]
|
stdio: [stdin, stdout, stderr],
|
||||||
}
|
}
|
||||||
let out = child_process.spawn(binPath, args, opts)
|
let out = child_process.spawn(binPath, args, opts)
|
||||||
console.log(`Project Manager has been spawned, pid = ${out.pid}.`)
|
console.log(`Project Manager has been spawned, pid = ${out.pid}.`)
|
||||||
out.on('exit', (code) => {
|
out.on('exit', code => {
|
||||||
console.log(`Project Manager exited with code ${code}.`)
|
console.log(`Project Manager exited with code ${code}.`)
|
||||||
})
|
})
|
||||||
return out
|
return out
|
||||||
@ -430,19 +416,17 @@ function runBackend() {
|
|||||||
if (args.verbose === true) {
|
if (args.verbose === true) {
|
||||||
opts.push('-vv')
|
opts.push('-vv')
|
||||||
}
|
}
|
||||||
console.log("Starting the backend process with the following options:", opts)
|
console.log('Starting the backend process with the following options:', opts)
|
||||||
return spawnProjectManager(opts)
|
return spawnProjectManager(opts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function backendVersion() {
|
async function backendVersion() {
|
||||||
if (args.backend !== false) {
|
if (args.backend !== false) {
|
||||||
return await execProjectManager(['--version']).then((t) => t.stdout)
|
return await execProjectManager(['--version']).then(t => t.stdout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ============
|
// ============
|
||||||
// === Main ===
|
// === Main ===
|
||||||
// ============
|
// ============
|
||||||
@ -456,7 +440,7 @@ let origin = null
|
|||||||
async function main(args) {
|
async function main(args) {
|
||||||
setUserAgent()
|
setUserAgent()
|
||||||
runBackend()
|
runBackend()
|
||||||
console.log("Starting the IDE service.")
|
console.log('Starting the IDE service.')
|
||||||
if (args.server !== false) {
|
if (args.server !== false) {
|
||||||
let serverCfg = Object.assign({}, args)
|
let serverCfg = Object.assign({}, args)
|
||||||
serverCfg.dir = root
|
serverCfg.dir = root
|
||||||
@ -465,9 +449,9 @@ async function main(args) {
|
|||||||
origin = `http://localhost:${server.port}`
|
origin = `http://localhost:${server.port}`
|
||||||
}
|
}
|
||||||
if (args.window !== false) {
|
if (args.window !== false) {
|
||||||
console.log("Starting the IDE client.")
|
console.log('Starting the IDE client.')
|
||||||
mainWindow = createWindow()
|
mainWindow = createWindow()
|
||||||
mainWindow.on("close", (evt) => {
|
mainWindow.on('close', evt => {
|
||||||
if (hideInsteadOfQuit) {
|
if (hideInsteadOfQuit) {
|
||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
mainWindow.hide()
|
mainWindow.hide()
|
||||||
@ -495,7 +479,7 @@ function urlParamsFromObject(obj) {
|
|||||||
let val = obj[key]
|
let val = obj[key]
|
||||||
params.push(`${key}=${val}`)
|
params.push(`${key}=${val}`)
|
||||||
}
|
}
|
||||||
return params.join("&")
|
return params.join('&')
|
||||||
}
|
}
|
||||||
|
|
||||||
function createWindow() {
|
function createWindow() {
|
||||||
@ -511,7 +495,7 @@ function createWindow() {
|
|||||||
sandbox: true,
|
sandbox: true,
|
||||||
backgroundThrottling: false,
|
backgroundThrottling: false,
|
||||||
transparent: false,
|
transparent: false,
|
||||||
titleBarStyle : 'default'
|
titleBarStyle: 'default',
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.dev) {
|
if (args.dev) {
|
||||||
@ -550,8 +534,12 @@ function createWindow() {
|
|||||||
verbose: args.verbose,
|
verbose: args.verbose,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.project) { urlCfg.project = args.project }
|
if (args.project) {
|
||||||
if (args.entryPoint) { urlCfg.entry = args.entryPoint }
|
urlCfg.project = args.project
|
||||||
|
}
|
||||||
|
if (args.entryPoint) {
|
||||||
|
urlCfg.entry = args.entryPoint
|
||||||
|
}
|
||||||
|
|
||||||
let params = urlParamsFromObject(urlCfg)
|
let params = urlParamsFromObject(urlCfg)
|
||||||
let address = `${origin}?${params}`
|
let address = `${origin}?${params}`
|
||||||
@ -574,8 +562,6 @@ function setupPermissions() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ==============
|
// ==============
|
||||||
// === Events ===
|
// === Events ===
|
||||||
// ==============
|
// ==============
|
||||||
@ -596,16 +582,16 @@ Electron.app.on('ready', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Frontend:")
|
console.log('Frontend:')
|
||||||
for (let name in versionInfo) {
|
for (let name in versionInfo) {
|
||||||
let label = capitalizeFirstLetter(name)
|
let label = capitalizeFirstLetter(name)
|
||||||
let spacing = ' '.repeat(maxNameLen - name.length)
|
let spacing = ' '.repeat(maxNameLen - name.length)
|
||||||
console.log(`${indent}${label}:${spacing} ${versionInfo[name]}`)
|
console.log(`${indent}${label}:${spacing} ${versionInfo[name]}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("")
|
console.log('')
|
||||||
console.log("Backend:")
|
console.log('Backend:')
|
||||||
backendVersion().then((backend) => {
|
backendVersion().then(backend => {
|
||||||
if (!backend) {
|
if (!backend) {
|
||||||
console.log(`${indent}No backend available.`)
|
console.log(`${indent}No backend available.`)
|
||||||
} else {
|
} else {
|
||||||
@ -630,8 +616,6 @@ if (process.platform === 'darwin') {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =================
|
// =================
|
||||||
// === Shortcuts ===
|
// === Shortcuts ===
|
||||||
// =================
|
// =================
|
||||||
@ -657,12 +641,12 @@ Electron.app.on('web-contents-created', (webContentsCreatedEvent, webContents) =
|
|||||||
let quit_on_win = process.platform == 'win32' && (alt_f4 || ctrl_w)
|
let quit_on_win = process.platform == 'win32' && (alt_f4 || ctrl_w)
|
||||||
let quit_on_lin = process.platform == 'linux' && (alt_f4 || ctrl_q || ctrl_w)
|
let quit_on_lin = process.platform == 'linux' && (alt_f4 || ctrl_q || ctrl_w)
|
||||||
let quit = quit_on_mac || quit_on_win || quit_on_lin
|
let quit = quit_on_mac || quit_on_win || quit_on_lin
|
||||||
if (quit) { Electron.app.quit() }
|
if (quit) {
|
||||||
|
Electron.app.quit()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =============================
|
// =============================
|
||||||
// === Deprecations & Fixmes ===
|
// === Deprecations & Fixmes ===
|
||||||
// =============================
|
// =============================
|
||||||
|
@ -1,22 +1,20 @@
|
|||||||
const remote = require('electron').remote
|
const remote = require('electron').remote
|
||||||
|
|
||||||
let win;
|
let win
|
||||||
if (remote !== undefined) {
|
if (remote !== undefined) {
|
||||||
win = remote.getCurrentWindow()
|
win = remote.getCurrentWindow()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (win === undefined) {
|
if (win === undefined) {
|
||||||
console.warn("Could not get current window object for window startup animation.")
|
console.warn('Could not get current window object for window startup animation.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =============================
|
// =============================
|
||||||
// === Window Show Animation ===
|
// === Window Show Animation ===
|
||||||
// =============================
|
// =============================
|
||||||
|
|
||||||
function ease_in_out_quad(t) {
|
function ease_in_out_quad(t) {
|
||||||
return t<.5 ? 2*t*t : 1 - (-2*t+2)*(-2*t+2) / 2
|
return t < 0.5 ? 2 * t * t : 1 - ((-2 * t + 2) * (-2 * t + 2)) / 2
|
||||||
}
|
}
|
||||||
|
|
||||||
function animate_show(target) {
|
function animate_show(target) {
|
||||||
@ -24,7 +22,9 @@ function animate_show(target) {
|
|||||||
let opacity = 0
|
let opacity = 0
|
||||||
function show_step(timestamp) {
|
function show_step(timestamp) {
|
||||||
opacity += 0.02
|
opacity += 0.02
|
||||||
if (opacity > 1) { opacity = 1 }
|
if (opacity > 1) {
|
||||||
|
opacity = 1
|
||||||
|
}
|
||||||
target.setOpacity(ease_in_out_quad(opacity))
|
target.setOpacity(ease_in_out_quad(opacity))
|
||||||
if (opacity < 1) {
|
if (opacity < 1) {
|
||||||
window.requestAnimationFrame(show_step)
|
window.requestAnimationFrame(show_step)
|
||||||
@ -40,8 +40,6 @@ if (win !== undefined) {
|
|||||||
window.showAnimation = animate_show(win)
|
window.showAnimation = animate_show(win)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ===================
|
// ===================
|
||||||
// === Debug Tools ===
|
// === Debug Tools ===
|
||||||
// ===================
|
// ===================
|
||||||
|
@ -1,18 +1,14 @@
|
|||||||
const crypto = require('crypto');
|
const crypto = require('crypto')
|
||||||
const fs = require('fs');
|
const fs = require('fs')
|
||||||
const glob = require('glob');
|
const glob = require('glob')
|
||||||
const paths = require('../../../../../build/paths')
|
const paths = require('../../../../../build/paths')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =================
|
// =================
|
||||||
// === Constants ===
|
// === Constants ===
|
||||||
// =================
|
// =================
|
||||||
|
|
||||||
const CHECKSUM_TYPE = 'sha256'
|
const CHECKSUM_TYPE = 'sha256'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ================
|
// ================
|
||||||
// === Checksum ===
|
// === Checksum ===
|
||||||
// ================
|
// ================
|
||||||
@ -20,28 +16,28 @@ const CHECKSUM_TYPE = 'sha256'
|
|||||||
/// The `type` argument can be one of `md5`, `sha1`, or `sha256`.
|
/// The `type` argument can be one of `md5`, `sha1`, or `sha256`.
|
||||||
function getChecksum(path, type) {
|
function getChecksum(path, type) {
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
const hash = crypto.createHash(type);
|
const hash = crypto.createHash(type)
|
||||||
const input = fs.createReadStream(path);
|
const input = fs.createReadStream(path)
|
||||||
input.on('error', reject);
|
input.on('error', reject)
|
||||||
input.on('data', function (chunk) {
|
input.on('data', function (chunk) {
|
||||||
hash.update(chunk);
|
hash.update(chunk)
|
||||||
});
|
})
|
||||||
input.on('close', function () {
|
input.on('close', function () {
|
||||||
resolve(hash.digest('hex'));
|
resolve(hash.digest('hex'))
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function writeFileChecksum(path, type) {
|
async function writeFileChecksum(path, type) {
|
||||||
let checksum = await getChecksum(path, type)
|
let checksum = await getChecksum(path, type)
|
||||||
let targetPath = `${path}.${type}`
|
let targetPath = `${path}.${type}`
|
||||||
fs.writeFile(targetPath,checksum,'utf8',(err) => {
|
fs.writeFile(targetPath, checksum, 'utf8', err => {
|
||||||
if (err) { throw err }
|
if (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ================
|
// ================
|
||||||
// === Callback ===
|
// === Callback ===
|
||||||
// ================
|
// ================
|
||||||
|
@ -1,25 +1,25 @@
|
|||||||
/// This script will trigger the notarisation process for macOS and trigger our pre-processing
|
/// This script will trigger the notarisation process for macOS and trigger our pre-processing
|
||||||
/// and signing of the engine.
|
/// and signing of the engine.
|
||||||
require('dotenv').config();
|
require('dotenv').config()
|
||||||
const { notarize } = require('electron-notarize');
|
const { notarize } = require('electron-notarize')
|
||||||
|
|
||||||
exports.default = async function notarizing(context) {
|
exports.default = async function notarizing(context) {
|
||||||
const { electronPlatformName, appOutDir } = context;
|
const { electronPlatformName, appOutDir } = context
|
||||||
if (electronPlatformName !== 'darwin') {
|
if (electronPlatformName !== 'darwin') {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
// We need to manually re-sign our build artifacts before notarisation.
|
// We need to manually re-sign our build artifacts before notarisation.
|
||||||
// See the script for more information.
|
// See the script for more information.
|
||||||
console.log(" • Performing additional signing of dependencies.")
|
console.log(' • Performing additional signing of dependencies.')
|
||||||
await require("./signArchives").default()
|
await require('./signArchives').default()
|
||||||
|
|
||||||
// Notarize the application.
|
// Notarize the application.
|
||||||
const appName = context.packager.appInfo.productFilename;
|
const appName = context.packager.appInfo.productFilename
|
||||||
console.log(" • Notarizing.")
|
console.log(' • Notarizing.')
|
||||||
return await notarize({
|
return await notarize({
|
||||||
appBundleId: 'com.enso.ide',
|
appBundleId: 'com.enso.ide',
|
||||||
appPath: `${appOutDir}/${appName}.app`,
|
appPath: `${appOutDir}/${appName}.app`,
|
||||||
appleId: process.env.APPLEID,
|
appleId: process.env.APPLEID,
|
||||||
appleIdPassword: process.env.APPLEIDPASS,
|
appleIdPassword: process.env.APPLEIDPASS,
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
const { beforeSign } = require('./signArchives')
|
const { beforeSign } = require('./signArchives')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ================
|
// ================
|
||||||
// === Callback ===
|
// === Callback ===
|
||||||
// ================
|
// ================
|
||||||
|
@ -26,7 +26,7 @@ const ID = '"Developer ID Application: New Byte Order Sp. z o. o. (NM77WTZJFQ)"'
|
|||||||
// Placeholder name for temporary archives.
|
// Placeholder name for temporary archives.
|
||||||
const tmpArchive = 'temporary_archive.zip'
|
const tmpArchive = 'temporary_archive.zip'
|
||||||
|
|
||||||
const GRAALVM = 'graalvm-ce-java11-21.1.0';
|
const GRAALVM = 'graalvm-ce-java11-21.1.0'
|
||||||
|
|
||||||
// Helper to execute a command in a given directory and return the output.
|
// Helper to execute a command in a given directory and return the output.
|
||||||
const run = (cmd, cwd) => child_process.execSync(cmd, { shell: true, cwd }).toString()
|
const run = (cmd, cwd) => child_process.execSync(cmd, { shell: true, cwd }).toString()
|
||||||
@ -36,8 +36,8 @@ function sign(targetPath, cwd) {
|
|||||||
console.log(`Signing ${targetPath} in ${cwd}`)
|
console.log(`Signing ${targetPath} in ${cwd}`)
|
||||||
const entitlements_path = path.resolve('./', 'entitlements.mac.plist')
|
const entitlements_path = path.resolve('./', 'entitlements.mac.plist')
|
||||||
return run(
|
return run(
|
||||||
`codesign -vvv --entitlements ${entitlements_path} --force --options=runtime `
|
`codesign -vvv --entitlements ${entitlements_path} --force --options=runtime ` +
|
||||||
+ `--sign ${ID} ${targetPath}`,
|
`--sign ${ID} ${targetPath}`,
|
||||||
cwd
|
cwd
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -108,8 +108,7 @@ function signArchive(archivePath, archiveName, binPaths) {
|
|||||||
// message provided by Apple and can then be added here.
|
// message provided by Apple and can then be added here.
|
||||||
const toSign = [
|
const toSign = [
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/dist/${ENGINE_VERSION}/lib/Standard/Database/${ENGINE_VERSION}/polyglot/java`,
|
||||||
`enso/dist/${ENGINE_VERSION}/lib/Standard/Database/${ENGINE_VERSION}/polyglot/java`,
|
|
||||||
jarName: 'sqlite-jdbc-3.34.0.jar',
|
jarName: 'sqlite-jdbc-3.34.0.jar',
|
||||||
jarContent: [
|
jarContent: [
|
||||||
'org/sqlite/native/Mac/aarch64/libsqlitejdbc.jnilib',
|
'org/sqlite/native/Mac/aarch64/libsqlitejdbc.jnilib',
|
||||||
@ -117,8 +116,7 @@ const toSign = [
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/dist/${ENGINE_VERSION}/component`,
|
||||||
`enso/dist/${ENGINE_VERSION}/component`,
|
|
||||||
jarName: 'runner.jar',
|
jarName: 'runner.jar',
|
||||||
jarContent: [
|
jarContent: [
|
||||||
'org/sqlite/native/Mac/x86_64/libsqlitejdbc.jnilib',
|
'org/sqlite/native/Mac/x86_64/libsqlitejdbc.jnilib',
|
||||||
@ -126,116 +124,97 @@ const toSign = [
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
|
||||||
jarName: 'jdk.jartool.jmod',
|
jarName: 'jdk.jartool.jmod',
|
||||||
jarContent: ['bin/jarsigner', 'bin/jar'],
|
jarContent: ['bin/jarsigner', 'bin/jar'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
|
||||||
jarName: 'jdk.jdeps.jmod',
|
jarName: 'jdk.jdeps.jmod',
|
||||||
jarContent: ['bin/javap', 'bin/jdeprscan', 'bin/jdeps'],
|
jarContent: ['bin/javap', 'bin/jdeprscan', 'bin/jdeps'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
|
||||||
jarName: 'jdk.jstatd.jmod',
|
jarName: 'jdk.jstatd.jmod',
|
||||||
jarContent: ['bin/jstatd'],
|
jarContent: ['bin/jstatd'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
|
||||||
jarName: 'jdk.pack.jmod',
|
jarName: 'jdk.pack.jmod',
|
||||||
jarContent: ['bin/unpack200', 'bin/pack200'],
|
jarContent: ['bin/unpack200', 'bin/pack200'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
|
||||||
jarName: 'jdk.hotspot.agent.jmod',
|
jarName: 'jdk.hotspot.agent.jmod',
|
||||||
jarContent: ['bin/jhsdb'],
|
jarContent: ['bin/jhsdb'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
|
||||||
jarName: 'jdk.jfr.jmod',
|
jarName: 'jdk.jfr.jmod',
|
||||||
jarContent: ['bin/jfr'],
|
jarContent: ['bin/jfr'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
|
||||||
jarName: 'jdk.rmic.jmod',
|
jarName: 'jdk.rmic.jmod',
|
||||||
jarContent: ['bin/rmic'],
|
jarContent: ['bin/rmic'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
|
||||||
jarName: 'java.rmi.jmod',
|
jarName: 'java.rmi.jmod',
|
||||||
jarContent: ['bin/rmid', 'bin/rmiregistry'],
|
jarContent: ['bin/rmid', 'bin/rmiregistry'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
|
||||||
jarName: 'java.base.jmod',
|
jarName: 'java.base.jmod',
|
||||||
jarContent: ['bin/java', 'bin/keytool', 'lib/jspawnhelper'],
|
jarContent: ['bin/java', 'bin/keytool', 'lib/jspawnhelper'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
|
||||||
jarName: 'jdk.jlink.jmod',
|
jarName: 'jdk.jlink.jmod',
|
||||||
jarContent: ['bin/jmod', 'bin/jlink', 'bin/jimage'],
|
jarContent: ['bin/jmod', 'bin/jlink', 'bin/jimage'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
|
||||||
jarName: 'jdk.scripting.nashorn.shell.jmod',
|
jarName: 'jdk.scripting.nashorn.shell.jmod',
|
||||||
jarContent: ['bin/jjs'],
|
jarContent: ['bin/jjs'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
|
||||||
jarName: 'jdk.jcmd.jmod',
|
jarName: 'jdk.jcmd.jmod',
|
||||||
jarContent: ['bin/jstack', 'bin/jcmd', 'bin/jps', 'bin/jmap', 'bin/jstat', 'bin/jinfo'],
|
jarContent: ['bin/jstack', 'bin/jcmd', 'bin/jps', 'bin/jmap', 'bin/jstat', 'bin/jinfo'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
|
||||||
jarName: 'jdk.jshell.jmod',
|
jarName: 'jdk.jshell.jmod',
|
||||||
jarContent: ['bin/jshell'],
|
jarContent: ['bin/jshell'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
|
||||||
jarName: 'jdk.compiler.jmod',
|
jarName: 'jdk.compiler.jmod',
|
||||||
jarContent: ['bin/javac', 'bin/serialver'],
|
jarContent: ['bin/javac', 'bin/serialver'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
|
||||||
jarName: 'java.scripting.jmod',
|
jarName: 'java.scripting.jmod',
|
||||||
jarContent: ['bin/jrunscript'],
|
jarContent: ['bin/jrunscript'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
|
||||||
jarName: 'jdk.jdi.jmod',
|
jarName: 'jdk.jdi.jmod',
|
||||||
jarContent: ['bin/jdb'],
|
jarContent: ['bin/jdb'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
|
||||||
jarName: 'jdk.javadoc.jmod',
|
jarName: 'jdk.javadoc.jmod',
|
||||||
jarContent: ['bin/javadoc'],
|
jarContent: ['bin/javadoc'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
|
||||||
jarName: 'jdk.jconsole.jmod',
|
jarName: 'jdk.jconsole.jmod',
|
||||||
jarContent: ['bin/jconsole'],
|
jarContent: ['bin/jconsole'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
jarDir:
|
jarDir: `enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/jmods`,
|
|
||||||
jarName: 'jdk.javadoc.jmod',
|
jarName: 'jdk.javadoc.jmod',
|
||||||
jarContent: ['bin/javadoc'],
|
jarContent: ['bin/javadoc'],
|
||||||
},
|
},
|
||||||
@ -260,9 +239,7 @@ const extra = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
// The list of readonly files in the GraalVM distribution.
|
// The list of readonly files in the GraalVM distribution.
|
||||||
const readonly = [
|
const readonly = [`enso/runtime/${GRAALVM}/Contents/Home/lib/server/classes.jsa`]
|
||||||
`enso/runtime/${GRAALVM}/Contents/Home/lib/server/classes.jsa`,
|
|
||||||
]
|
|
||||||
|
|
||||||
function beforeSign() {
|
function beforeSign() {
|
||||||
for (let file of readonly) {
|
for (let file of readonly) {
|
||||||
|
@ -10,7 +10,7 @@ module.exports = {
|
|||||||
index: path.resolve(thisPath, 'src', 'index.js'),
|
index: path.resolve(thisPath, 'src', 'index.js'),
|
||||||
},
|
},
|
||||||
mode: 'production',
|
mode: 'production',
|
||||||
target: "electron-main",
|
target: 'electron-main',
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(distPath, 'content'),
|
path: path.resolve(distPath, 'content'),
|
||||||
filename: '[name].js',
|
filename: '[name].js',
|
||||||
@ -19,12 +19,12 @@ module.exports = {
|
|||||||
new Copy([
|
new Copy([
|
||||||
{
|
{
|
||||||
from: path.resolve(thisPath, 'package.json'),
|
from: path.resolve(thisPath, 'package.json'),
|
||||||
to : path.resolve(distPath,'content','package.json')
|
to: path.resolve(distPath, 'content', 'package.json'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
from: path.resolve(thisPath, 'src', 'preload.js'),
|
from: path.resolve(thisPath, 'src', 'preload.js'),
|
||||||
to : path.resolve(distPath,'content','preload.js')
|
to: path.resolve(distPath, 'content', 'preload.js'),
|
||||||
}
|
},
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
performance: {
|
performance: {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
let config = {
|
let config = {
|
||||||
version: "1.0.0",
|
version: '1.0.0',
|
||||||
name: "enso-studio-common",
|
name: 'enso-studio-common',
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { config }
|
module.exports = { config }
|
||||||
|
@ -6,13 +6,13 @@
|
|||||||
// =================
|
// =================
|
||||||
|
|
||||||
export function ease_in_out_cubic(t) {
|
export function ease_in_out_cubic(t) {
|
||||||
return t<.5 ? 4*t*t*t : 1 - (-2*t+2) * (-2*t+2) * (-2*t+2) / 2
|
return t < 0.5 ? 4 * t * t * t : 1 - ((-2 * t + 2) * (-2 * t + 2) * (-2 * t + 2)) / 2
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ease_in_out_quad(t) {
|
export function ease_in_out_quad(t) {
|
||||||
return t<.5 ? 2*t*t : 1 - (-2*t+2)*(-2*t+2) / 2
|
return t < 0.5 ? 2 * t * t : 1 - ((-2 * t + 2) * (-2 * t + 2)) / 2
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ease_out_quart(t) {
|
export function ease_out_quart(t) {
|
||||||
return 1-(--t)*t*t*t
|
return 1 - --t * t * t * t
|
||||||
}
|
}
|
||||||
|
@ -3,14 +3,12 @@ import * as html_utils from './html_utils'
|
|||||||
import * as math from './math'
|
import * as math from './math'
|
||||||
import * as svg from './svg'
|
import * as svg from './svg'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =========================
|
// =========================
|
||||||
// === ProgressIndicator ===
|
// === ProgressIndicator ===
|
||||||
// =========================
|
// =========================
|
||||||
|
|
||||||
let bg_color = "rgb(249,250,251)"
|
let bg_color = 'rgb(249,250,251)'
|
||||||
let loader_color = "#303030"
|
let loader_color = '#303030'
|
||||||
let top_layer_index = 1000
|
let top_layer_index = 1000
|
||||||
|
|
||||||
/// Visual representation of the loader.
|
/// Visual representation of the loader.
|
||||||
@ -38,9 +36,9 @@ export class ProgressIndicator {
|
|||||||
progress_bar.innerHTML = progress_bar_svg
|
progress_bar.innerHTML = progress_bar_svg
|
||||||
center.appendChild(progress_bar)
|
center.appendChild(progress_bar)
|
||||||
|
|
||||||
this.progress_indicator = document.getElementById("progress_indicator")
|
this.progress_indicator = document.getElementById('progress_indicator')
|
||||||
this.progress_indicator_mask = document.getElementById("progress_indicator_mask")
|
this.progress_indicator_mask = document.getElementById('progress_indicator_mask')
|
||||||
this.progress_indicator_corner = document.getElementById("progress_indicator_corner")
|
this.progress_indicator_corner = document.getElementById('progress_indicator_corner')
|
||||||
|
|
||||||
this.set(0)
|
this.set(0)
|
||||||
this.set_opacity(0)
|
this.set_opacity(0)
|
||||||
@ -48,7 +46,9 @@ export class ProgressIndicator {
|
|||||||
if (cfg.use_loader) {
|
if (cfg.use_loader) {
|
||||||
this.initialized = this.animate_show()
|
this.initialized = this.animate_show()
|
||||||
} else {
|
} else {
|
||||||
this.initialized = new Promise((resolve) => {resolve()})
|
this.initialized = new Promise(resolve => {
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
this.animate_rotation()
|
this.animate_rotation()
|
||||||
this.destroyed = false
|
this.destroyed = false
|
||||||
@ -64,14 +64,21 @@ export class ProgressIndicator {
|
|||||||
let mid_radius = (inner_radius + outer_radius) / 2
|
let mid_radius = (inner_radius + outer_radius) / 2
|
||||||
let bar_width = outer_radius - inner_radius
|
let bar_width = outer_radius - inner_radius
|
||||||
|
|
||||||
return svg.new_svg(width,height,`
|
return svg.new_svg(
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
`
|
||||||
<defs>
|
<defs>
|
||||||
<g id="progress_bar">
|
<g id="progress_bar">
|
||||||
<circle fill="${loader_color}" r="${outer_radius}" />
|
<circle fill="${loader_color}" r="${outer_radius}" />
|
||||||
<circle fill="${bg_color}" r="${inner_radius}" />
|
<circle fill="${bg_color}" r="${inner_radius}" />
|
||||||
<path fill="${bg_color}" opacity="${alpha}" id="progress_indicator_mask" />
|
<path fill="${bg_color}" opacity="${alpha}" id="progress_indicator_mask" />
|
||||||
<circle fill="${loader_color}" r="${bar_width/2}" id="progress_indicator_corner" />
|
<circle fill="${loader_color}" r="${
|
||||||
<circle fill="${loader_color}" r="${bar_width/2}" cy="-${mid_radius}" />
|
bar_width / 2
|
||||||
|
}" id="progress_indicator_corner" />
|
||||||
|
<circle fill="${loader_color}" r="${
|
||||||
|
bar_width / 2
|
||||||
|
}" cy="-${mid_radius}" />
|
||||||
</g>
|
</g>
|
||||||
</defs>
|
</defs>
|
||||||
<g transform="translate(${width / 2},${height / 2})">
|
<g transform="translate(${width / 2},${height / 2})">
|
||||||
@ -79,7 +86,8 @@ export class ProgressIndicator {
|
|||||||
<use xlink:href="#progress_bar"></use>
|
<use xlink:href="#progress_bar"></use>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
`)
|
`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destroys the component. Removes it from the stage and destroys attached callbacks.
|
/// Destroys the component. Removes it from the stage and destroys attached callbacks.
|
||||||
@ -95,19 +103,19 @@ export class ProgressIndicator {
|
|||||||
let angle_span = max_angle - min_angle
|
let angle_span = max_angle - min_angle
|
||||||
let mask_angle = (1 - value) * angle_span - min_angle
|
let mask_angle = (1 - value) * angle_span - min_angle
|
||||||
let corner_pos = math.polar_to_cartesian(54, -mask_angle)
|
let corner_pos = math.polar_to_cartesian(54, -mask_angle)
|
||||||
this.progress_indicator_mask.setAttribute("d", svg.arc(128, -mask_angle))
|
this.progress_indicator_mask.setAttribute('d', svg.arc(128, -mask_angle))
|
||||||
this.progress_indicator_corner.setAttribute("cx", corner_pos.x)
|
this.progress_indicator_corner.setAttribute('cx', corner_pos.x)
|
||||||
this.progress_indicator_corner.setAttribute("cy", corner_pos.y)
|
this.progress_indicator_corner.setAttribute('cy', corner_pos.y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the opacity of the loader.
|
/// Set the opacity of the loader.
|
||||||
set_opacity(val) {
|
set_opacity(val) {
|
||||||
this.progress_indicator.setAttribute("opacity",val)
|
this.progress_indicator.setAttribute('opacity', val)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the rotation of the loader (angles).
|
/// Set the rotation of the loader (angles).
|
||||||
set_rotation(val) {
|
set_rotation(val) {
|
||||||
this.progress_indicator.setAttribute("transform",`rotate(${val},0,0)`)
|
this.progress_indicator.setAttribute('transform', `rotate(${val},0,0)`)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start show animation. It is used after the loader is created.
|
/// Start show animation. It is used after the loader is created.
|
||||||
@ -116,7 +124,9 @@ export class ProgressIndicator {
|
|||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
let alpha = 0
|
let alpha = 0
|
||||||
function show_step() {
|
function show_step() {
|
||||||
if (alpha > 1) { alpha = 1 }
|
if (alpha > 1) {
|
||||||
|
alpha = 1
|
||||||
|
}
|
||||||
indicator.set_opacity(animation.ease_in_out_quad(alpha))
|
indicator.set_opacity(animation.ease_in_out_quad(alpha))
|
||||||
alpha += 0.02
|
alpha += 0.02
|
||||||
if (alpha < 1) {
|
if (alpha < 1) {
|
||||||
@ -144,8 +154,6 @@ export class ProgressIndicator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ==============
|
// ==============
|
||||||
// === Loader ===
|
// === Loader ===
|
||||||
// ==============
|
// ==============
|
||||||
@ -163,7 +171,9 @@ export class Loader {
|
|||||||
|
|
||||||
let self = this
|
let self = this
|
||||||
this.done_resolve = null
|
this.done_resolve = null
|
||||||
this.done = new Promise((resolve) => {self.done_resolve = resolve})
|
this.done = new Promise(resolve => {
|
||||||
|
self.done_resolve = resolve
|
||||||
|
})
|
||||||
|
|
||||||
for (let resource of resources) {
|
for (let resource of resources) {
|
||||||
this.total_bytes += parseInt(resource.headers.get('Content-Length'))
|
this.total_bytes += parseInt(resource.headers.get('Content-Length'))
|
||||||
@ -171,7 +181,9 @@ export class Loader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Number.isNaN(this.total_bytes)) {
|
if (Number.isNaN(this.total_bytes)) {
|
||||||
console.error("Loader error. Server is not configured to send the 'Content-Length' metadata.")
|
console.error(
|
||||||
|
"Loader error. Server is not configured to send the 'Content-Length' metadata."
|
||||||
|
)
|
||||||
this.total_bytes = 0
|
this.total_bytes = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,7 +222,9 @@ export class Loader {
|
|||||||
|
|
||||||
let indicator_progress = this.value() * this.cap_progress_at
|
let indicator_progress = this.value() * this.cap_progress_at
|
||||||
this.indicator.set(indicator_progress)
|
this.indicator.set(indicator_progress)
|
||||||
if (this.is_done()) { this.done_resolve() }
|
if (this.is_done()) {
|
||||||
|
this.done_resolve()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Download percentage value.
|
/// Download percentage value.
|
||||||
@ -239,7 +253,7 @@ export class Loader {
|
|||||||
return new WritableStream({
|
return new WritableStream({
|
||||||
write(t) {
|
write(t) {
|
||||||
loader.on_receive(t.length)
|
loader.on_receive(t.length)
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,19 @@
|
|||||||
/// This module defines a common math operations.
|
/// This module defines a common math operations.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ============
|
// ============
|
||||||
// === Math ===
|
// === Math ===
|
||||||
// ============
|
// ============
|
||||||
|
|
||||||
/// Converts the polar coordinates to cartesian ones.
|
/// Converts the polar coordinates to cartesian ones.
|
||||||
export function polar_to_cartesian(radius, angle_degrees) {
|
export function polar_to_cartesian(radius, angle_degrees) {
|
||||||
let angle = (angle_degrees-90) * Math.PI / 180.0
|
let angle = ((angle_degrees - 90) * Math.PI) / 180.0
|
||||||
return {
|
return {
|
||||||
x: radius * Math.cos(angle),
|
x: radius * Math.cos(angle),
|
||||||
y : radius * Math.sin(angle)
|
y: radius * Math.sin(angle),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Format bytes as megabytes with a single precision number.
|
/// Format bytes as megabytes with a single precision number.
|
||||||
export function format_mb(bytes) {
|
export function format_mb(bytes) {
|
||||||
return Math.round(10 * bytes / (1024 * 1024)) / 10
|
return Math.round((10 * bytes) / (1024 * 1024)) / 10
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,6 @@ import * as mime from 'mime-types'
|
|||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import * as portfinder from 'portfinder'
|
import * as portfinder from 'portfinder'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ============
|
// ============
|
||||||
// === Port ===
|
// === Port ===
|
||||||
// ============
|
// ============
|
||||||
@ -19,8 +17,6 @@ async function findPort(cfg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ==============
|
// ==============
|
||||||
// === Server ===
|
// === Server ===
|
||||||
// ==============
|
// ==============
|
||||||
@ -35,22 +31,28 @@ class Server {
|
|||||||
this.dir = cfg.dir
|
this.dir = cfg.dir
|
||||||
this.port = cfg.port
|
this.port = cfg.port
|
||||||
this.fallback = cfg.fallback
|
this.fallback = cfg.fallback
|
||||||
this.server = createServers({
|
this.server = createServers(
|
||||||
|
{
|
||||||
http: this.port,
|
http: this.port,
|
||||||
handler: function (request, response) {
|
handler: function (request, response) {
|
||||||
self.process(request.url, response)
|
self.process(request.url, response)
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
function (errs) {
|
function (errs) {
|
||||||
if (errs) { return console.log(errs.http) }
|
if (errs) {
|
||||||
|
return console.log(errs.http)
|
||||||
|
}
|
||||||
console.log(`Server started on port ${this.port}.`)
|
console.log(`Server started on port ${this.port}.`)
|
||||||
console.log(`Serving files from '${process.cwd()}/${this.dir}'.`)
|
console.log(`Serving files from '${process.cwd()}/${this.dir}'.`)
|
||||||
}.bind(this))
|
}.bind(this)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
process(resource, response) {
|
process(resource, response) {
|
||||||
let resource_file = `${this.dir}${resource}`
|
let resource_file = `${this.dir}${resource}`
|
||||||
fs.readFile(resource_file, function (err,data) {
|
fs.readFile(
|
||||||
|
resource_file,
|
||||||
|
function (err, data) {
|
||||||
if (err) {
|
if (err) {
|
||||||
let fallback = this.fallback
|
let fallback = this.fallback
|
||||||
if (fallback) {
|
if (fallback) {
|
||||||
@ -70,7 +72,8 @@ class Server {
|
|||||||
response.writeHead(200)
|
response.writeHead(200)
|
||||||
response.end(data)
|
response.end(data)
|
||||||
}
|
}
|
||||||
}.bind(this))
|
}.bind(this)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
import * as math from './math'
|
import * as math from './math'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ===========
|
// ===========
|
||||||
// === SVG ===
|
// === SVG ===
|
||||||
// ===========
|
// ===========
|
||||||
@ -27,6 +25,6 @@ export function arc(radius, end_angle){
|
|||||||
}
|
}
|
||||||
let start = math.polar_to_cartesian(radius, end_angle)
|
let start = math.polar_to_cartesian(radius, end_angle)
|
||||||
let end = math.polar_to_cartesian(radius, start_angle)
|
let end = math.polar_to_cartesian(radius, start_angle)
|
||||||
let large_arc = end_angle - start_angle <= 180 ? "0" : "1"
|
let large_arc = end_angle - start_angle <= 180 ? '0' : '1'
|
||||||
return `M 0 0 L ${start.x} ${start.y} A ${radius} ${radius} 0 ${large_arc} 0 ${end.x} ${end.y}`
|
return `M 0 0 L ${start.x} ${start.y} A ${radius} ${radius} 0 ${large_arc} 0 ${end.x} ${end.y}`
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,27 @@
|
|||||||
let config = {
|
let config = {
|
||||||
name: "enso-studio-content",
|
name: 'enso-studio-content',
|
||||||
version: "1.0.0",
|
version: '1.0.0',
|
||||||
scripts: {
|
scripts: {
|
||||||
"build": "npx webpack",
|
build: 'npx webpack',
|
||||||
"watch": "npx webpack-dev-server"
|
watch: 'npx webpack-dev-server',
|
||||||
},
|
},
|
||||||
dependencies: {
|
dependencies: {
|
||||||
"enso-studio-common": "1.0.0",
|
'enso-studio-common': '1.0.0',
|
||||||
"firebase": "^8.6.8",
|
firebase: '^8.6.8',
|
||||||
"firebaseui": "^4.8.0",
|
firebaseui: '^4.8.0',
|
||||||
"copy-webpack-plugin": "^5.1.1",
|
'copy-webpack-plugin': '^5.1.1',
|
||||||
"html-loader": "^1.3.2",
|
'html-loader': '^1.3.2',
|
||||||
"mixpanel-browser": "2.40.1"
|
'mixpanel-browser': '2.40.1',
|
||||||
},
|
},
|
||||||
devDependencies: {
|
devDependencies: {
|
||||||
"compression-webpack-plugin": "^3.1.0",
|
'compression-webpack-plugin': '^3.1.0',
|
||||||
"copy-webpack-plugin": "^5.1.1",
|
'copy-webpack-plugin': '^5.1.1',
|
||||||
"yaml-loader": "^0.6.0",
|
'yaml-loader': '^0.6.0',
|
||||||
"ts-loader": "^8.0.3",
|
'ts-loader': '^8.0.3',
|
||||||
"typescript": "^4.0.2",
|
typescript: '^4.0.2',
|
||||||
"webpack": "^4.44.1",
|
webpack: '^4.44.1',
|
||||||
"webpack-cli": "^3.3.12"
|
'webpack-cli': '^3.3.12',
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { config }
|
module.exports = { config }
|
||||||
|
@ -1,37 +1,42 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Source Code Pro';
|
font-family: "Source Code Pro";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_XiYsKILxRpg3hIP6sJ7fM7PqtlsnztA.ttf) format('truetype');
|
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_XiYsKILxRpg3hIP6sJ7fM7PqtlsnztA.ttf)
|
||||||
|
format("truetype");
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Source Code Pro';
|
font-family: "Source Code Pro";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_SiYsKILxRpg3hIP6sJ7fM7PqVOg.ttf) format('truetype');
|
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_SiYsKILxRpg3hIP6sJ7fM7PqVOg.ttf)
|
||||||
|
format("truetype");
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Source Code Pro';
|
font-family: "Source Code Pro";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_XiYsKILxRpg3hIP6sJ7fM7PqtzsjztA.ttf) format('truetype');
|
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_XiYsKILxRpg3hIP6sJ7fM7PqtzsjztA.ttf)
|
||||||
|
format("truetype");
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Source Code Pro';
|
font-family: "Source Code Pro";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_XiYsKILxRpg3hIP6sJ7fM7Pqt4s_ztA.ttf) format('truetype');
|
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_XiYsKILxRpg3hIP6sJ7fM7Pqt4s_ztA.ttf)
|
||||||
|
format("truetype");
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Source Code Pro';
|
font-family: "Source Code Pro";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_XiYsKILxRpg3hIP6sJ7fM7Pqths7ztA.ttf) format('truetype');
|
src: url(https://fonts.gstatic.com/s/sourcecodepro/v14/HI_XiYsKILxRpg3hIP6sJ7fM7Pqths7ztA.ttf)
|
||||||
|
format("truetype");
|
||||||
}
|
}
|
||||||
.enso.docs {
|
.enso.docs {
|
||||||
font-family: Causten, DejaVuSansMonoBook, sans-serif;
|
font-family: Causten, DejaVuSansMonoBook, sans-serif;
|
||||||
@ -60,7 +65,7 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding: 1px 0px 2px;
|
padding: 1px 0px 2px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
color: #4EA5FD;
|
color: #4ea5fd;
|
||||||
-webkit-box-decoration-break: clone;
|
-webkit-box-decoration-break: clone;
|
||||||
}
|
}
|
||||||
.enso.docs .doc-copy-btn {
|
.enso.docs .doc-copy-btn {
|
||||||
@ -164,7 +169,7 @@
|
|||||||
line-height: 1.35;
|
line-height: 1.35;
|
||||||
box-decoration-break: clone;
|
box-decoration-break: clone;
|
||||||
-webkit-box-decoration-break: clone;
|
-webkit-box-decoration-break: clone;
|
||||||
background-color: #E7E9EB;
|
background-color: #e7e9eb;
|
||||||
}
|
}
|
||||||
.light-theme .enso.docs .tag .details {
|
.light-theme .enso.docs .tag .details {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@ -172,7 +177,7 @@
|
|||||||
.light-theme .enso.docs .important,
|
.light-theme .enso.docs .important,
|
||||||
.light-theme .enso.docs .info,
|
.light-theme .enso.docs .info,
|
||||||
.light-theme .enso.docs .example {
|
.light-theme .enso.docs .example {
|
||||||
background-color: #E7E9EB;
|
background-color: #e7e9eb;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding: 1px 0px 2px;
|
padding: 1px 0px 2px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
color: #4EA5FD;
|
color: #4ea5fd;
|
||||||
-webkit-box-decoration-break: clone;
|
-webkit-box-decoration-break: clone;
|
||||||
}
|
}
|
||||||
.doc-copy-btn {
|
.doc-copy-btn {
|
||||||
@ -136,7 +136,7 @@
|
|||||||
line-height: 1.35;
|
line-height: 1.35;
|
||||||
box-decoration-break: clone;
|
box-decoration-break: clone;
|
||||||
-webkit-box-decoration-break: clone;
|
-webkit-box-decoration-break: clone;
|
||||||
background-color: #E7E9EB;
|
background-color: #e7e9eb;
|
||||||
}
|
}
|
||||||
.details {
|
.details {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@ -145,7 +145,7 @@
|
|||||||
.important,
|
.important,
|
||||||
.info,
|
.info,
|
||||||
.example {
|
.example {
|
||||||
background-color: #E7E9EB;
|
background-color: #e7e9eb;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
.summary {
|
.summary {
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8" />
|
||||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||||
<!-- FIXME https://github.com/validator/validator/issues/917 -->
|
<!-- FIXME https://github.com/validator/validator/issues/917 -->
|
||||||
<!-- FIXME Security Vulnerabilities: https://github.com/enso-org/ide/issues/226 -->
|
<!-- FIXME Security Vulnerabilities: https://github.com/enso-org/ide/issues/226 -->
|
||||||
<!-- NOTE `frame-src` section of `http-equiv` required only for authorization -->
|
<!-- NOTE `frame-src` section of `http-equiv` required only for authorization -->
|
||||||
<meta http-equiv="Content-Security-Policy" content="
|
<meta
|
||||||
|
http-equiv="Content-Security-Policy"
|
||||||
|
content="
|
||||||
default-src 'self';
|
default-src 'self';
|
||||||
frame-src 'self' data: https://accounts.google.com https://enso-org.firebaseapp.com;
|
frame-src 'self' data: https://accounts.google.com https://enso-org.firebaseapp.com;
|
||||||
script-src 'self' 'unsafe-eval' data: https://*;
|
script-src 'self' 'unsafe-eval' data: https://*;
|
||||||
@ -16,7 +18,9 @@
|
|||||||
img-src 'self' blob: data: https://*;
|
img-src 'self' blob: data: https://*;
|
||||||
font-src 'self' data: https://*"
|
font-src 'self' data: https://*"
|
||||||
/>
|
/>
|
||||||
<meta name="viewport" content="
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="
|
||||||
width=device-width,
|
width=device-width,
|
||||||
initial-scale = 1.0,
|
initial-scale = 1.0,
|
||||||
maximum-scale = 1.0,
|
maximum-scale = 1.0,
|
||||||
@ -25,7 +29,11 @@
|
|||||||
<title>Enso</title>
|
<title>Enso</title>
|
||||||
<link rel="stylesheet" href="/assets/style.css" />
|
<link rel="stylesheet" href="/assets/style.css" />
|
||||||
<link rel="stylesheet" href="/assets/docsStyle.css" />
|
<link rel="stylesheet" href="/assets/docsStyle.css" />
|
||||||
<link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/4.8.0/firebase-ui-auth.css" />
|
<link
|
||||||
|
type="text/css"
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://www.gstatic.com/firebasejs/ui/4.8.0/firebase-ui-auth.css"
|
||||||
|
/>
|
||||||
<script type="module" src="/assets/index.js" defer></script>
|
<script type="module" src="/assets/index.js" defer></script>
|
||||||
<script type="module" src="/assets/run.js" defer></script>
|
<script type="module" src="/assets/run.js" defer></script>
|
||||||
</head>
|
</head>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/// This module defines the Project Manager endpoint.
|
/// This module defines the Project Manager endpoint.
|
||||||
|
|
||||||
const PROJECT_MANAGER_ENDPOINT = "ws://127.0.0.1:30535"
|
const PROJECT_MANAGER_ENDPOINT = 'ws://127.0.0.1:30535'
|
||||||
|
|
||||||
const MISSING_COMPONENT_ACTION_INSTALL = 'Install'
|
const MISSING_COMPONENT_ACTION_INSTALL = 'Install'
|
||||||
|
|
||||||
@ -8,7 +8,6 @@ const MISSING_COMPONENT_ACTION_INSTALL = 'Install'
|
|||||||
* A WebSocket endpoint to the project manager.
|
* A WebSocket endpoint to the project manager.
|
||||||
*/
|
*/
|
||||||
class ProjectManager {
|
class ProjectManager {
|
||||||
|
|
||||||
protected readonly connection_url: string
|
protected readonly connection_url: string
|
||||||
|
|
||||||
constructor(connection_url: string) {
|
constructor(connection_url: string) {
|
||||||
@ -23,12 +22,11 @@ class ProjectManager {
|
|||||||
* Get the projects list.
|
* Get the projects list.
|
||||||
*/
|
*/
|
||||||
listProjects(): any {
|
listProjects(): any {
|
||||||
const req =
|
const req = {
|
||||||
{
|
jsonrpc: '2.0',
|
||||||
jsonrpc: "2.0",
|
|
||||||
id: 0,
|
id: 0,
|
||||||
method: "project/list",
|
method: 'project/list',
|
||||||
params: {}
|
params: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
const ws = new WebSocket(this.connection_url)
|
const ws = new WebSocket(this.connection_url)
|
||||||
@ -59,14 +57,13 @@ class ProjectManager {
|
|||||||
}
|
}
|
||||||
if (template !== undefined) {
|
if (template !== undefined) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
params["projectTemplate"] = template
|
params['projectTemplate'] = template
|
||||||
}
|
}
|
||||||
const req =
|
const req = {
|
||||||
{
|
jsonrpc: '2.0',
|
||||||
jsonrpc: "2.0",
|
|
||||||
id: 0,
|
id: 0,
|
||||||
method: "project/create",
|
method: 'project/create',
|
||||||
params: params
|
params: params,
|
||||||
}
|
}
|
||||||
|
|
||||||
const ws = new WebSocket(this.connection_url)
|
const ws = new WebSocket(this.connection_url)
|
||||||
@ -74,10 +71,10 @@ class ProjectManager {
|
|||||||
ws.onopen = () => {
|
ws.onopen = () => {
|
||||||
ws.send(JSON.stringify(req))
|
ws.send(JSON.stringify(req))
|
||||||
}
|
}
|
||||||
ws.onmessage = (event) => {
|
ws.onmessage = event => {
|
||||||
resolve(JSON.parse(event.data))
|
resolve(JSON.parse(event.data))
|
||||||
}
|
}
|
||||||
ws.onerror = (error) => {
|
ws.onerror = error => {
|
||||||
reject(error)
|
reject(error)
|
||||||
}
|
}
|
||||||
}).finally(() => ws.close())
|
}).finally(() => ws.close())
|
||||||
|
@ -11,10 +11,8 @@
|
|||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Causten";
|
font-family: "Causten";
|
||||||
src: url("/assets/fonts/CaustenExtraLight/font.woff2")
|
src: url("/assets/fonts/CaustenExtraLight/font.woff2") format("woff2"),
|
||||||
format("woff2"),
|
url("/assets/fonts/CaustenExtraLight/font.woff") format("woff");
|
||||||
url("/assets/fonts/CaustenExtraLight/font.woff")
|
|
||||||
format("woff");
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 200;
|
font-weight: 200;
|
||||||
font-display: block;
|
font-display: block;
|
||||||
@ -22,10 +20,8 @@
|
|||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Causten";
|
font-family: "Causten";
|
||||||
src: url("/assets/fonts/CaustenLight/font.woff2")
|
src: url("/assets/fonts/CaustenLight/font.woff2") format("woff2"),
|
||||||
format("woff2"),
|
url("/assets/fonts/CaustenLight/font.woff") format("woff");
|
||||||
url("/assets/fonts/CaustenLight/font.woff")
|
|
||||||
format("woff");
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-display: block;
|
font-display: block;
|
||||||
@ -33,10 +29,8 @@
|
|||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Causten";
|
font-family: "Causten";
|
||||||
src: url("/assets/fonts/CaustenRegular/font.woff2")
|
src: url("/assets/fonts/CaustenRegular/font.woff2") format("woff2"),
|
||||||
format("woff2"),
|
url("/assets/fonts/CaustenRegular/font.woff") format("woff");
|
||||||
url("/assets/fonts/CaustenRegular/font.woff")
|
|
||||||
format("woff");
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-display: block;
|
font-display: block;
|
||||||
@ -44,10 +38,8 @@
|
|||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Causten";
|
font-family: "Causten";
|
||||||
src: url("/assets/fonts/CaustenMedium/font.woff2")
|
src: url("/assets/fonts/CaustenMedium/font.woff2") format("woff2"),
|
||||||
format("woff2"),
|
url("/assets/fonts/CaustenMedium/font.woff") format("woff");
|
||||||
url("/assets/fonts/CaustenMedium/font.woff")
|
|
||||||
format("woff");
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-display: block;
|
font-display: block;
|
||||||
@ -55,10 +47,8 @@
|
|||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Causten";
|
font-family: "Causten";
|
||||||
src: url("/assets/fonts/CaustenSemiBold/font.woff2")
|
src: url("/assets/fonts/CaustenSemiBold/font.woff2") format("woff2"),
|
||||||
format("woff2"),
|
url("/assets/fonts/CaustenSemiBold/font.woff") format("woff");
|
||||||
url("/assets/fonts/CaustenSemiBold/font.woff")
|
|
||||||
format("woff");
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-display: block;
|
font-display: block;
|
||||||
@ -66,10 +56,8 @@
|
|||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Causten";
|
font-family: "Causten";
|
||||||
src: url("/assets/fonts/CaustenBold/font.woff2")
|
src: url("/assets/fonts/CaustenBold/font.woff2") format("woff2"),
|
||||||
format("woff2"),
|
url("/assets/fonts/CaustenBold/font.woff") format("woff");
|
||||||
url("/assets/fonts/CaustenBold/font.woff")
|
|
||||||
format("woff");
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-display: block;
|
font-display: block;
|
||||||
@ -77,10 +65,8 @@
|
|||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Causten";
|
font-family: "Causten";
|
||||||
src: url("/assets/fonts/CaustenExtraBold/font.woff2")
|
src: url("/assets/fonts/CaustenExtraBold/font.woff2") format("woff2"),
|
||||||
format("woff2"),
|
url("/assets/fonts/CaustenExtraBold/font.woff") format("woff");
|
||||||
url("/assets/fonts/CaustenExtraBold/font.woff")
|
|
||||||
format("woff");
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
font-display: block;
|
font-display: block;
|
||||||
@ -88,10 +74,8 @@
|
|||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Causten";
|
font-family: "Causten";
|
||||||
src: url("/assets/fonts/CaustenBlack/font.woff2")
|
src: url("/assets/fonts/CaustenBlack/font.woff2") format("woff2"),
|
||||||
format("woff2"),
|
url("/assets/fonts/CaustenBlack/font.woff") format("woff");
|
||||||
url("/assets/fonts/CaustenBlack/font.woff")
|
|
||||||
format("woff");
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
font-display: block;
|
font-display: block;
|
||||||
@ -99,7 +83,8 @@
|
|||||||
|
|
||||||
/* End of fonts */
|
/* End of fonts */
|
||||||
|
|
||||||
html, body {
|
html,
|
||||||
|
body {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,12 +259,12 @@ body {
|
|||||||
.templates-view .side-menu ul img {
|
.templates-view .side-menu ul img {
|
||||||
width: 14px;
|
width: 14px;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
background-color: #4180F1;
|
background-color: #4180f1;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.templates-view .side-menu li#projects-list-new-project img {
|
.templates-view .side-menu li#projects-list-new-project img {
|
||||||
background-color: #EFEFEF;
|
background-color: #efefef;
|
||||||
}
|
}
|
||||||
|
|
||||||
.templates-view .content {
|
.templates-view .content {
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
<div id="templates-view" class="templates-view">
|
<div id="templates-view" class="templates-view">
|
||||||
<div id="templates-status-box" style="color: DarkSalmon; text-align: center; visibility: hidden;">Hidden</div>
|
<div
|
||||||
|
id="templates-status-box"
|
||||||
|
style="color: DarkSalmon; text-align: center; visibility: hidden"
|
||||||
|
>
|
||||||
|
Hidden
|
||||||
|
</div>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<aside class="side-menu">
|
<aside class="side-menu">
|
||||||
<h2>Your projects</h2>
|
<h2>Your projects</h2>
|
||||||
@ -16,26 +21,24 @@
|
|||||||
<div class="cards">
|
<div class="cards">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div id="card-spreadsheets" class="card card-spreadsheets">
|
<div id="card-spreadsheets" class="card card-spreadsheets">
|
||||||
<img
|
<img src="/assets/spreadsheets.png" />
|
||||||
src="/assets/spreadsheets.png"
|
|
||||||
/>
|
|
||||||
<h3>Combine spreadsheets</h3>
|
<h3>Combine spreadsheets</h3>
|
||||||
<p>
|
<p>
|
||||||
Glue multiple spreadsheets together to analyse all your data at once.
|
Glue multiple spreadsheets together to analyse all your data at
|
||||||
|
once.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div id="card-geo" class="card card-geo">
|
<div id="card-geo" class="card card-geo">
|
||||||
<h3>Geospatial analysis</h3>
|
<h3>Geospatial analysis</h3>
|
||||||
<p>
|
<p>Learn where to open a coffee shop to maximize your income.</p>
|
||||||
Learn where to open a coffee shop to maximize your income.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div id="card-visualize" class="card card-visualize">
|
<div id="card-visualize" class="card card-visualize">
|
||||||
<h3>Analyze GitHub stars</h3>
|
<h3>Analyze GitHub stars</h3>
|
||||||
<p>
|
<p>
|
||||||
Find out which of Enso's repositories are most popular over time.
|
Find out which of Enso's repositories are most popular over
|
||||||
|
time.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -11,11 +11,7 @@ const CARD_SPREADSHEETS = 'card-spreadsheets'
|
|||||||
const CARD_GEO = 'card-geo'
|
const CARD_GEO = 'card-geo'
|
||||||
const CARD_VISUALIZE = 'card-visualize'
|
const CARD_VISUALIZE = 'card-visualize'
|
||||||
|
|
||||||
const ALL_CARDS = [
|
const ALL_CARDS = [CARD_SPREADSHEETS, CARD_GEO, CARD_VISUALIZE]
|
||||||
CARD_SPREADSHEETS,
|
|
||||||
CARD_GEO,
|
|
||||||
CARD_VISUALIZE,
|
|
||||||
]
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The sore for hidden elements.
|
* The sore for hidden elements.
|
||||||
@ -46,7 +42,7 @@ async function loadTemplatesView(openProject: (project: string) => void): Promis
|
|||||||
try {
|
try {
|
||||||
await loadProjectsList(openProject)
|
await loadProjectsList(openProject)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
displayStatusBox("Failed to load projects.")
|
displayStatusBox('Failed to load projects.')
|
||||||
}
|
}
|
||||||
|
|
||||||
setTemplateCardHandlers(openProject)
|
setTemplateCardHandlers(openProject)
|
||||||
@ -118,15 +114,14 @@ async function loadProjectsList(openProject: (project: string) => void): Promise
|
|||||||
})
|
})
|
||||||
.catch((error: any) => {
|
.catch((error: any) => {
|
||||||
console.error('onclick', PROJECTS_LIST_NEW_PROJECT, error)
|
console.error('onclick', PROJECTS_LIST_NEW_PROJECT, error)
|
||||||
displayStatusBox("Failed to create a new project.")
|
displayStatusBox('Failed to create a new project.')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const projectsListResult = await PM.listProjects()
|
const projectsListResult = await PM.listProjects()
|
||||||
const projectsList = projectsListResult
|
const projectsList = projectsListResult.result.projects.map((project: any) =>
|
||||||
.result
|
buildProjectListNode(project.name, openProject)
|
||||||
.projects
|
)
|
||||||
.map((project: any) => buildProjectListNode(project.name, openProject))
|
|
||||||
|
|
||||||
projectsList.forEach((element: any) => {
|
projectsList.forEach((element: any) => {
|
||||||
projectsListNode.insertBefore(element, newProjectNode)
|
projectsListNode.insertBefore(element, newProjectNode)
|
||||||
@ -139,7 +134,10 @@ async function loadProjectsList(openProject: (project: string) => void): Promise
|
|||||||
* @param projectName the name of the project
|
* @param projectName the name of the project
|
||||||
* @param openProject the callback that opens IDE with the provided project
|
* @param openProject the callback that opens IDE with the provided project
|
||||||
*/
|
*/
|
||||||
function buildProjectListNode(projectName: string, openProject: (project: string) => void): HTMLLIElement {
|
function buildProjectListNode(
|
||||||
|
projectName: string,
|
||||||
|
openProject: (project: string) => void
|
||||||
|
): HTMLLIElement {
|
||||||
const li = document.createElement('li')
|
const li = document.createElement('li')
|
||||||
li.setAttribute('style', 'cursor: pointer;')
|
li.setAttribute('style', 'cursor: pointer;')
|
||||||
li.onclick = () => {
|
li.onclick = () => {
|
||||||
@ -176,7 +174,10 @@ function setTemplateCardHandlers(openProject: (project: String) => void): void {
|
|||||||
* @param element the HTML element of the template card
|
* @param element the HTML element of the template card
|
||||||
* @param openProject the callback that opens IDE with the provided project
|
* @param openProject the callback that opens IDE with the provided project
|
||||||
*/
|
*/
|
||||||
function setTemplateCardHandler(element: HTMLElement, openProject: (project: string) => void): void {
|
function setTemplateCardHandler(
|
||||||
|
element: HTMLElement,
|
||||||
|
openProject: (project: string) => void
|
||||||
|
): void {
|
||||||
element.setAttribute('style', 'cursor: pointer;')
|
element.setAttribute('style', 'cursor: pointer;')
|
||||||
element.onclick = () => {
|
element.onclick = () => {
|
||||||
const projectName = getProjectName(element.id)
|
const projectName = getProjectName(element.id)
|
||||||
@ -186,7 +187,7 @@ function setTemplateCardHandler(element: HTMLElement, openProject: (project: str
|
|||||||
PM.createProject(projectName, templateName)
|
PM.createProject(projectName, templateName)
|
||||||
.then((response: any) => {
|
.then((response: any) => {
|
||||||
if (response.error !== undefined) {
|
if (response.error !== undefined) {
|
||||||
console.error("Project manager createProject failed", response)
|
console.error('Project manager createProject failed', response)
|
||||||
displayStatusBox(response.error.message)
|
displayStatusBox(response.error.message)
|
||||||
} else {
|
} else {
|
||||||
restoreRootHtml()
|
restoreRootHtml()
|
||||||
@ -195,7 +196,7 @@ function setTemplateCardHandler(element: HTMLElement, openProject: (project: str
|
|||||||
})
|
})
|
||||||
.catch((error: any) => {
|
.catch((error: any) => {
|
||||||
console.error('onclick', element.id, error)
|
console.error('onclick', element.id, error)
|
||||||
displayStatusBox("Failed to open a template.")
|
displayStatusBox('Failed to open a template.')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import * as wasm_rust_glue from "wasm_rust_glue"
|
import * as wasm_rust_glue from 'wasm_rust_glue'
|
||||||
|
|
||||||
/// WARNING
|
/// WARNING
|
||||||
/// This module is a hacky binding to wasm_pack. It works only if the wasm_pack output is
|
/// This module is a hacky binding to wasm_pack. It works only if the wasm_pack output is
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
let config = {
|
let config = {
|
||||||
name: "enso-studio-icons",
|
name: 'enso-studio-icons',
|
||||||
version: "1.0.0",
|
version: '1.0.0',
|
||||||
scripts: {
|
scripts: {
|
||||||
"build": "node src/index.js"
|
build: 'node src/index.js',
|
||||||
},
|
},
|
||||||
devDependencies: {
|
devDependencies: {
|
||||||
"sharp": "^0.26.2",
|
sharp: '^0.26.2',
|
||||||
"to-ico": "^1.1.5"
|
'to-ico': '^1.1.5',
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { config }
|
module.exports = { config }
|
||||||
|
@ -23,19 +23,29 @@ class Logo {
|
|||||||
this.d = 4
|
this.d = 4
|
||||||
let innerSize = 56
|
let innerSize = 56
|
||||||
this.scale1 = innerSize / 64
|
this.scale1 = innerSize / 64
|
||||||
this.scale = (this.xsize / 64)
|
this.scale = this.xsize / 64
|
||||||
this.tx = (64 - innerSize) / 2
|
this.tx = (64 - innerSize) / 2
|
||||||
if (this.compatibleMode) { this.ref = "xlink:href" } else { this.ref = "href" }
|
if (this.compatibleMode) {
|
||||||
|
this.ref = 'xlink:href'
|
||||||
|
} else {
|
||||||
|
this.ref = 'href'
|
||||||
|
}
|
||||||
this.defs = ''
|
this.defs = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
generate() {
|
generate() {
|
||||||
return `
|
return `
|
||||||
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="${this.xsize}" width="${this.xsize}" viewBox="0 0 ${this.xsize} ${this.xsize}">
|
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="${
|
||||||
|
this.xsize
|
||||||
|
}" width="${this.xsize}" viewBox="0 0 ${this.xsize} ${this.xsize}">
|
||||||
<defs>
|
<defs>
|
||||||
<circle id="innerCircle" cx="32" cy="32" r="${this.innerRadius}"/>
|
<circle id="innerCircle" cx="32" cy="32" r="${this.innerRadius}"/>
|
||||||
<circle id="leftAtom" cx="${this.borderWidth + this.borderOffset + this.atomRadius + this.atomDiff - this.d}" cy="32" r="${this.atomRadius + this.atomDiff + this.d}"/>
|
<circle id="leftAtom" cx="${
|
||||||
<circle id="rightAtom" cx="${this.borderWidth + this.borderOffset + 3 * this.atomRadius + this.atomDiff}" cy="32" r="${this.atomRadius - this.atomDiff}"/>
|
this.borderWidth + this.borderOffset + this.atomRadius + this.atomDiff - this.d
|
||||||
|
}" cy="32" r="${this.atomRadius + this.atomDiff + this.d}"/>
|
||||||
|
<circle id="rightAtom" cx="${
|
||||||
|
this.borderWidth + this.borderOffset + 3 * this.atomRadius + this.atomDiff
|
||||||
|
}" cy="32" r="${this.atomRadius - this.atomDiff}"/>
|
||||||
<mask id="innerCircleMask">
|
<mask id="innerCircleMask">
|
||||||
<use ${this.ref}="#innerCircle" fill="white"/>
|
<use ${this.ref}="#innerCircle" fill="white"/>
|
||||||
</mask>
|
</mask>
|
||||||
@ -101,17 +111,19 @@ class AppLogo extends Logo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fastGenerate = (cons) => (...args) => new cons(...args).generate()
|
fastGenerate =
|
||||||
|
cons =>
|
||||||
|
(...args) =>
|
||||||
|
new cons(...args).generate()
|
||||||
|
|
||||||
exports.generateMinimalWhiteLogo = fastGenerate(AppLogo)
|
exports.generateMinimalWhiteLogo = fastGenerate(AppLogo)
|
||||||
|
|
||||||
|
|
||||||
const fss = require('fs')
|
const fss = require('fs')
|
||||||
const fs = fss.promises
|
const fs = fss.promises
|
||||||
const exec = require('child_process').exec
|
const exec = require('child_process').exec
|
||||||
const spawn = require('child_process').spawn
|
const spawn = require('child_process').spawn
|
||||||
const toIco = require('to-ico')
|
const toIco = require('to-ico')
|
||||||
const sharp = require("sharp")
|
const sharp = require('sharp')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
|
||||||
const thisPath = path.resolve(__dirname)
|
const thisPath = path.resolve(__dirname)
|
||||||
@ -119,7 +131,6 @@ const root = path.resolve(thisPath,'..','..','..','..','..')
|
|||||||
const distPath = path.resolve(root, 'dist', 'icons')
|
const distPath = path.resolve(root, 'dist', 'icons')
|
||||||
const donePath = path.resolve(distPath, 'init')
|
const donePath = path.resolve(distPath, 'init')
|
||||||
|
|
||||||
|
|
||||||
async function genIcons() {
|
async function genIcons() {
|
||||||
let sizes = [16, 32, 64, 128, 256, 512, 1024]
|
let sizes = [16, 32, 64, 128, 256, 512, 1024]
|
||||||
let win_sizes = [16, 32, 64, 128, 256]
|
let win_sizes = [16, 32, 64, 128, 256]
|
||||||
@ -129,7 +140,7 @@ async function genIcons() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Generating SVG icons.")
|
console.log('Generating SVG icons.')
|
||||||
await fs.mkdir(path.resolve(distPath, 'svg'), { recursive: true })
|
await fs.mkdir(path.resolve(distPath, 'svg'), { recursive: true })
|
||||||
await fs.mkdir(path.resolve(distPath, 'png'), { recursive: true })
|
await fs.mkdir(path.resolve(distPath, 'png'), { recursive: true })
|
||||||
for (let size of sizes) {
|
for (let size of sizes) {
|
||||||
@ -141,38 +152,46 @@ async function genIcons() {
|
|||||||
/// AND KEEPS THE METADATA INFORMATION ABOUT DPI OF 144.
|
/// AND KEEPS THE METADATA INFORMATION ABOUT DPI OF 144.
|
||||||
/// It is required to properly display png images on MacOS.
|
/// It is required to properly display png images on MacOS.
|
||||||
/// There is currently no other way in `sharp` to do it.
|
/// There is currently no other way in `sharp` to do it.
|
||||||
console.log("Generating PNG icons.")
|
console.log('Generating PNG icons.')
|
||||||
for (let size of sizes) {
|
for (let size of sizes) {
|
||||||
let inName = `icon_${size}x${size}.svg`
|
let inName = `icon_${size}x${size}.svg`
|
||||||
let outName = `icon_${size}x${size}.png`
|
let outName = `icon_${size}x${size}.png`
|
||||||
await sharp(`${distPath}/svg/${inName}`,{density:144}).png().resize({
|
await sharp(`${distPath}/svg/${inName}`, { density: 144 })
|
||||||
|
.png()
|
||||||
|
.resize({
|
||||||
width: size,
|
width: size,
|
||||||
kernel : sharp.kernel.mitchell
|
kernel: sharp.kernel.mitchell,
|
||||||
}).toFile(`${distPath}/png/${outName}`)
|
})
|
||||||
|
.toFile(`${distPath}/png/${outName}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let size of sizes.slice(1)) {
|
for (let size of sizes.slice(1)) {
|
||||||
let size2 = size / 2
|
let size2 = size / 2
|
||||||
let inName = `icon_${size}x${size}.svg`
|
let inName = `icon_${size}x${size}.svg`
|
||||||
let outName = `icon_${size2}x${size2}@2x.png`
|
let outName = `icon_${size2}x${size2}@2x.png`
|
||||||
await sharp(`${distPath}/svg/${inName}`,{density:144}).png().resize({
|
await sharp(`${distPath}/svg/${inName}`, { density: 144 })
|
||||||
|
.png()
|
||||||
|
.resize({
|
||||||
width: size,
|
width: size,
|
||||||
kernel : sharp.kernel.mitchell
|
kernel: sharp.kernel.mitchell,
|
||||||
}).toFile(`${distPath}/png/${outName}`)
|
})
|
||||||
|
.toFile(`${distPath}/png/${outName}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Generating ICNS.")
|
console.log('Generating ICNS.')
|
||||||
exec(`cp -R ${distPath}/png ${distPath}/png.iconset`)
|
exec(`cp -R ${distPath}/png ${distPath}/png.iconset`)
|
||||||
exec(`iconutil --convert icns --output ${distPath}/icon.icns ${distPath}/png.iconset`)
|
exec(`iconutil --convert icns --output ${distPath}/icon.icns ${distPath}/png.iconset`)
|
||||||
|
|
||||||
console.log("Generating ICO.")
|
console.log('Generating ICO.')
|
||||||
let files = []
|
let files = []
|
||||||
for (let size of win_sizes) {
|
for (let size of win_sizes) {
|
||||||
let inName = `icon_${size}x${size}.png`
|
let inName = `icon_${size}x${size}.png`
|
||||||
let data = await fs.readFile(`${distPath}/png/${inName}`)
|
let data = await fs.readFile(`${distPath}/png/${inName}`)
|
||||||
files.push(data)
|
files.push(data)
|
||||||
}
|
}
|
||||||
toIco(files).then(buf => { fss.writeFileSync(`${distPath}/icon.ico`, buf) })
|
toIco(files).then(buf => {
|
||||||
|
fss.writeFileSync(`${distPath}/icon.ico`, buf)
|
||||||
|
})
|
||||||
|
|
||||||
let handle = await fs.open(donePath, 'w')
|
let handle = await fs.open(donePath, 'w')
|
||||||
await handle.close()
|
await handle.close()
|
||||||
|
@ -29,4 +29,3 @@
|
|||||||
"mock-fs": "^4.13.0"
|
"mock-fs": "^4.13.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -9,18 +9,14 @@ const yargs = require('yargs')
|
|||||||
|
|
||||||
const defaultPort = require('../../config.js').defaultLogServerPort
|
const defaultPort = require('../../config.js').defaultLogServerPort
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
startServer
|
startServer,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function main(argv) {
|
function main(argv) {
|
||||||
startServer(parse_args(argv).port)
|
startServer(parse_args(argv).port)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =================
|
// =================
|
||||||
// === Constants ===
|
// === Constants ===
|
||||||
// =================
|
// =================
|
||||||
@ -32,8 +28,6 @@ const httpStatusCodes = {
|
|||||||
internalServerError: 500,
|
internalServerError: 500,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ========================
|
// ========================
|
||||||
// === Argument Parsing ===
|
// === Argument Parsing ===
|
||||||
// ========================
|
// ========================
|
||||||
@ -46,15 +40,12 @@ function parse_args(argv) {
|
|||||||
'The number of the port that this server will listen on. ' +
|
'The number of the port that this server will listen on. ' +
|
||||||
'If the the number is 0 then an arbitrary free port will be chosen.',
|
'If the the number is 0 then an arbitrary free port will be chosen.',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
default: defaultPort
|
default: defaultPort,
|
||||||
})
|
})
|
||||||
.help()
|
.help()
|
||||||
.alias('help', 'h')
|
.alias('help', 'h').argv
|
||||||
.argv
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ==============
|
// ==============
|
||||||
// === Server ===
|
// === Server ===
|
||||||
// ==============
|
// ==============
|
||||||
@ -63,9 +54,11 @@ function startServer(port) {
|
|||||||
const app = express()
|
const app = express()
|
||||||
app.use(express.text())
|
app.use(express.text())
|
||||||
|
|
||||||
app.post("/", async (req, res) => {
|
app.post('/', async (req, res) => {
|
||||||
if (typeof req.headers.origin === 'undefined' ||
|
if (
|
||||||
(new URL(req.headers.origin).hostname) !== 'localhost') {
|
typeof req.headers.origin === 'undefined' ||
|
||||||
|
new URL(req.headers.origin).hostname !== 'localhost'
|
||||||
|
) {
|
||||||
res.sendStatus(httpStatusCodes.forbidden)
|
res.sendStatus(httpStatusCodes.forbidden)
|
||||||
} else if (typeof req.body !== 'string') {
|
} else if (typeof req.body !== 'string') {
|
||||||
res.sendStatus(httpStatusCodes.badRequest)
|
res.sendStatus(httpStatusCodes.badRequest)
|
||||||
@ -75,9 +68,7 @@ function startServer(port) {
|
|||||||
console.log(`Saved log from origin ${req.headers.origin}`)
|
console.log(`Saved log from origin ${req.headers.origin}`)
|
||||||
res.sendStatus(httpStatusCodes.noContent)
|
res.sendStatus(httpStatusCodes.noContent)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(
|
console.error('Could not write log file:\n' + e.message)
|
||||||
'Could not write log file:\n' +
|
|
||||||
e.message)
|
|
||||||
res.sendStatus(httpStatusCodes.internalServerError)
|
res.sendStatus(httpStatusCodes.internalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,8 +81,6 @@ function startServer(port) {
|
|||||||
return server
|
return server
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ==================
|
// ==================
|
||||||
// === File Utils ===
|
// === File Utils ===
|
||||||
// ==================
|
// ==================
|
||||||
@ -107,7 +96,6 @@ async function writeLog(message) {
|
|||||||
await fs.promises.writeFile(`${dir}/${file}`, message)
|
await fs.promises.writeFile(`${dir}/${file}`, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current UTC date and time in the format "yyy-MM-dd_HH:mm:ss.".
|
* Returns the current UTC date and time in the format "yyy-MM-dd_HH:mm:ss.".
|
||||||
*/
|
*/
|
||||||
@ -115,19 +103,16 @@ function timestamp() {
|
|||||||
const d = new Date()
|
const d = new Date()
|
||||||
|
|
||||||
const year = d.getUTCFullYear().toString()
|
const year = d.getUTCFullYear().toString()
|
||||||
const month = d.getUTCMonth().toString().padStart(2, "0")
|
const month = d.getUTCMonth().toString().padStart(2, '0')
|
||||||
const day = d.getUTCDate().toString().padStart(2, "0")
|
const day = d.getUTCDate().toString().padStart(2, '0')
|
||||||
|
|
||||||
const hour = d.getUTCHours().toString().padStart(2, "0")
|
const hour = d.getUTCHours().toString().padStart(2, '0')
|
||||||
const minute = d.getUTCMinutes().toString().padStart(2, "0")
|
const minute = d.getUTCMinutes().toString().padStart(2, '0')
|
||||||
const second = d.getUTCSeconds().toString().padStart(2, "0")
|
const second = d.getUTCSeconds().toString().padStart(2, '0')
|
||||||
|
|
||||||
return `${year}-${month}-${day}_${hour}:${minute}:${second}`
|
return `${year}-${month}-${day}_${hour}:${minute}:${second}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
const command_line_args = process.argv.slice(2)
|
const command_line_args = process.argv.slice(2)
|
||||||
main(command_line_args)
|
main(command_line_args)
|
||||||
|
@ -6,11 +6,7 @@ const path = require('path')
|
|||||||
|
|
||||||
const { startServer } = require('../server')
|
const { startServer } = require('../server')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
describe('Logging Server', function () {
|
describe('Logging Server', function () {
|
||||||
|
|
||||||
let server
|
let server
|
||||||
let serverUrl
|
let serverUrl
|
||||||
|
|
||||||
@ -18,20 +14,20 @@ describe('Logging Server', function () {
|
|||||||
const goodConfig = {
|
const goodConfig = {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'text/plain',
|
'Content-Type': 'text/plain',
|
||||||
'Origin': 'http://localhost/'
|
Origin: 'http://localhost/',
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
const wrongOriginConfig = {
|
const wrongOriginConfig = {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'text/plain',
|
'Content-Type': 'text/plain',
|
||||||
'Origin': 'http://attacker/'
|
Origin: 'http://attacker/',
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
const wrongContentTypeConfig = {
|
const wrongContentTypeConfig = {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'image/jpeg',
|
'Content-Type': 'image/jpeg',
|
||||||
'Origin': 'http://localhost/'
|
Origin: 'http://localhost/',
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(function (done) {
|
beforeEach(function (done) {
|
||||||
@ -41,7 +37,7 @@ describe('Logging Server', function () {
|
|||||||
|
|
||||||
// We mock the file system so the server does not actually write logs to disk.
|
// We mock the file system so the server does not actually write logs to disk.
|
||||||
mockFs({
|
mockFs({
|
||||||
[rawBodyDir]: mockFs.load(rawBodyDir)
|
[rawBodyDir]: mockFs.load(rawBodyDir),
|
||||||
})
|
})
|
||||||
|
|
||||||
const port = 0 // Choose an arbitrary available port
|
const port = 0 // Choose an arbitrary available port
|
||||||
@ -74,12 +70,11 @@ describe('Logging Server', function () {
|
|||||||
await Promise.allSettled([
|
await Promise.allSettled([
|
||||||
axios.post(serverUrl, '', goodConfig),
|
axios.post(serverUrl, '', goodConfig),
|
||||||
axios.post(serverUrl, '', wrongOriginConfig),
|
axios.post(serverUrl, '', wrongOriginConfig),
|
||||||
axios.post(serverUrl, '', wrongContentTypeConfig)
|
axios.post(serverUrl, '', wrongContentTypeConfig),
|
||||||
])
|
])
|
||||||
|
|
||||||
await axios.post(serverUrl, dummyMessage, goodConfig)
|
await axios.post(serverUrl, dummyMessage, goodConfig)
|
||||||
const log_files = fs.readdirSync('log/')
|
const log_files = fs.readdirSync('log/')
|
||||||
assert(log_files.some(file =>
|
assert(log_files.some(file => fs.readFileSync(`log/${file}`).toString() === dummyMessage))
|
||||||
fs.readFileSync(`log/${file}`).toString() === dummyMessage))
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
let config = {
|
let config = {
|
||||||
name: 'enso-studio-project-manager',
|
name: 'enso-studio-project-manager',
|
||||||
version: "1.0.0",
|
version: '1.0.0',
|
||||||
scripts: {
|
scripts: {
|
||||||
build: 'npx ts-node src/build.ts',
|
build: 'npx ts-node src/build.ts',
|
||||||
},
|
},
|
||||||
|
@ -39,7 +39,10 @@ async function get_build_config() {
|
|||||||
// === Project Manager ===
|
// === Project Manager ===
|
||||||
// =======================
|
// =======================
|
||||||
|
|
||||||
interface BuildInfo { version: string, target: string }
|
interface BuildInfo {
|
||||||
|
version: string
|
||||||
|
target: string
|
||||||
|
}
|
||||||
|
|
||||||
function get_project_manager_url({ version, target }: BuildInfo): string {
|
function get_project_manager_url({ version, target }: BuildInfo): string {
|
||||||
console.log('webpack target ' + target)
|
console.log('webpack target ' + target)
|
||||||
@ -145,7 +148,8 @@ async function download_project_manager(file_url: string, overwrite: boolean): P
|
|||||||
const target_file = fss.createWriteStream(file_path)
|
const target_file = fss.createWriteStream(file_path)
|
||||||
const progress_indicator = new DownloadProgressIndicator()
|
const progress_indicator = new DownloadProgressIndicator()
|
||||||
await new Promise((resolve, reject) =>
|
await new Promise((resolve, reject) =>
|
||||||
http.get(options, (res: IncomingMessage) => {
|
http
|
||||||
|
.get(options, (res: IncomingMessage) => {
|
||||||
res.on('data', (data: string) => {
|
res.on('data', (data: string) => {
|
||||||
target_file.write(data)
|
target_file.write(data)
|
||||||
progress_indicator.add_progress_bytes(data.length)
|
progress_indicator.add_progress_bytes(data.length)
|
||||||
@ -154,7 +158,8 @@ async function download_project_manager(file_url: string, overwrite: boolean): P
|
|||||||
console.log(`${file_url} downloaded to "${file_path}".`)
|
console.log(`${file_url} downloaded to "${file_path}".`)
|
||||||
resolve(undefined)
|
resolve(undefined)
|
||||||
})
|
})
|
||||||
}).on('error', async (e: http.ClientRequest) => {
|
})
|
||||||
|
.on('error', async (e: http.ClientRequest) => {
|
||||||
target_file.end()
|
target_file.end()
|
||||||
await fs.rm(file_path)
|
await fs.rm(file_path)
|
||||||
reject('Error: The download of the project manager was interrupted:\n' + e)
|
reject('Error: The download of the project manager was interrupted:\n' + e)
|
||||||
@ -193,9 +198,10 @@ async function main() {
|
|||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (buildInfo.version !== existing_build_info?.version ||
|
if (
|
||||||
buildInfo.target !== existing_build_info?.target) {
|
buildInfo.version !== existing_build_info?.version ||
|
||||||
|
buildInfo.target !== existing_build_info?.target
|
||||||
|
) {
|
||||||
// We remove the build info file to avoid misinformation if the build is interrupted during
|
// We remove the build info file to avoid misinformation if the build is interrupted during
|
||||||
// the call to `download_project_manager`.
|
// the call to `download_project_manager`.
|
||||||
// We use `force: true` because the file might not exist.
|
// We use `force: true` because the file might not exist.
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
/// which scans the GLSL code and mangles all names of primitive functions. This way we can define
|
/// which scans the GLSL code and mangles all names of primitive functions. This way we can define
|
||||||
/// overloaded functions the same way as we did in GLSL 100.
|
/// overloaded functions the same way as we did in GLSL 100.
|
||||||
|
|
||||||
let builtins =
|
let builtins = `float radians(float degrees)
|
||||||
`float radians(float degrees)
|
|
||||||
vec2 radians(vec2 degrees)
|
vec2 radians(vec2 degrees)
|
||||||
vec3 radians(vec3 degrees)
|
vec3 radians(vec3 degrees)
|
||||||
vec4 radians(vec4 degrees)
|
vec4 radians(vec4 degrees)
|
||||||
@ -223,8 +222,9 @@ function redirect_builtins() {
|
|||||||
let argsStr = match[3]
|
let argsStr = match[3]
|
||||||
let args = argsStr.split(', ').map(v => v.split(' '))
|
let args = argsStr.split(', ').map(v => v.split(' '))
|
||||||
let argNames = args.map(a => a[1])
|
let argNames = args.map(a => a[1])
|
||||||
let redirection =
|
let redirection = `${outType} overloaded_${fname} (${argsStr}) {return ${fname}(${argNames.join(
|
||||||
`${outType} overloaded_${fname} (${argsStr}) {return ${fname}(${argNames.join(',')});}`
|
','
|
||||||
|
)});}`
|
||||||
names.push(fname)
|
names.push(fname)
|
||||||
redirections.push(redirection)
|
redirections.push(redirection)
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ export class TextInputHandlers {
|
|||||||
this.text_area.focus()
|
this.text_area.focus()
|
||||||
this.bind_text_area_events()
|
this.bind_text_area_events()
|
||||||
this.bind_window_events()
|
this.bind_window_events()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set event handler. The name can be 'keyup' or 'keydown'.
|
// Set event handler. The name can be 'keyup' or 'keydown'.
|
||||||
@ -46,11 +45,15 @@ export class TextInputHandlers {
|
|||||||
bind_text_area_events() {
|
bind_text_area_events() {
|
||||||
this.text_area.addEventListener('cut', e => {
|
this.text_area.addEventListener('cut', e => {
|
||||||
// Clear textarea in next frame (after cutting).
|
// Clear textarea in next frame (after cutting).
|
||||||
setTimeout(_ => {this.text_area.value = "";}, 0)
|
setTimeout(_ => {
|
||||||
|
this.text_area.value = ''
|
||||||
|
}, 0)
|
||||||
})
|
})
|
||||||
this.text_area.addEventListener('copy', e => {
|
this.text_area.addEventListener('copy', e => {
|
||||||
// Clear textarea in next frame (after copying).
|
// Clear textarea in next frame (after copying).
|
||||||
setTimeout(_ => {this.text_area.value = "";}, 0)
|
setTimeout(_ => {
|
||||||
|
this.text_area.value = ''
|
||||||
|
}, 0)
|
||||||
})
|
})
|
||||||
this.text_area.addEventListener('paste', e => {
|
this.text_area.addEventListener('paste', e => {
|
||||||
if (typeof this.paste_handler !== 'undefined') {
|
if (typeof this.paste_handler !== 'undefined') {
|
||||||
@ -67,7 +70,7 @@ export class TextInputHandlers {
|
|||||||
this.text_area.focus()
|
this.text_area.focus()
|
||||||
})
|
})
|
||||||
this.text_area.addEventListener('keydown', e => {
|
this.text_area.addEventListener('keydown', e => {
|
||||||
let code = e.keyCode;
|
let code = e.keyCode
|
||||||
|
|
||||||
let is_cut = code === 88 && (e.metaKey || e.ctrlKey)
|
let is_cut = code === 88 && (e.metaKey || e.ctrlKey)
|
||||||
let is_copy = code === 67 && (e.metaKey || e.ctrlKey)
|
let is_copy = code === 67 && (e.metaKey || e.ctrlKey)
|
||||||
@ -75,8 +78,8 @@ export class TextInputHandlers {
|
|||||||
if (is_copy || is_cut) {
|
if (is_copy || is_cut) {
|
||||||
if (typeof this.copy_handler !== 'undefined') {
|
if (typeof this.copy_handler !== 'undefined') {
|
||||||
this.text_area.value = this.copy_handler(is_cut)
|
this.text_area.value = this.copy_handler(is_cut)
|
||||||
this.text_area.selectionStart = 0;
|
this.text_area.selectionStart = 0
|
||||||
this.text_area.selectionEnd = this.text_area.value.length;
|
this.text_area.selectionEnd = this.text_area.value.length
|
||||||
} else {
|
} else {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
}
|
}
|
||||||
@ -107,7 +110,7 @@ export class TextInputHandlers {
|
|||||||
|
|
||||||
// Creates invisible textarea.
|
// Creates invisible textarea.
|
||||||
function create_invisible_text_area() {
|
function create_invisible_text_area() {
|
||||||
const css_class_name = "enso";
|
const css_class_name = 'enso'
|
||||||
|
|
||||||
let text_area = document.createElement('textarea')
|
let text_area = document.createElement('textarea')
|
||||||
text_area.className = css_class_name
|
text_area.className = css_class_name
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
{
|
{
|
||||||
"goog:chromeOptions": {
|
"goog:chromeOptions": {
|
||||||
"args": [
|
"args": ["--no-proxy-server", "--no-sandbox"]
|
||||||
"--no-proxy-server",
|
|
||||||
"--no-sandbox"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -25,10 +25,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@keyframes sk-bouncedelay {
|
@keyframes sk-bouncedelay {
|
||||||
0%, 80%, 100% {
|
0%,
|
||||||
|
80%,
|
||||||
|
100% {
|
||||||
transform: scale(0);
|
transform: scale(0);
|
||||||
} 40% {
|
}
|
||||||
transform: scale(1.0);
|
40% {
|
||||||
|
transform: scale(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
function fallbackWriteText(text) {
|
function fallbackWriteText(text) {
|
||||||
let successful = false
|
let successful = false
|
||||||
let textArea = document.createElement("textarea")
|
let textArea = document.createElement('textarea')
|
||||||
|
|
||||||
// *** This styling is an extra step which is likely not required. ***
|
// *** This styling is an extra step which is likely not required. ***
|
||||||
//
|
//
|
||||||
@ -44,14 +44,15 @@ function fallbackWriteText(text) {
|
|||||||
textArea.style.background = 'transparent'
|
textArea.style.background = 'transparent'
|
||||||
|
|
||||||
textArea.value = text
|
textArea.value = text
|
||||||
textArea.style.top = "0"
|
textArea.style.top = '0'
|
||||||
textArea.style.left = "0"
|
textArea.style.left = '0'
|
||||||
textArea.style.position = "fixed"
|
textArea.style.position = 'fixed'
|
||||||
document.body.appendChild(textArea)
|
document.body.appendChild(textArea)
|
||||||
textArea.focus()
|
textArea.focus()
|
||||||
textArea.select()
|
textArea.select()
|
||||||
try { successful = document.execCommand('copy') == 1 }
|
try {
|
||||||
catch (err) {}
|
successful = document.execCommand('copy') == 1
|
||||||
|
} catch (err) {}
|
||||||
document.body.removeChild(textArea)
|
document.body.removeChild(textArea)
|
||||||
if (!successful) {
|
if (!successful) {
|
||||||
console.error('Could not write to clipboard.')
|
console.error('Could not write to clipboard.')
|
||||||
@ -62,18 +63,21 @@ export function writeText(text) {
|
|||||||
if (!navigator.clipboard) {
|
if (!navigator.clipboard) {
|
||||||
fallbackWriteText(text)
|
fallbackWriteText(text)
|
||||||
} else {
|
} else {
|
||||||
navigator.clipboard.writeText(text).then(() => {}, (err) => {
|
navigator.clipboard.writeText(text).then(
|
||||||
|
() => {},
|
||||||
|
err => {
|
||||||
fallbackWriteText(text)
|
fallbackWriteText(text)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Firefox only supports reading the clipboard in browser extensions, so it will
|
/// Firefox only supports reading the clipboard in browser extensions, so it will
|
||||||
/// only work with `cmd + v` shortcut. To learn more, see the
|
/// only work with `cmd + v` shortcut. To learn more, see the
|
||||||
/// [MSDN compatibility note](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/readText).
|
/// [MSDN compatibility note](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/readText).
|
||||||
let lastPaste = ""
|
let lastPaste = ''
|
||||||
function init_firefox_fallback() {
|
function init_firefox_fallback() {
|
||||||
window.addEventListener('paste', (event) => {
|
window.addEventListener('paste', event => {
|
||||||
lastPaste = (event.clipboardData || window.clipboardData).getData('text')
|
lastPaste = (event.clipboardData || window.clipboardData).getData('text')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -82,16 +86,17 @@ export function readText(callback) {
|
|||||||
if (!navigator.clipboard) {
|
if (!navigator.clipboard) {
|
||||||
callback(lastPaste)
|
callback(lastPaste)
|
||||||
} else {
|
} else {
|
||||||
navigator.clipboard.readText().then(function(text) {
|
navigator.clipboard.readText().then(
|
||||||
|
function (text) {
|
||||||
callback(text)
|
callback(text)
|
||||||
}, function(err) {
|
},
|
||||||
|
function (err) {
|
||||||
callback(lastPaste)
|
callback(lastPaste)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ======================
|
// ======================
|
||||||
// === Initialization ===
|
// === Initialization ===
|
||||||
// ======================
|
// ======================
|
||||||
|
@ -32,7 +32,6 @@ class IxPool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============
|
// ============
|
||||||
// === Pool ===
|
// === Pool ===
|
||||||
// ============
|
// ============
|
||||||
@ -40,7 +39,7 @@ class IxPool {
|
|||||||
class Pool {
|
class Pool {
|
||||||
constructor(cons) {
|
constructor(cons) {
|
||||||
this.cons = cons
|
this.cons = cons
|
||||||
this.ixs = new IxPool
|
this.ixs = new IxPool()
|
||||||
}
|
}
|
||||||
|
|
||||||
reserve(...args) {
|
reserve(...args) {
|
||||||
@ -55,13 +54,11 @@ class Pool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============================
|
// ============================
|
||||||
// === IntersectionObserver ===
|
// === IntersectionObserver ===
|
||||||
// ============================
|
// ============================
|
||||||
|
|
||||||
let intersectionObserverPool =
|
let intersectionObserverPool = new Pool((...args) => new IntersectionObserver(...args))
|
||||||
new Pool((...args) => new IntersectionObserver(...args))
|
|
||||||
|
|
||||||
export function intersection_observe(target, f) {
|
export function intersection_observe(target, f) {
|
||||||
let id = intersectionObserverPool.reserve(intersection_observer_update(f))
|
let id = intersectionObserverPool.reserve(intersection_observer_update(f))
|
||||||
@ -76,7 +73,7 @@ export function intersection_unobserve(id) {
|
|||||||
|
|
||||||
function intersection_observer_update(f) {
|
function intersection_observer_update(f) {
|
||||||
return entries => {
|
return entries => {
|
||||||
let rect = entries[0].boundingClientRect;
|
let rect = entries[0].boundingClientRect
|
||||||
f(rect.x, rect.y, rect.width, rect.height);
|
f(rect.x, rect.y, rect.width, rect.height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@ class IxPool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============
|
// ============
|
||||||
// === Pool ===
|
// === Pool ===
|
||||||
// ============
|
// ============
|
||||||
@ -32,7 +31,7 @@ class IxPool {
|
|||||||
class Pool {
|
class Pool {
|
||||||
constructor(cons) {
|
constructor(cons) {
|
||||||
this.cons = cons
|
this.cons = cons
|
||||||
this.ixs = new IxPool
|
this.ixs = new IxPool()
|
||||||
}
|
}
|
||||||
|
|
||||||
reserve(...args) {
|
reserve(...args) {
|
||||||
@ -47,7 +46,6 @@ class Pool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ======================
|
// ======================
|
||||||
// === ResizeObserver ===
|
// === ResizeObserver ===
|
||||||
// ======================
|
// ======================
|
||||||
@ -67,7 +65,7 @@ export function resize_unobserve(id) {
|
|||||||
|
|
||||||
function resize_observer_update(f) {
|
function resize_observer_update(f) {
|
||||||
return entries => {
|
return entries => {
|
||||||
let rect = entries[0].contentRect;
|
let rect = entries[0].contentRect
|
||||||
f(rect.width, rect.height);
|
f(rect.width, rect.height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user