Skip to content

Commit

Permalink
Migrate all Juvix projects from juvix.yaml to Package.juvix in the re…
Browse files Browse the repository at this point in the history
…pository (#2503)

This PR:

* Modifies entry point `_entryPointBuildDir` to use the `BuildDir` type
instead of `SomeBase Dir`. This allows delayed resolution of the default
build directory which was useful for the Package -> Concrete translation
point below.
* Modifies `juvix dev root` to render the current package as a
Package.juvix file.
* Modifies the Package -> Concrete translation to recognise default
arguments. So, for example, an empty `juvix.yaml` file will be
translated into the following (instead of the `name`, `version`, and
`dependencies` arguments being populated).

        
        module Package;

        import Stdlib.Prelude open;
        import PackageDescription.V1 open;

        package : Package := defaultPackage;
        
* Adds a temporary command (removed when juvix.yaml support is removed)
`juvix dev migrate-juvix-yaml` that translates `juvix.yaml` into an
equivalent `Package.juvix` in the current project.
* Adds a temporary script `migrate-juvix-yaml.sh` (removed when
juvix.yaml support is removed) which can be run in the project to
translate all Juvix projects in the repository.
* Actually translate all of the `juvix.yaml` files to `Package.juvix`
using the script.

* Part of #2487
  • Loading branch information
paulcadman authored Nov 7, 2023
1 parent 473ed25 commit 68d4314
Show file tree
Hide file tree
Showing 177 changed files with 642 additions and 160 deletions.
2 changes: 1 addition & 1 deletion app/App.hs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ runAppIO args@RunAppIOArgs {..} =
AskRoot -> return _runAppIOArgsRoot
AskInvokeDir -> return invDir
AskPkgDir -> return (_runAppIOArgsRoot ^. rootRootDir)
AskBuildDir -> return (_runAppIOArgsRoot ^. rootBuildDir)
AskBuildDir -> return (resolveAbsBuildDir (_runAppIOArgsRoot ^. rootRootDir) (_runAppIOArgsRoot ^. rootBuildDir))
RunCorePipelineEither input -> do
entry <- embed (getEntryPoint' args input)
embed (corePipelineIOEither entry)
Expand Down
2 changes: 2 additions & 0 deletions app/Commands/Dev.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Commands.Dev.DisplayRoot qualified as DisplayRoot
import Commands.Dev.Geb qualified as Geb
import Commands.Dev.Highlight qualified as Highlight
import Commands.Dev.Internal qualified as Internal
import Commands.Dev.MigrateJuvixYaml qualified as MigrateJuvixYaml
import Commands.Dev.Options
import Commands.Dev.Parse qualified as Parse
import Commands.Dev.Runtime qualified as Runtime
Expand All @@ -31,3 +32,4 @@ runCommand = \case
Runtime opts -> Runtime.runCommand opts
DisplayRoot opts -> DisplayRoot.runCommand opts
JuvixDevRepl opts -> Repl.runCommand opts
MigrateJuvixYaml opts -> runFilesIO $ MigrateJuvixYaml.runCommand opts
4 changes: 2 additions & 2 deletions app/Commands/Dev/DisplayRoot.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Commands.Dev.DisplayRoot where

import Commands.Base
import Commands.Dev.DisplayRoot.Options
import Data.Yaml
import Commands.Extra.Package

runCommand :: forall r. (Members '[Embed IO, App] r) => RootOptions -> Sem r ()
runCommand RootOptions {..} = do
Expand All @@ -12,4 +12,4 @@ runCommand RootOptions {..} = do
printPackage :: Sem r ()
printPackage = do
say "+----------------------------+"
askPackage >>= say . decodeUtf8 . encode . rawPackage
askPackage >>= say . renderPackage
2 changes: 1 addition & 1 deletion app/Commands/Dev/DisplayRoot/Options.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ parseRoot = do
_rootPrintPackage <-
switch
( long "print-package"
<> help "print the juvix.yaml file as parsed"
<> help "print the Package.juvix file as parsed"
)

_rootMainFile <- optional (parseInputFile FileExtJuvix)
Expand Down
20 changes: 20 additions & 0 deletions app/Commands/Dev/MigrateJuvixYaml.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module Commands.Dev.MigrateJuvixYaml where

import Commands.Base
import Commands.Dev.MigrateJuvixYaml.Options
import Commands.Extra.Package
import Juvix.Extra.Paths

runCommand :: forall r. (Members '[Embed IO, Files, App] r) => MigrateJuvixYamlOptions -> Sem r ()
runCommand MigrateJuvixYamlOptions {..} = do
pkgDir <- askPkgDir
isGlobalPackage <- askPackageGlobal
let pkgFilePath = pkgDir <//> packageFilePath
pkgFileExists <- fileExists' pkgFilePath
pkg <- askPackage
if
| isGlobalPackage -> exitMsg (ExitFailure 1) "No Package file found"
| not pkgFileExists || _migrateJuvixYamlOptionsForce -> do
writePackageFile pkgDir pkg
removeFile' (pkgDir <//> juvixYamlFile)
| otherwise -> exitMsg (ExitFailure 1) (show pkgFilePath <> " already exists.")
20 changes: 20 additions & 0 deletions app/Commands/Dev/MigrateJuvixYaml/Options.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module Commands.Dev.MigrateJuvixYaml.Options where

import CommonOptions

newtype MigrateJuvixYamlOptions = MigrateJuvixYamlOptions
{ _migrateJuvixYamlOptionsForce :: Bool
}
deriving stock (Data)

makeLenses ''MigrateJuvixYamlOptions

parseMigrateJuvixYaml :: Parser MigrateJuvixYamlOptions
parseMigrateJuvixYaml = do
_migrateJuvixYamlOptionsForce <-
switch
( long "force"
<> short 'f'
<> help "Overwrite existing Package.juvix"
)
pure MigrateJuvixYamlOptions {..}
12 changes: 11 additions & 1 deletion app/Commands/Dev/Options.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import Commands.Dev.DisplayRoot.Options
import Commands.Dev.Geb.Options
import Commands.Dev.Highlight.Options
import Commands.Dev.Internal.Options
import Commands.Dev.MigrateJuvixYaml.Options
import Commands.Dev.Parse.Options
import Commands.Dev.Repl.Options
import Commands.Dev.Runtime.Options
Expand All @@ -38,6 +39,7 @@ data DevCommand
| Scope ScopeOptions
| Termination TerminationCommand
| JuvixDevRepl ReplOptions
| MigrateJuvixYaml MigrateJuvixYamlOptions
deriving stock (Data)

parseDevCommand :: Parser DevCommand
Expand All @@ -54,7 +56,8 @@ parseDevCommand =
commandScope,
commandShowRoot,
commandTermination,
commandJuvixDevRepl
commandJuvixDevRepl,
commandMigrateJuvixYaml
]
)

Expand Down Expand Up @@ -136,3 +139,10 @@ commandJuvixDevRepl =
(JuvixDevRepl <$> parseDevRepl)
(progDesc "Run the Juvix dev REPL")
)

commandMigrateJuvixYaml :: Mod CommandFields DevCommand
commandMigrateJuvixYaml =
command "migrate-juvix-yaml" $
info
(MigrateJuvixYaml <$> parseMigrateJuvixYaml)
(progDesc "Migrate juvix.yaml to Package.juvix in the current project")
18 changes: 18 additions & 0 deletions app/Commands/Extra/Package.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module Commands.Extra.Package where

import Data.Text.IO.Utf8 qualified as Utf8
import Juvix.Compiler.Pipeline.Package.Base
import Juvix.Compiler.Pipeline.Package.Loader
import Juvix.Extra.Paths
import Juvix.Prelude

renderPackage :: Package -> Text
renderPackage = renderPackageVersion PackageVersion1

writePackageFile :: (Member (Embed IO) r) => Path Abs Dir -> Package -> Sem r ()
writePackageFile root pkg =
embed
( Utf8.writeFile @IO
(toFilePath (root <//> packageFilePath))
(renderPackage pkg)
)
9 changes: 3 additions & 6 deletions app/Commands/Init.hs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
module Commands.Init where

import Commands.Extra.Package
import Commands.Init.Options
import Data.Text qualified as Text
import Data.Text.IO.Utf8 qualified as Utf8
import Data.Versions
import Juvix.Compiler.Pipeline.Package
import Juvix.Compiler.Pipeline.Package.Loader
import Juvix.Data.Effect.Fail.Extra qualified as Fail
import Juvix.Extra.Paths
import Juvix.Prelude
Expand Down Expand Up @@ -39,13 +38,11 @@ init opts = do
Nothing -> emptyPkg
Just n -> emptyPkg {_packageName = n}
when isInteractive (say ("creating " <> pack (toFilePath packageFilePath)))
writePackage pkg
cwd <- getCurrentDir
writePackageFile cwd pkg
checkPackage
when isInteractive (say "you are all set")
where
writePackage :: Package -> Sem r ()
writePackage pkg = embed (Utf8.writeFile @IO (toFilePath packageFilePath) (renderPackageVersion PackageVersion1 pkg))

isInteractive :: Bool
isInteractive = not (opts ^. initOptionsNonInteractive)

Expand Down
4 changes: 2 additions & 2 deletions app/Commands/Repl.hs
Original file line number Diff line number Diff line change
Expand Up @@ -535,8 +535,8 @@ runCommand opts = do
defaultPreludeEntryPoint :: Repl (Maybe EntryPoint)
defaultPreludeEntryPoint = do
root <- State.gets (^. replStateRoot)
let buildDir = root ^. rootBuildDir
buildRoot = root ^. rootRootDir
let buildRoot = root ^. rootRootDir
buildDir = resolveAbsBuildDir buildRoot (root ^. rootBuildDir)
pkg = root ^. rootPackage
mstdlibPath <- liftIO (runM (runFilesIO (packageStdlib buildRoot buildDir (pkg ^. packageDependencies))))
case mstdlibPath of
Expand Down
4 changes: 2 additions & 2 deletions app/GlobalOptions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ entryPointFromGlobalOptions root mainFile opts = do
_entryPointNoStdlib = opts ^. globalNoStdlib,
_entryPointUnrollLimit = opts ^. globalUnrollLimit,
_entryPointGenericOptions = project opts,
_entryPointBuildDir = maybe (def ^. entryPointBuildDir) Abs mabsBuildDir,
_entryPointBuildDir = maybe (def ^. entryPointBuildDir) (CustomBuildDir . Abs) mabsBuildDir,
_entryPointOffline = opts ^. globalOffline
}
where
Expand All @@ -178,7 +178,7 @@ entryPointFromGlobalOptionsNoFile root opts = do
_entryPointNoStdlib = opts ^. globalNoStdlib,
_entryPointUnrollLimit = opts ^. globalUnrollLimit,
_entryPointGenericOptions = project opts,
_entryPointBuildDir = maybe (def ^. entryPointBuildDir) Abs mabsBuildDir,
_entryPointBuildDir = maybe (def ^. entryPointBuildDir) (CustomBuildDir . Abs) mabsBuildDir,
_entryPointOffline = opts ^. globalOffline
}
where
Expand Down
7 changes: 7 additions & 0 deletions examples/demo/Package.juvix
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module Package;

import PackageDescription.V1 open;

package : Package :=
defaultPackage
{name := "Demo"; version := mkVersion 0 1 0};
2 changes: 0 additions & 2 deletions examples/demo/juvix.yaml

This file was deleted.

7 changes: 7 additions & 0 deletions examples/midsquare/Package.juvix
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module Package;

import PackageDescription.V1 open;

package : Package :=
defaultPackage
{name := "midsquare"; version := mkVersion 0 1 0};
2 changes: 0 additions & 2 deletions examples/midsquare/juvix.yaml

This file was deleted.

5 changes: 5 additions & 0 deletions examples/milestone/Bank/Package.juvix
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module Package;

import PackageDescription.V1 open;

package : Package := defaultPackage {name := "bank"};
4 changes: 0 additions & 4 deletions examples/milestone/Bank/juvix.yaml

This file was deleted.

10 changes: 10 additions & 0 deletions examples/milestone/Collatz/Package.juvix
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module Package;

import Stdlib.Prelude open;
import PackageDescription.V1 open;

package : Package :=
defaultPackage
{name := "Collatz";
version := mkVersion 0 1 0;
main := just "Collatz.juvix"};
3 changes: 0 additions & 3 deletions examples/milestone/Collatz/juvix.yaml

This file was deleted.

10 changes: 10 additions & 0 deletions examples/milestone/Fibonacci/Package.juvix
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module Package;

import Stdlib.Prelude open;
import PackageDescription.V1 open;

package : Package :=
defaultPackage
{name := "Fibonacci";
version := mkVersion 0 1 0;
main := just "Fibonacci.juvix"};
3 changes: 0 additions & 3 deletions examples/milestone/Fibonacci/juvix.yaml

This file was deleted.

10 changes: 10 additions & 0 deletions examples/milestone/Hanoi/Package.juvix
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module Package;

import Stdlib.Prelude open;
import PackageDescription.V1 open;

package : Package :=
defaultPackage
{name := "Hanoi";
version := mkVersion 0 1 0;
main := just "Hanoi.juvix"};
3 changes: 0 additions & 3 deletions examples/milestone/Hanoi/juvix.yaml

This file was deleted.

10 changes: 10 additions & 0 deletions examples/milestone/HelloWorld/Package.juvix
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module Package;

import Stdlib.Prelude open;
import PackageDescription.V1 open;

package : Package :=
defaultPackage
{name := "HelloWorld";
version := mkVersion 0 1 0;
main := just "HelloWorld.juvix"};
3 changes: 0 additions & 3 deletions examples/milestone/HelloWorld/juvix.yaml

This file was deleted.

10 changes: 10 additions & 0 deletions examples/milestone/PascalsTriangle/Package.juvix
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module Package;

import Stdlib.Prelude open;
import PackageDescription.V1 open;

package : Package :=
defaultPackage
{name := "PascalsTriangle";
version := mkVersion 0 1 0;
main := just "PascalsTriangle.juvix"};
3 changes: 0 additions & 3 deletions examples/milestone/PascalsTriangle/juvix.yaml

This file was deleted.

10 changes: 10 additions & 0 deletions examples/milestone/TicTacToe/Package.juvix
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module Package;

import Stdlib.Prelude open;
import PackageDescription.V1 open;

package : Package :=
defaultPackage
{name := "TicTacToe";
version := mkVersion 0 1 0;
main := just "CLI/TicTacToe.juvix"};
3 changes: 0 additions & 3 deletions examples/milestone/TicTacToe/juvix.yaml

This file was deleted.

7 changes: 7 additions & 0 deletions examples/milestone/Tutorial/Package.juvix
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module Package;

import PackageDescription.V1 open;

package : Package :=
defaultPackage
{name := "Tutorial"; version := mkVersion 0 1 0};
2 changes: 0 additions & 2 deletions examples/milestone/Tutorial/juvix.yaml

This file was deleted.

9 changes: 9 additions & 0 deletions migrate-juvix-yaml.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

# Projects must be migrated depth-first because Package.juvix is searched before juvix.yaml
# (so Package.juvix in parent directories are used before juvix.yaml in the current directory)
find . -type f -name "juvix.yaml" | awk -F'/' '{print NF-1 " " $0}' | sort -nr | cut -d' ' -f2- | while IFS= read -r file; do
dir=$(dirname "$file")
echo "migrating: $dir"
(cd "$dir" && juvix dev migrate-juvix-yaml)
done
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,9 @@ mkPackage ::
Path Abs Dir ->
Sem r Package
mkPackage mpackageEntry _packageRoot = do
let buildDir :: Path Abs Dir = maybe (rootBuildDir _packageRoot) (someBaseToAbs _packageRoot . (^. entryPointBuildDir)) mpackageEntry
buildDirDep :: BuildDir
| isJust mpackageEntry = CustomBuildDir (Abs buildDir)
| otherwise = DefaultBuildDir
let buildDirDep = case mpackageEntry of
Just packageEntry -> rootedBuildDir _packageRoot (packageEntry ^. entryPointBuildDir)
Nothing -> DefaultBuildDir
maybe (readPackage _packageRoot buildDirDep) (return . (^. entryPointPackage)) mpackageEntry

mkPackageInfo ::
Expand All @@ -50,7 +49,7 @@ mkPackageInfo ::
Package ->
Sem r PackageInfo
mkPackageInfo mpackageEntry _packageRoot pkg = do
let buildDir :: Path Abs Dir = maybe (rootBuildDir _packageRoot) (someBaseToAbs _packageRoot . (^. entryPointBuildDir)) mpackageEntry
let buildDir :: Path Abs Dir = maybe (rootBuildDir _packageRoot) (someBaseToAbs _packageRoot . resolveBuildDir . (^. entryPointBuildDir)) mpackageEntry
deps <- getDependencies
let _packagePackage = set packageDependencies deps pkg
depsPaths <- mapM (fmap (^. resolvedDependencyPath) . resolveDependency . mkPackageDependencyInfo pkgFile) deps
Expand Down
5 changes: 2 additions & 3 deletions src/Juvix/Compiler/Pipeline/EntryPoint.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ where
import Juvix.Compiler.Backend
import Juvix.Compiler.Pipeline.Package.Base
import Juvix.Compiler.Pipeline.Root.Base
import Juvix.Extra.Paths
import Juvix.Prelude

-- | An option specifiying how symbols should be pruned in the Internal to Core translation
Expand All @@ -22,7 +21,7 @@ data EntryPoint = EntryPoint
-- | initial root for the path resolver. Usually it should be equal to
-- _entryPointRoot. It only differs for `juvix repl`.
_entryPointResolverRoot :: Path Abs Dir,
_entryPointBuildDir :: SomeBase Dir,
_entryPointBuildDir :: BuildDir,
_entryPointNoTermination :: Bool,
_entryPointNoPositivity :: Bool,
_entryPointNoCoverage :: Bool,
Expand Down Expand Up @@ -56,7 +55,7 @@ defaultEntryPointNoFile root =
EntryPoint
{ _entryPointRoot = root ^. rootRootDir,
_entryPointResolverRoot = root ^. rootRootDir,
_entryPointBuildDir = Rel relBuildDir,
_entryPointBuildDir = DefaultBuildDir,
_entryPointNoTermination = False,
_entryPointNoPositivity = False,
_entryPointNoCoverage = False,
Expand Down
Loading

0 comments on commit 68d4314

Please sign in to comment.