mirror of
https://github.com/aljazceru/pear-docs.git
synced 2025-12-17 22:44:21 +01:00
pear cli installation functionality
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -1,18 +1,41 @@
|
|||||||
|
/* eslint-env browser */
|
||||||
|
import os from 'os'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
import { spawn } from 'child_process'
|
||||||
import { config } from 'pear'
|
import { config } from 'pear'
|
||||||
|
|
||||||
const pearBin = path.join(config.pearDir, 'bin')
|
const BIN = path.join(config.pearDir, 'bin')
|
||||||
|
const isWin = process.platform === 'win32'
|
||||||
|
|
||||||
const paths = process.env.PATH.split(path.delimiter)
|
customElements.define('pear-welcome', class extends HTMLElement {
|
||||||
|
constructor () {
|
||||||
|
super()
|
||||||
|
this.template = document.createElement('template')
|
||||||
|
this.template.innerHTML = `
|
||||||
|
<blockquote>
|
||||||
|
<p>Pear is installed.</p>
|
||||||
|
</blockquote>
|
||||||
|
<p>✔ Pear is in the system PATH and ready to go.</p>
|
||||||
|
`
|
||||||
|
this.root = this.attachShadow({ mode: 'open' })
|
||||||
|
|
||||||
|
this.root.appendChild(this.template.content.cloneNode(true))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
customElements.define('system-status', class extends HTMLElement {
|
customElements.define('system-status', class extends HTMLElement {
|
||||||
constructor () {
|
constructor () {
|
||||||
super()
|
super()
|
||||||
this.vianode = false
|
this.zsh = false
|
||||||
this.installed = paths.some((p) => {
|
this.bash = false
|
||||||
if (p.includes('node') && p.includes('bin')) this.vianode = fs.existsSync(path.join(p, 'pear'))
|
this.paths = process.env.PATH.split(path.delimiter)
|
||||||
return p === pearBin
|
this.installed = this.paths.some((bin) => {
|
||||||
|
if (isWin === false) {
|
||||||
|
if (this.zsh === false && fs.existsSync(path.join(bin, 'zsh'))) this.zsh = true
|
||||||
|
if (this.bash === false && fs.existsSync(path.join(bin, 'bash'))) this.bash = true
|
||||||
|
}
|
||||||
|
return bin === BIN && fs.existsSync(path.join(BIN, isWin ? 'pear.cmd' : 'pear'))
|
||||||
})
|
})
|
||||||
this.template = document.createElement('template')
|
this.template = document.createElement('template')
|
||||||
this.template.innerHTML = `
|
this.template.innerHTML = `
|
||||||
@@ -38,17 +61,14 @@ customElements.define('system-status', class extends HTMLElement {
|
|||||||
</style>
|
</style>
|
||||||
<h1>System Status</h1>
|
<h1>System Status</h1>
|
||||||
${
|
${
|
||||||
this.installed ? `
|
this.installed
|
||||||
<blockquote>
|
? '<pear-welcome></pear-welcome>'
|
||||||
<p>Pear is installed.</p>
|
: `
|
||||||
</blockquote>
|
|
||||||
<p>✔ Pear is in the system PATH and ready to go.</p>
|
|
||||||
` : `
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>Pear setup is nearly complete.</p>
|
<p>Pear setup is nearly complete.</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<p><button> Complete Pear Setup </button><p>
|
<p><button> Complete Pear Setup </button><p>
|
||||||
<p id=tip><small>Click the button to add </small><code>${pearBin}</code><small> to the system PATH<small></p>
|
<p id=tip><small>Click the button to add </small><code>${BIN}</code><small> to the system PATH<small></p>
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@@ -62,11 +82,71 @@ customElements.define('system-status', class extends HTMLElement {
|
|||||||
if (this.button) {
|
if (this.button) {
|
||||||
const listener = () => {
|
const listener = () => {
|
||||||
this.button.removeEventListener('click', listener)
|
this.button.removeEventListener('click', listener)
|
||||||
|
this.#installPear()
|
||||||
|
.then(() => {
|
||||||
|
this.replaceWith(new this.constructor())
|
||||||
|
console.log('now show version info, and a gif showing pear command line help output run through')
|
||||||
|
})
|
||||||
|
.catch((err) => this.#error(err))
|
||||||
}
|
}
|
||||||
this.button.addEventListener('click', listener)
|
this.button.addEventListener('click', listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#error (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
#installPear () {
|
||||||
|
const runtime = path.join(config.pearDir, 'current', 'by-arch', process.platform + '-' + process.arch, 'bin', 'bare', 'pear')
|
||||||
|
fs.mkdirSync(BIN, { recursive: true })
|
||||||
|
if (isWin) {
|
||||||
|
const ps1tmp = path.join(BIN, Math.floor(Math.random() * 1000) + '.pear')
|
||||||
|
fs.writeFileSync(ps1tmp, `function pear { & "${runtime}" }; Export-ModuleMember -Function pear`)
|
||||||
|
fs.renameSync(ps1tmp, path.join(BIN, 'pear.ps1'))
|
||||||
|
const cmdtmp = path.join(BIN, Math.floor(Math.random() * 1000) + '.pear')
|
||||||
|
fs.writeFileSync(cmdtmp, `@echo off\n"${runtime}" %*`)
|
||||||
|
fs.renameSync(cmdtmp, path.join(BIN, 'pear.cmd'))
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
spawn('cmd', ['/c', `setx PATH "${BIN};%PATH%"`]).on('exit', (code) => {
|
||||||
|
const codes = [code]
|
||||||
|
spawn('powershell', ['-Command', `$env:PATH = "${BIN};$env:PATH"`]).on('exit', (code) => {
|
||||||
|
codes.push(code)
|
||||||
|
if (codes[0] + codes[1] !== 0) {
|
||||||
|
reject(new Error(
|
||||||
|
'Failed to set PATH in' + [
|
||||||
|
codes[0] ? ' cmd - exit code: ' + codes[0] : '',
|
||||||
|
codes[1] ? ' powershell - exit code:' + codes[1] : ''
|
||||||
|
].filter(Boolean)
|
||||||
|
))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
process.env.PATH = `${BIN};${process.env.PATH}`
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const pear = path.join(BIN, 'pear')
|
||||||
|
const tmp = path.join(BIN, Math.floor(Math.random() * 1000) + '.pear')
|
||||||
|
fs.symlinkSync(runtime, tmp)
|
||||||
|
fs.renameSync(tmp, pear)
|
||||||
|
fs.chmodSync(pear, 0o755)
|
||||||
|
|
||||||
|
let shellProfileExists = false
|
||||||
|
const statement = `\nexport PATH="${BIN}":$PATH\n`
|
||||||
|
for (const file of ['.zshrc', '.zshenv', '.zshprofile', '.zlogin', '.profile', '.bashrc']) {
|
||||||
|
const filepath = path.join(os.homedir(), file)
|
||||||
|
if (fs.existsSync(filepath)) {
|
||||||
|
fs.writeFileSync(filepath, statement, { flag: 'a' })
|
||||||
|
shellProfileExists = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (shellProfileExists === false) {
|
||||||
|
fs.writeFileSync(path.join(os.homedir(), this.bash ? '.bashrc' : '.profile'), statement, { flag: 'a' })
|
||||||
|
if (this.zsh) fs.writeFileSync(path.join(os.homedir(), '.zshrc'), statement, { flag: 'a' })
|
||||||
|
}
|
||||||
|
process.env.PATH = `${BIN}:${process.env.PATH}`
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user