~siegfriedehret/brrr

ca949a75ca071821619dac72e9d5ec77a5faf364 — Siegfried Ehret 2 years ago 9fd5bc0
🎁 allow to uninstall a package
M Makefile => Makefile +1 -0
@@ 10,6 10,7 @@ format: ## Format files using nimpretty
	nimpretty src/**/*.nim

run: build ## Run brrr
	./brrr uninstall exa ;\
	./brrr install exa

help: ## Print this message

M src/commands/install.nim => src/commands/install.nim +7 -9
@@ 2,13 2,11 @@ import std/[algorithm, httpclient, osproc, sequtils, strutils,
    sugar, tables, times]
import ../lib/[common, repository, stash, types, utils]

const star = "*"

proc getFilename(url: string): string =
  let splits = rsplit(url, "/", maxsplit = 1)
  return splits[1]

proc downloadPackage(url: string, filename: string,
proc downloadPackage(url, filename: string,
    targetDir: string = "/tmp/") =
  log("Downloading " & url)
  try:


@@ 17,22 15,22 @@ proc downloadPackage(url: string, filename: string,
  except IOError:
    log("Failed to fetch package")

proc downloadVersion(brrrFile: BrrrFile, packageVersion: string,
    installVersion: string, arch: string) =
proc downloadVersion(brrrFile: BrrrFile, packageVersion,
    installVersion, arch: string) =
  let templateVersion = brrrFile.versions[installVersion]
  let downloadUrl = brrrFile.templates[templateVersion][arch].url.multiReplace((
      "{brrr_package_version}", packageVersion))
  let filename = getFilename(downloadUrl)
  downloadPackage(downloadUrl, filename, getPackageDir(brrrFile.name))

proc runScripts(pkgDef: BrrrFile, packageVersion: string,
    installVersion: string, arch: string) =
proc runScripts(pkgDef: BrrrFile, packageVersion,
    installVersion, arch: string) =
  let templateVersion = pkgDef.versions[installVersion]
  for script in pkgDef.templates[templateVersion][arch].install:
    let runScript = script.multiReplace(
      ("{brrr_package_version}", packageVersion),
      ("{brrr_from}", getPackageDir(pkgDef.name)),
      ("{brrr_to}", getBrrrBinDir()))
      ("{brrr_pkgdir}", getPackageDir(pkgDef.name)),
      ("{brrr_bin}", getBrrrBinDir()))
    log("Running script: " & runScript)
    let logs = execCmdEx(runScript, workingDir = getPackageDir(pkgDef.name))
    log(logs[0], 2)

A src/commands/uninstall.nim => src/commands/uninstall.nim +46 -0
@@ 0,0 1,46 @@
import std/[osproc, strutils, tables, times]
import ../lib/[common, repository, stash, types]

proc runScripts(pkgDef: BrrrFile, packageVersion,
    installedVersion, arch: string) =
  let templateVersion = pkgDef.versions[installedVersion]
  for script in pkgDef.templates[templateVersion][arch].uninstall:
    let runScript = script.multiReplace(
      ("{brrr_package_version}", packageVersion),
      ("{brrr_pkgdir}", getPackageDir(pkgDef.name)),
      ("{brrr_bin}", getBrrrBinDir()))
    log("Running script: " & runScript)
    let logs = execCmdEx(runScript, workingDir = getPackageDir(pkgDef.name))
    log(logs[0], 2)

proc uninstallPackage(pkg: PkgTuple, pkgDef: BrrrFile,
    installedVersion: string) =
  let hasVersion = pkgDef.versions.hasKey(installedVersion)
  let hasStarVersion = pkgDef.versions.hasKey(star)
  let osArch = getOS()

  if hasVersion:
    runScripts(pkgDef, installedVersion, installedVersion, osArch)
  elif hasStarVersion:
    runScripts(pkgDef, installedVersion, star, osArch)
  else:
    raise brrrError("Can't find version")

  removePackageDir(pkg.name)
  removePackageFromConfig(pkg.name)

proc uninstall*(packages: seq[PkgTuple]) =
  for pkg in packages.items:
    if isInstalled(pkg.name):
      let timeStart = now()
      let (version, url) = getPackageConfig(pkg.name)
      var (_, pkgDef) = downloadPackageDefinition(pkg)

      uninstallPackage(pkg, pkgDef, version)

      let timeEnd = now()
      let duration = timeEnd - timeStart
      log($pkg.name & "@" & version & " uninstalled successfully (" &
          $duration & ")")
    else:
      log($pkg.name & " is not installed.")

M src/lib/common.nim => src/lib/common.nim +2 -0
@@ 2,6 2,8 @@ import std/strutils

const brrrVersion* = "0.1.0"

const star* = "*"

type
  BrrrError* = object of CatchableError
    message*: string

M src/lib/stash.nim => src/lib/stash.nim +24 -7
@@ 17,10 17,8 @@ proc getBrrrConfigPath(): string =

proc getBrrrConfig(): Config =
  let configPath = getBrrrConfigPath()
  var info: FileInfo
  try:
    info = getFileInfo(configPath)
    echo info
    discard getFileInfo(configPath)
  except OSError:
    var config = newConfig()
    config.writeConfig(configPath)


@@ 32,6 30,24 @@ proc addPackageToConfig*(name, version, url: string) =
  config.setSectionKey(name, "url", url)
  config.writeConfig(getBrrrConfigPath())

proc getPackageConfig*(name: string): tuple[version: string, url: string] =
  var config = getBrrrConfig()
  var version = config.getSectionValue(name, "version")
  var url = config.getSectionValue(name, "url")
  return (version, url)

proc isInstalled*(name: string): bool =
  var config = getBrrrConfig()
  let version = config.getSectionValue(name, "version", "")
  return version != ""



proc removePackageFromConfig*(name: string) =
  var config = getBrrrConfig()
  config.delSection(name)
  config.writeConfig(getBrrrConfigPath())

proc initStash*() =
  try:
    discard existsOrCreateDir(brrrHome)


@@ 40,14 56,15 @@ proc initStash*() =
  except IOError:
    log("Failed to initialize brrr home")

proc createPackageDir*(packageName: string) =
proc removePackageDir*(packageName: string) =
  let packageDir = getPackageDir(packageName)
  try:
    removeDir(packageDir)
  except OSError:
    discard

  createDir(packageDir)
proc createPackageDir*(packageName: string) =
  removePackageDir(packageName)

# proc getConfig() =
#   let config =
  let packageDir = getPackageDir(packageName)
  createDir(packageDir)

M src/options.nim => src/options.nim +11 -15
@@ 1,18 1,16 @@
import commands/[help, install, version], lib/types
import std/[parseopt, strutils]
import commands/[help, install, uninstall, version], lib/types

# Many lines come from nimble.

type
  ActionType* = enum
    actionNil, actionHelp, actionInstall, actionVersion
    actionNil, actionHelp, actionInstall, actionUninstall, actionVersion
  Action* = object
    case typ*: ActionType
    of actionNil: nil
    of actionHelp: nil
    of actionInstall:
    of actionNil, actionHelp, actionVersion: nil
    of actionInstall, actionUninstall:
      packages*: seq[PkgTuple]
    of actionVersion: nil
  Options* = object
    action*: Action



@@ 22,42 20,40 @@ proc parseActionType*(action: string): ActionType =
    result = actionHelp
  of "install":
    result = actionInstall
  of "uninstall":
    result = actionUninstall
  of "version":
    result = actionVersion
  else:
    result = actionHelp

proc parseCommand*(key: string, result: var Options) =
  echo "parseCommand ", key
  result.action = Action(typ: parseActionType(key))

proc parseArgument*(key: string, result: var Options) =
  echo "parseArgument ", key
  case result.action.typ
  of actionNil:
    assert false
  of actionHelp:
  of actionHelp, actionVersion:
    discard
  of actionInstall:
  of actionInstall, actionUninstall:
    if '@' in key:
      let i = find(key, '@')
      let (pkgName, pkgVer) = (key[0 .. i-1], key[i+1 .. key.len-1])
      result.action.packages.add((pkgName, pkgVer))
    else:
      result.action.packages.add((key, "*"))
  of actionVersion:
    discard

proc doAction*(options: var Options) =
  case options.action.typ
    of actionHelp:
    of actionHelp, actionNil:
      writeHelp()
    of actionInstall:
      install(options.action.packages)
    of actionUninstall:
      uninstall(options.action.packages)
    of actionVersion:
      writeVersion()
    of actionNil:
      writeHelp()

proc initOptions*(): Options =
  Options(