willdonnelly / dyre Goto Github PK
View Code? Open in Web Editor NEWA Dynamic Reconfiguration Library for Haskell Programs
License: BSD 3-Clause "New" or "Revised" License
A Dynamic Reconfiguration Library for Haskell Programs
License: BSD 3-Clause "New" or "Revised" License
Reproduce:
Expected result: Program runs the default configuration.
Actual result: The error message from the failed compilation persists, and I have to wipe my program's cache directory.
One of my mid-term goals is to put my neovim plugin provider on stackage. Your package is the only one keeping me from doing so and I really need this way of recompilation.
Would you mind putting it there? If you don't want to do the work, I can to it.
I don't necessarily want all of my config in a single file. But if I factor out parts into other modules, my config won't re-compile unless I run the program from in the $HOME/.config/programName
directory, because the includeCurrentDirectory
setting defaults to true. More useful to me would be adding System.Environment.XDG.BaseDir.getUserConfigDir programName
as a -i
argument to the ghc execution.
I'm using a basic cabal executable configuration. My project is just a DyreExample. Every time I run the executable I get this error when the configuration file is found. I'm running the executable with cabal run
.
Could not find module ‘MyModule’
Use -v to see a list of the files searched for.
Why can't Dyre find my module which is defined in cabal and is compiled into the executable?
(I'm using yi as an example client of dyre here, but nothing is actually specific to yi.)
When a user runs (for instance)
> touch ~/.yi/yi.hs
> yi --help
the following happens:
Configuration '/home/reiner/.yi/yi.hs' changed. Recompiling.
Program reconfiguration successful.
Launching custom binary /home/reiner/.cache/yi/yi-linux-x86_64
Usage: yi ...
That is, the program is recompiled and the commandline is only processed afterwards. I find this behaviour rather surprising, because I typically expect programname --help
to return immediately. Similarly, I also expect yi to exit immediately if I enter bad commandline arguments, rather than recompile and then exit.
One solution to this would be for dyre to first run yi's commandline parser, and only reconfigure yi once that has succeeded. This would need some special support from dyre (to filter out its commandline options) so this would essentially involve adding the following to Config.Dyre.Params
:
data Params cfgType = Params {
...
parseCommandline :: [String] -> IO (Maybe cfgType), -- ^ Just x if parsing succeeded and gave result x; Nothing if parsing failed
...
}
The special treatment of commandline parsing is unfortunate, and perhaps not worth the change. This ticket is merely to document the inconvenience.
The canonicalizePath call in the new version of System.Directory throws an exception if the path does not exist. Dyre uses canonicalizePath when a file may not exist https://github.com/willdonnelly/dyre/blob/master/Config/Dyre.hs#L170, so this new behavior is triggered, and an unhandled exception results.
This issue is a place to leave feedback when testing the 0.9.0 release. Any general feedback, including "I tested X on platform Y and it worked" can go here. Problem reports can go here to (I will clone to separate tickets as appropriate).
Release candidate is available from https://hackage.haskell.org/package/dyre-0.9.0/candidate, or just clone this repo and check out the dyre-0.9.0-rc1 tag.
Things that need to be tested:
We have an issue at yi-editor/yi#515 which traces a failing fromMaybe
to dyre. It'd be great if there was some error handling in place rather than using fromMaybe and hoping for the best. At the very least, a better message would be great than the stock fromMaybe one. Perhaps use something like the maybe
function from Data.Maybe with error "helpful message"
as the default value.
I think it's generally useful to parameterize the return type of realMain and warpMain to IO a
as we might use dyre with any IO actions that need to load config files written in Haskell at runtime. Is it possible to do so or does dyre only works with the main function?
Could you please use the more generic MonadBase IO m => m a
type in place of IO a
?
Or at least MonadIO m => m a
if you care about Haskell 98 compliance.
I get the following error while trying to cabal install dyre-0.8.9:
Config/Dyre/Options.hs:33:37:
Module `System.Environment' does not export `getExecutablePath'
Sometimes the --make
is not sufficient to guess all packages for configuration file. Consider:
It should be possible to fine-tune the requirements.
I am simply trying Dyre out in preparation to use it in a project so I tried to run the example shown here: https://github.com/willdonnelly/dyre/blob/master/Config/Dyre.hs#L23
I am running GHC 7.6.3 installed from package on Debian 8/Jessie.
I checked out the ghc man page and did not see the -B<dir>
option at all.
The steps to reproduce:
$runhaskell Main.hs
Launching custom binary ~/.cache/dyreExample/dyreExample-linux-x86_64
Dyre Example v0.1 (Modified)
> hello
ghc: missing -B<dir> option
$
Let me know if there is additional information I can provide.
Hi,
if a configuration file couldn't be build then an errors.log
file is created and its content is forwarded to the application using dyre
.
If the configuration file gets deleted then the errors.log
file seems to be kept and continually forwarded to the application.
Greetings,
Daniel
Cancelling compilation early can leave an invalid executable in the cache dir which has to be manually removed. Attempting to start program without removing the invalid executable will crash by trying to launch it, with no error handling.
Possibilities: Trigger recompilation, or for example compile to some other location and then copy at he end to ensure that it is atomic.
GHC's -dynamic
flag (see http://www.haskell.org/ghc/docs/latest/html/users_guide/options-phases.html#options-linker) can improve link times, which can be quite useful for dynamic reconfigurations, as the configuration file is typically much smaller than the library it is linking to.
It would be good to support dynamic linking in Dyre. Not all users will want this (for instance, it isn't supported in Windows, and it requires the relevant packages to have been installed with @--enable-shared@), so there should be some way for the user to enable/disable dynamic linking. The easiest way I see is to add a --dynamic-linking
commandline option which enables dynamic linking in GHC.
In Dyre.hs, thisBinary is compared against tempBinary using a string equality test. If the user's home directory has a symlink between it and /, getExecutablePath in Dyre/Paths.h resolves these symlinks while the method used to construct the path to the tempBinary does not. When the two are compared, the test always fails and dyre falls into an infinite loop of execing the custom binary.
Using canonicalizePath from System.Directory on tempBinary and thisBinary before the comparison is enough to fix this for at least some cases.
One can use GHC.Environment.getFullArgs to filter RTS arguments (including profiling options) given to the driver binary,
and then forward them to the relaunched binary.
Could you please adapt the API to accept Text
objects in place of String
ones ?
Thank you.
Commit 6d8653d is crucial to getting Yi working on NixOS. Could you please update the hackage version of Dyre to include this change?
It would be helpful if dyre worked with stack and cabal-sandbox by default. I ran into this need when trying to hack around on the Yi editor which uses dyre.
If I extend the basic example to use submodule, for example like this:
-- ~/.config/dyreExample/dyreExample.hs
import DyreExample
import qualified MyModule
main = dyreExample $ defaultConfig { message = "Dyre Example v1.2", n = MyModule.random }
-- ~/.config/dyreExample/MyModule.hs
module MyModule where
random :: Integer
random = 7
-- DyreExample.hs
...
realMain Config{message = message, errorMsg = errorMsg, n = n} = do
...
print n
...
, Dyre.ghcOpts = ["-i/path/to/.config/dyreExample"]
...
... then the change inside MyModule.hs
is not detected and the custom configuration is not recompiled (for example if I change the value of random
). It gets recompiled only after ~/.config/dyreExample/dyreExample.hs
is touched.
How can I workaround this problem?
Here is the error:
Config/Dyre/Paths.hs:40:13:
Couldn't match expected type `UTCTime'
with actual type `old-time-1.1.0.0:System.Time.ClockTime'
Expected type: IO (Maybe UTCTime)
Actual type: IO (Maybe old-time-1.1.0.0:System.Time.ClockTime)
In the expression: fmap Just $ getModificationTime path
In a stmt of a 'do' block:
if fileExists then
fmap Just $ getModificationTime path
else
return Nothing
May I suggest you give https://travis-ci.org a try? It really helps spotting this kind of issues.
I think the latest changes might have introduced a regression regarding builds with the Nix package manager. I have not had a chance to look at builds in Fedora. I currently don't have any specifics, just symptoms.
Typical problem is, that the packages can't be picked up (Note: this includes printing the flags I changed myself):
% result/bin/purebred
Configuration '/home/rjoost/.config/purebred/purebred.hs' changed. Recompiling.
Flags: -v0-i/home/rjoost/.config/purebred/lib-i/home/rjoost/works/purebred-i/nix/store/y5g5s6q926lsj6h9dyjgpdq91h3bwhzr-purebred-0.1.0.0/lib/ghc-8.8.4/x86_64-linux-ghc-8.8.4/purebred-0.1.0.0-7Yxwc0odFxzINrVJ1QtwAR-threaded--make/home/rjoost/.config/purebred/purebred.hs-ou
tputdir/home/rjoost/.cache/purebred-o/home/rjoost/.cache/purebred/purebred-linux-x86_64.tmp-fforce-recomp
Error occurred while loading configuration file.
purebred:
/home/rjoost/.config/purebred/purebred.hs:24:1: error:
Could not find module ‘Purebred’
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
|
24 | import Purebred
| ^^^^^^^^^^^^^^^
/home/rjoost/.config/purebred/purebred.hs:25:1: error:
Could not find module ‘Purebred.Plugin.ICU’
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
|
25 | import qualified Purebred.Plugin.ICU
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/home/rjoost/.config/purebred/purebred.hs:33:1: error:
Could not find module ‘Data.MIME’
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
|
33 | import Data.MIME (matchContentType)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
CallStack (from HasCallStack):
error, called at src/Purebred.hs:347:69 in purebred-0.1.0.0-7Yxwc0odFxzINrVJ1QtwAR:Purebred
See http://code.google.com/p/yi-editor/issues/detail?id=355 for the relevant ticket for Yi.
Basically, I would like better control over recompilation. Specifically:
Config.Dyre.Relaunch
I don't want to shut down the UI until I know that recompilation has succeeded. If recompilation has failed, I want to abort the relaunch and display the error messages to the user.Config.Dyre.Compile.customCompile
, but this function will always trigger a recompile, whereas I only want to recompile when my config file has changed.When recompiling a program, Dyre spawns GHC using the following command:
ghcProc <- runProcess "ghc" ghcOpts (Just cacheDir) Nothing Nothing Nothing (Just errHandle)
This way, the ghc
executable uses the global environment (cabal packages). It gets in your way when you're developing a project within a cabal sandbox: you expect ghc
to use the sandbox environment instead. This is usually done by calling cabal exec ghc
rather than ghc
.
I think Dyre should adopt the following behavior:
cabal.sandbox.config
) is present in the current working directory, then use cabal exec ghc
;ghc
.Optionally, a flag could be added to Params
to disable the autodetection, in case it's undesirable.
What do you think ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.