An interactive command-line interface (CLI) tool to help you install, use, and administer an AO instance.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

140 lines
4.8 KiB

import { execSync } from 'child_process'
import { fileURLToPath } from 'url'
import path from 'path'
import fs from 'fs'
import { loadJsonFile } from '../files.js'
// Can't include .json files without adding an experimental node flag, but we can use this workaround to use require, which works, instead
import { createRequire } from "module"; // Bring in the ability to create the 'require' method
const require = createRequire(import.meta.url); // construct the require method
const packageVersion = require("../../package.json").version
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
// Returns one of: off, installed, enabled, running, synced, error
function cliStatus() {
try {
const stdout = execSync('npm list -g @autonomousorganization/ao-cli')
const isAoCliInstalled = stdout.includes('@autonomousorganization/ao-cli@')
if(isAoCliInstalled) return 'installed'
} catch(err) {
return 'error'
}
return 'off'
}
// It is possible to run ao-cli with npx @autonomousorganization/ao-cli. In this case, it can help you install it permanently.
function installAoCli() {
try {
execSync('npm i -g @autonomousorganization/ao-cli 2>&1')
console.log('Installed ao-cli.')
} catch(err) {
console.log('Error installing ao-cli:', err)
}
}
async function getAoCliVersion() {
const npmGlobalPackagesPath = execSync('npm root -g').toString().replace(/\n/, '')
const aoGlobalPackagePath = path.join(npmGlobalPackagesPath, '@autonomousorganization/ao-cli/package.json')
let jsonFileContents
try {
const contents = fs.readFileSync(aoGlobalPackagePath)
jsonFileContents = JSON.parse(contents)
} catch(err) {
if(err.code === 'ENOENT') {
console.log('The global ao-cli package.json file does not exist.')
} else {
console.log('Unknown error loading global ao-cli package.json file, aborting.', err)
}
return null
}
if(!jsonFileContents.hasOwnProperty('version')) {
return null
}
return jsonFileContents.version
}
// Updates the globally-installed version of this package, ao-cli, using npm
async function selfUpdate() {
try {
const beforeVersionNumber = await getAoCliVersion()
const result = execSync('npm update -g @autonomousorganization/ao-cli 2>&1')
const afterVersionNumber = await getAoCliVersion()
if(beforeVersionNumber === afterVersionNumber) {
console.log("ao-cli version is already current.")
} else {
console.log('\nao-cli self-updated automatically from version', beforeVersionNumber, 'to version', afterVersionNumber, 'from the official npm repository.')
}
} catch (err) {
console.log('Failed to update ao-cli: ', err)
}
}
// Returns true if the 'ao' alias for ao-cli has already been addded to .bashrc
function checkAoAlias() {
try {
execSync('grep "ao=ao-cli" ~/.bashrc')
} catch(err) {
return 'off'
}
return 'installed'
}
// Adds a line to .bashrc to make 'ao' an alias for 'ao-cli', to simplify using the AO from the command line
function installAoAlias() {
try {
execSync('echo alias ao=ao-cli >> $HOME/.bashrc')
console.log('Added alias line to ~/.bashrc. You can now type \'ao\' to launch ao-cli.')
} catch(err) {
console.log('Failed to add alias, sorry.')
}
}
// Returns true if the cd hook function has already been addded to .bashrc
function checkCdHook() {
try {
execSync('grep "function cd \{ builtin cd.*--interstitial.* ; \}$" ~/\.bashrc')
} catch(err) {
return 'off'
}
return 'installed'
}
// Adds a line to .bashrc to make 'ao' an alias for 'ao-cli', to simplify using the AO from the command line
function installCdHook() {
try {
execSync('echo \'function cd { builtin cd "\$@" && node \~/ao-cli \-\-interstitial "\$\@" ; }\' >> $HOME/.bashrc')
console.log('Added alias line to ~/.bashrc. Try typing \'cd\' in a terminal.')
} catch(err) {
console.log('Failed to add alias, sorry.')
}
}
function removeCdHook() {
try {
let result = execSync('sed -i \'/^function cd.*/d\' ' + process.env.HOME + '/.bashrc')
console.log('sed:', result.toString())
} catch(error) {
console.log(error.output.toString())
}
}
export default {
description: 'this AO command-line interface',
status: cliStatus,
install: installAoCli,
version: getAoCliVersion,
update: selfUpdate,
add_alias: installAoAlias,
remove_alias: () => console.log("Not implemented yet."),
add_cd: installCdHook,
remove_cd: removeCdHook,
menu: [
{ name: () => checkAoAlias() === 'installed' ? 'Remove \'ao\' shortcut for \'ao-cli\'' : 'Install \'ao\' shortcut for \'ao-cli\'',
value: () => checkAoAlias() === 'installed' ? 'remove_alias' : 'add_alias' },
{ name: () => checkCdHook() === 'installed' ? 'Remove \'cd\' fantasy hook' : 'Install \'cd\' fantasy hook',
value: () => checkCdHook() === 'installed' ? 'remove_cd' : 'add_cd' },
]
}