From 7514c15d3949881b435d24673bc4a395ca96c770 Mon Sep 17 00:00:00 2001 From: Josip Lisec Date: Wed, 10 Mar 2010 01:55:32 +0100 Subject: [PATCH] Reorganised PackageInstaller, added support for SVN and basic dependency management --- README.textile | 4 +- depends | 0 io/Eerie.io | 18 ++-- .../{PackageInstaller => }/AddonBuilder.io | 0 io/Eerie/Package.io | 19 +++- io/Eerie/PackageDownloader.io | 2 +- io/Eerie/PackageDownloader/Git.io | 25 ----- io/Eerie/PackageDownloader/Vcs.io | 48 ++++++++++ io/Eerie/PackageInstaller.io | 92 ++++++++++++++++++- io/Eerie/PackageInstaller/Directory.io | 9 +- io/Eerie/PackageInstaller/File.io | 4 +- io/Eerie/PackageInstaller/IoAddon.io | 80 ++-------------- package.json | 2 +- 13 files changed, 180 insertions(+), 123 deletions(-) delete mode 100644 depends rename io/Eerie/{PackageInstaller => }/AddonBuilder.io (100%) delete mode 100644 io/Eerie/PackageDownloader/Git.io create mode 100644 io/Eerie/PackageDownloader/Vcs.io diff --git a/README.textile b/README.textile index 91d175e..c4f35eb 100644 --- a/README.textile +++ b/README.textile @@ -1,8 +1,8 @@ h1. Eerie, package manager for Io Eerie is an attempt to create feature-full package manager for Io, due to lack of working and usable package managers. -Eerie is modelled after "Rip":http://hellorip.com which means that there is no central repository of packages, and environments as a -tool for switching between different versions. +Eerie is modelled after "Rip":http://hellorip.com which means that there is no central repository of packages, and that environments +are used as a tool for switching between different versions. h2. How to install diff --git a/depends b/depends deleted file mode 100644 index e69de29..0000000 diff --git a/io/Eerie.io b/io/Eerie.io index d824b2b..a4c9c55 100644 --- a/io/Eerie.io +++ b/io/Eerie.io @@ -6,16 +6,20 @@ Eerie := Object clone do( config ::= nil envs := List clone - sh := method(cmd, + sh := method(cmd, logFailure, self log(cmd, "console") cmdOut := System runCommand(cmd) - if(cmdOut exitStatus != 0, - self log("Last command exited with the following error:", "error") - self log(cmdOut stdout, "output") - self log(cmdOut stderr, "output") - System exit(1)) - true) + if(cmdOut exitStatus != 0, + if(logFailure == false, + false + , + self log("Last command exited with the following error:", "error") + self log(cmdOut stdout, "output") + self log(cmdOut stderr, "output") + System exit(1)) + , + true)) _logMods := Map with( "info", " - ", diff --git a/io/Eerie/PackageInstaller/AddonBuilder.io b/io/Eerie/AddonBuilder.io similarity index 100% rename from io/Eerie/PackageInstaller/AddonBuilder.io rename to io/Eerie/AddonBuilder.io diff --git a/io/Eerie/Package.io b/io/Eerie/Package.io index bf9ca16..a0f0c84 100644 --- a/io/Eerie/Package.io +++ b/io/Eerie/Package.io @@ -41,6 +41,14 @@ Package := Object clone do( withConfig := method(config, self clone setConfig(config)) + guessName := method(_uri, + f := File with(_uri) + f exists ifTrue( + return(f baseName makeFirstCharacterUppercase)) + + _uri containsSeq("://") ifTrue( + return(_uri split("/") last split(".") first makeFirstCharacterUppercase))) + setInstaller := method(inst, self installer = inst self config atPut("installer", inst type) @@ -65,8 +73,7 @@ Package := Object clone do( self downloader download self loadMetadata - self dependencies ?isEmpty ifFalse( - self installDependencies) + self installDependencies self setInstaller(Eerie PackageInstaller detect(self path)) self installer install @@ -77,7 +84,9 @@ Package := Object clone do( self runHook("after" .. event)) installDependencies := method( - Eerie log("Installing depenendencies")) + deps := self dependencies("packages") + deps foreach(_uri, + self with(self guessName(_uri), _uri) install)) update := method( self runHook("beforeUpdateDownload") @@ -115,8 +124,8 @@ Package := Object clone do( p := self config at("meta") ?at("protos") if(p isNil, list(), p)) - dependencies := method( - d := self config at("meta") ?at("dependencies") + dependencies := method(category, + d := self config at("meta") ?at("dependencies") ?at(category) if(d isNil, list(), d)) asJson := method( diff --git a/io/Eerie/PackageDownloader.io b/io/Eerie/PackageDownloader.io index cde3178..a655836 100644 --- a/io/Eerie/PackageDownloader.io +++ b/io/Eerie/PackageDownloader.io @@ -27,4 +27,4 @@ PackageDownloader := Object clone do( PackageDownloader instances := Object clone PackageDownloader instances doRelativeFile("PackageDownloader/File.io") PackageDownloader instances doRelativeFile("PackageDownloader/Directory.io") -PackageDownloader instances doRelativeFile("PackageDownloader/Git.io") +PackageDownloader instances doRelativeFile("PackageDownloader/Vcs.io") diff --git a/io/Eerie/PackageDownloader/Git.io b/io/Eerie/PackageDownloader/Git.io deleted file mode 100644 index c5eda60..0000000 --- a/io/Eerie/PackageDownloader/Git.io +++ /dev/null @@ -1,25 +0,0 @@ -GitDownloader := Eerie PackageDownloader clone do( - git := method(gitArgs, - pwd := Directory currentWorkingDirectory - Directory setCurrentWorkingDirectory(self path) - r := Eerie sh("git " .. gitArgs) - Directory setCurrentWorkingDirectory(pwd) - - r) - - canDownload := method(uri, - (uri containsSeq("git://")) or(uri containsSeq(".git"))) - - download := method( - # Package.io will create addon's directory but, - # Git insists on creating it on its own. - Directory with(self path) remove - self git("clone #{self uri} #{self path}" interpolate) - self git("submodule init") - self git("submodule update") - true) - - update := method(path, - self git("update") - self git("submodule update")) -) diff --git a/io/Eerie/PackageDownloader/Vcs.io b/io/Eerie/PackageDownloader/Vcs.io new file mode 100644 index 0000000..e001ede --- /dev/null +++ b/io/Eerie/PackageDownloader/Vcs.io @@ -0,0 +1,48 @@ +VcsDownloader := Eerie PackageDownloader clone do( + vcs := Object clone do( + git := Object clone do( + check := method(uri, + uri containsSeq("git://") or uri containsSeq(".git")) + + cmd := "git" + download := list("clone #{self uri} #{self path}", "submodule init", "submodule update") + update := list("update", "submodule update") + ) + + svn := Object clone do( + check := method(uri, + Eerie sh("svn info " .. uri, false)) + + cmd := "svn" + download := list("co #{self uri} #{self path}") + update := list("up") + ) + ) + + vcsCmd := method(args, + Eerie sh((self vcs cmd) .. " " .. args)) + + runCommands := method(cmds, + cmds foreach(cmd, + self vcsCmd(cmd interpolate))) + + whichVcs := method(_uri, + self vcs slotNames foreach(name, + self vcs getSlot(name) check(_uri) ifTrue( + return(name))) + + nil) + + canDownload := method(_uri, + self whichVcs(_uri) != nil) + + download := method( + self vcs := self vcs getSlot(self whichVcs(self uri)) + + Directory with(self path) remove + self runCommands(self vcs download)) + + update := method( + self vcs := self vcs getSlot(self whichVcs(self uri)) + self runCommands(self vcs update)) +) \ No newline at end of file diff --git a/io/Eerie/PackageInstaller.io b/io/Eerie/PackageInstaller.io index 30fe477..a9a7e61 100644 --- a/io/Eerie/PackageInstaller.io +++ b/io/Eerie/PackageInstaller.io @@ -2,9 +2,18 @@ PackageInstaller := Object clone do( //doc PackageInstaller path Path to at which package is located. path ::= nil + //doc PackageInstaller root Directory with PackageInstallers' path. + root := method( + self root = Directory with(self path)) + + //doc PackageInstaller config Contains contents of a package.json + config ::= nil + + //doc PackageInstaller with(path) with := method(_path, self clone setPath(_path)) + //doc PacakgeInstaller detect(path) Returns first PackageInstaller which can install package at provided path. detect := method(_path, self instances foreachSlot(slotName, installer, installer canInstall(_path) ifTrue( @@ -14,8 +23,89 @@ PackageInstaller := Object clone do( //doc PackageInstaller canInstall(path) canInstall := method(path, false) - //doc PackageInstaller install() + + //doc PackageInstaller install install := method(false) + + //doc PackageInstaller fileNamed(name) Returns an File relative to root directory. + fileNamed := method(name, + self root fileNamed(name)) + + //doc PackageInstaller dirNamed(name) Returns an Directory relative to root directory. + dirNamed := method(name, + self root directoryNamed(name)) + + loadConfig := method( + configFile := self fileNamed("package.json") + configFile exists ifTrue( + self setConfig(Yajl parseJson(configFile openForReading contents)) + configFile close)) + + extractDataFromPackageJson := method( + providedProtos := self config at("protos") ?join(" ") + providedProtos isNil ifTrue( + providedProtos = "") + + deps := self config at("dependencies") + protoDeps := deps ?at("protos") ?join(" ") + protoDeps isNil ifTrue( + protoDeps = "") + + self fileNamed("protos") create openForUpdating write(providedProtos) close + self fileNamed("depends") create openForUpdating write(protoDeps) close + + self fileNamed("build.io") exists ifFalse( + headerDeps := deps ?at("headers") + libDeps := deps ?at("libs") + + buildIo := "AddonBuilder clone do(\n" asMutable + libDeps ?foreach(lib, + buildIo appendSeq(" dependsOnLib(\"#{lib}\")\n")) + headerDeps ?foreach(header, + buildIo appendSeq(" dependsOnHeader(\"#{header}\")\n")) + buildIo appendSeq(")\n") + + self fileNamed("build.io") create openForUpdating write(buildIo interpolate) close)) + + compile := method( + builderContext := Object clone + builderContext doRelativeFile("AddonBuilder.io") + prevPath := Directory currentWorkingDirectory + Directory setCurrentWorkingDirectory(self path) + + addon := builderContext doFile((self path) .. "/build.io") + addon folder := Directory with(self path) + addon build(if(System platform split at(0) asLowercase == "windows", + "-MD -Zi -DWIN32 -DNDEBUG -DIOBINDINGS -D_CRT_SECURE_NO_DEPRECATE", + "-Os -g -Wall -pipe -fno-strict-aliasing -DSANE_POPEN -DIOBINDINGS")) + + Directory setCurrentWorkingDirectory(prevPath) + self) + + buildPackageJson := method( + package := Map with( + "dependencies", list(), + "protos", list()) + + providedProtos := self fileNamed("protos") + protoDeps := self fileNamed("depends") + + providedProtos exists ifTrue( + providedProtos openForReading contents split(" ") foreach(pp, package at("protos") append(pp strip))) + providedProtos close + + protoDeps exists ifTrue( + protoDeps openForReading contents split(" ") foreach(pd, package at("dependencies") append(pd strip))) + protoDeps close + + self fileNamed("package.json") create openForUpdating write(package asJson) close + + self) + + copyBinaries := method( + Eerie sh("chmod +x #{self path}/bin/*" interpolate) + self dirNamed("bin") files foreach(f, + Eerie sh("ln -s #{f path} #{Eerie activeEnv path}/bin/#{f name}" interpolate))) ) PackageInstaller instances := Object clone do( diff --git a/io/Eerie/PackageInstaller/Directory.io b/io/Eerie/PackageInstaller/Directory.io index 6e5d3c8..e425f84 100644 --- a/io/Eerie/PackageInstaller/Directory.io +++ b/io/Eerie/PackageInstaller/Directory.io @@ -5,17 +5,16 @@ DirectoryInstaller := Eerie PackageInstaller clone do( dir exists and(dir filesWithExtension("io") isEmpty not) and(packageJson exists not)) install := method( - root := Directory with(self path) - ioDir := root directoryNamed("io") create - + ioDir := self dirNamed("io") create + protosList := list() - root filesWithExtension("io") foreach(ioFile, + self root filesWithExtension("io") map(ioFile, ioFile baseName at(0) isUppercase ifTrue( protoList append(ioFile baseName))) Eerie sh("mv #{self path}/*.io #{ioDir path}" interpolate) - File with((self path) .. "/package.json") create openForUpdating write(Map with( + self fileNamed("package.json") remove create openForUpdating write(Map with( "author", User name, "dependencies", list(), "protos", protosList diff --git a/io/Eerie/PackageInstaller/File.io b/io/Eerie/PackageInstaller/File.io index a393825..8be8580 100644 --- a/io/Eerie/PackageInstaller/File.io +++ b/io/Eerie/PackageInstaller/File.io @@ -5,9 +5,9 @@ FileInstaller := Eerie PackageInstaller clone do( f exists and(f isRegularFile)) install := method( - File with((self path) .. "/package.json") create openForUpdating write(Map with( + self fileNamed("package.json") remove create openForUpdating write(Map with( "author", User name, "dependencies", list(), - "protos", list(Directory with(self path) filesWithExtension("io") first baseName makeFirstCharacterUppercase) + "protos", list(self root filesWithExtension("io") first baseName makeFirstCharacterUppercase) ) asJson) close) ) \ No newline at end of file diff --git a/io/Eerie/PackageInstaller/IoAddon.io b/io/Eerie/PackageInstaller/IoAddon.io index 9fe74e5..6e7dd9d 100644 --- a/io/Eerie/PackageInstaller/IoAddon.io +++ b/io/Eerie/PackageInstaller/IoAddon.io @@ -6,87 +6,19 @@ IoAddonInstaller := Eerie PackageInstaller clone do( _pathDir exists and(ioDir exists)) install := method( - dir := Directory with(self path) - configFile := File with((self path) .. "/package.json") - self config := if(configFile exists, - Yajl parseJson(configFile openForReading contents), - Map clone) - configFile close + self loadConfig - if(File with((self path) .. "/protos") exists, + if(self fileNamed("protos") exists, self buildPackageJson, self extractDataFromPackageJson) - if(dir directoryNamed("source") exists, + if(self dirNamed("source") exists, self compile, - dir createSubdirectory("source")) + self root createSubdirectory("source")) - if(dir directoryNamed("bin") exists, + if(self dirNamed("bin") exists, self copyBinaries, - dir createSubdirectory("bin")) + self root createSubdirectory("bin")) true) - - extractDataFromPackageJson := method( - providedProtos := self config at("protos") - protoDeps := self config at("dependencies") ?at("protos") - - providedProtos ?isEmpty ifFalse( - File with((self path) .. "/protos") create openForUpdating write(providedProtos join(" ")) close) - - protoDeps ?isEmpty ifFalse( - File with((self path) .. "/depends") create openForUpdating write(protoDeps join(" ")) close) - - File with((self path) .. "/build.io") exists ifFalse( - headerDeps := self config at("dependencies") ?at("headers") - libDeps := self config at("dependencies") ?at("libs") - - buildIo := "AddonBuilder clone do(\n" asMutable - libDeps ?foreach(lib, - buildIo appendSeq(""" dependsOnLib("#{lib}")\n""")) - headerDeps ?foreach(header, - buildIo appendSeq(""" dependsOnHeader("#{header}")\n""")) - buildIo appendSeq(")\n") - - File with((self path) .. "/build.io") create openForUpdating write(buildIo interpolate) close)) - - compile := method( - builderContext := Object clone - builderContext doRelativeFile("AddonBuilder.io") - prevPath := Directory currentWorkingDirectory - Directory setCurrentWorkingDirectory(self path) - - addon := builderContext doFile((self path) .. "/build.io") - addon folder := Directory with(self path) - addon build(if(System platform split at(0) asLowercase == "windows", - "-MD -Zi -DWIN32 -DNDEBUG -DIOBINDINGS -D_CRT_SECURE_NO_DEPRECATE", - "-Os -g -Wall -pipe -fno-strict-aliasing -DSANE_POPEN -DIOBINDINGS")) - - Directory setCurrentWorkingDirectory(prevPath) - self) - - buildPackageJson := method( - package := Map with( - "dependencies", list(), - "protos", list()) - - providedProtos := File with((self path) .. "/protos") - protoDeps := File with((self path) .. "/depends") - - providedProtos exists ifTrue( - providedProtos openForReading contents split(" ") foreach(pp, package at("protos") append(pp strip))) - providedProtos close - - protoDeps exists ifTrue( - protoDeps openForReading contents split(" ") foreach(pd, package at("dependencies") append(pd strip))) - protoDeps close - - File with((self path) .. "/package.json") create openForUpdating write(package asJson) close - - self) - - copyBinaries := method( - Eerie sh("chmod +x #{self path}/bin/*" interpolate) - Directory with((self path) .. "/bin") files foreach(f, - Eerie sh("ln -s #{f path} #{Eerie activeEnv path}/bin/#{f name}" interpolate))) ) \ No newline at end of file diff --git a/package.json b/package.json index 3993a5d..4b4983f 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "dependencies": { "headers": [], "protos": [], - "packages": ["git://github.com/stevedekorte/io.git"] + "packages": ["git://github.com/josip/Kano.git"] }, "protos": ["Eerie"] }