Add git.clone and git.checkout states

This commit is contained in:
garrettmills 2020-03-05 11:48:38 -06:00
parent 904a4be1b1
commit 9dc6f9d214
No known key found for this signature in database
GPG Key ID: 6ACD58D6ADACFC6E
5 changed files with 97 additions and 1 deletions

View File

@ -62,6 +62,20 @@ class Repository extends Injectable {
await this._git_cmd(`checkout "${ref}"`)
}
async current_branch() {
const cd_cmd = await this._host.get_directory_change_command(this._path)
const cmd = `${cd_cmd} && git symbolic-ref HEAD`
const full_ref = await this._host.run_line_result(cmd)
return full_ref.replace('refs/heads/', '')
}
async current_ref() {
const cd_cmd = await this._host.get_directory_change_command(this._path)
const cmd = `${cd_cmd} && git show-ref HEAD`
const ref = await this._host.run_line_result(cmd)
return ref.split(' ')[0]
}
async stash() {
await this._git_cmd(`stash`)
}

View File

@ -0,0 +1,45 @@
const State = require('../State')
const Repository = require('../../git/Repository')
class CheckoutState extends State {
static get services() {
return [...super.services, 'output']
}
async apply() {
if ( !(await this.check()) ) {
const repo = await this._repo()
await repo.checkout(this._config.target)
}
}
async check() {
const repo = await this._repo()
const target = await this._config.target
try {
if ( (await repo.current_branch()) === target ) return true
if ( (await repo.current_ref()) === target ) return true
} catch (e) {}
return false
}
async reverse() {
if ( this._config.revert_to ) {
if ( await this.check() ) {
const repo = await this._repo()
await repo.checkout(this._config.revert_to)
}
} else {
this.output.warn('Checkout state does not currently support automatic reversal. Specify the revert_to config key to enable.')
}
}
async _repo() {
const path = await this._host.get_path(this._config.path)
if ( !path.is_valid() ) await path.touch(true)
return new Repository(path)
}
}
module.exports = exports = CheckoutState

View File

@ -0,0 +1,33 @@
const State = require('../State')
const Repository = require('../../git/Repository')
class CloneState extends State {
async apply() {
if ( !(await this.check()) ) {
const repo = await this._repo()
await repo.clone(this._config.source)
}
}
async check() {
const repo = await this._repo()
return repo.is_repo()
}
async reverse() {
if ( await this.check() ) {
const path = await this._host.get_path(this._config.path)
await path.unlink()
}
}
async _repo() {
const path = await this._host.get_path(this._config.path)
if ( !path.is_valid() ) await path.touch(true)
return new Repository(path)
}
}
module.exports = exports = CloneState

View File

@ -18,6 +18,8 @@ class CommandState extends State {
if ( this._config.reverse ) {
const cmd = `${this._config.reverse}`
await this._host.run(cmd)
} else {
this.output.warn(`No reversal command specified for Command State. Nothing was changed. (Host: ${this._host.name})`)
}
}

View File

@ -14,7 +14,6 @@ class StatesService extends Service {
// TODO apache and nginx states - virtual host, reverse proxy
// TODO package repository states - import keys, install repository
// TODO service manager states - service enabled, service installed, stopped
// TODO git states - clone repo, ref checked out
// TODO package states - uninstalled
'fs.file': require('../classes/state/fs/FileState'),
@ -24,6 +23,9 @@ class StatesService extends Service {
'fs.permission': require('../classes/state/fs/PermissionState'),
'fs.ownership': require('../classes/state/fs/OwnerState'),
'git.clone': require('../classes/state/git/CloneState'),
'git.checkout': require('../classes/state/git/CheckoutState'),
'os.cmd': require('../classes/state/os/CommandState'),
'package.present': require('../classes/state/os/PackageState'),