Compare commits

...

29 Commits

Author SHA1 Message Date
Brian Hicks a47d7ef8a4 format with ormolu 2 years ago
Brian Hicks 4e5eb1856f add ormolu 2 years ago
Brian Hicks 6d1f3bec52 pin nixpkgs 2 years ago
Brian Hicks 5d1e02c9cf niv init 2 years ago
Brian Hicks a5cde5058b build out to the stub of downloading the binary 2 years ago
Brian Hicks 71d82de6ac get binary 2 years ago
Brian Hicks 7435215758 make a cache location function 2 years ago
Brian Hicks c1fee18656 add todo 2 years ago
Brian Hicks b8007c0b60 add a function to get download locations 2 years ago
Brian Hicks a8bd830636 sort shell deps 2 years ago
Brian Hicks e056f8ddc7 add bench to shell deps 2 years ago
Brian Hicks b977a8f11c update elm-swapper.nix 2 years ago
Brian Hicks dc87034349 rearrange to remove intermediate values 2 years ago
Brian Hicks 98f38625e6 parse version number 2 years ago
Brian Hicks 798724e98a add a decoder which hypothetically works? 2 years ago
Brian Hicks 2fd304394f hindent 2 years ago
Brian Hicks a3fa4e19cd more ignores 2 years ago
Brian Hicks 09349152f7 ignore stuff from cabal 2 years ago
Brian Hicks fc7b7158a4 add aeson dep 2 years ago
Brian Hicks 464def86d3 add cabal tool in shell 2 years ago
Brian Hicks 357780b367 add a target to rebuild elm-swapper.nix 2 years ago
Brian Hicks 6bb6ee6cf4 get the nearest elm.json 2 years ago
Brian Hicks cf0dda73b7 get the current directory 2 years ago
Brian Hicks ec2f4630b1 add directory to deps 2 years ago
Brian Hicks 9a7e471dd0 try that again 2 years ago
Brian Hicks ddfc87a064 ignore result file 2 years ago
Brian Hicks c2a98c5f3c add release files 2 years ago
Brian Hicks 3ff920ae89 make build tools happy 2 years ago
Brian Hicks 3e48621d3d cabal init 2 years ago
  1. 4
      .gitignore
  2. 5
      CHANGELOG.md
  3. 1
      LICENSE
  4. 2
      Makefile
  5. 2
      Setup.hs
  6. 72
      elm-swapper.cabal
  7. 16
      elm-swapper.nix
  8. 38
      nix/sources.json
  9. 93
      nix/sources.nix
  10. 5
      release.nix
  11. 22
      shell.nix
  12. 92
      src/Main.hs

4
.gitignore

@ -0,0 +1,4 @@
/.ghc.environment.*
/cabal.project.local
/dist-newstyle
/result

5
CHANGELOG.md

@ -0,0 +1,5 @@
# Revision history for elm-swapper
## 0.1.0.0 -- YYYY-mm-dd
* First version. Released on an unsuspecting world.

1
LICENSE

@ -0,0 +1 @@
you don't have permission to use this yet. This LICENSE file only exists to make the build tools happier.

2
Makefile

@ -0,0 +1,2 @@
elm-swapper.nix: elm-swapper.cabal
cabal2nix . > $@

2
Setup.hs

@ -0,0 +1,2 @@
import Distribution.Simple
main = defaultMain

72
elm-swapper.cabal

@ -0,0 +1,72 @@
cabal-version: 2.4
-- Initial package description 'elm-swapper.cabal' generated by 'cabal
-- init'. For further documentation, see
-- http://haskell.org/cabal/users-guide/
-- The name of the package.
name: elm-swapper
-- The package version. See the Haskell package versioning policy (PVP)
-- for standards guiding when and how versions should be incremented.
-- https://pvp.haskell.org
-- PVP summary: +-+------- breaking API changes
-- | | +----- non-breaking API additions
-- | | | +--- code changes with no API change
version: 0.1.0.0
-- A short (one-line) description of the package.
synopsis: automatically dispatch to the right version of Elm
-- A longer description of the package.
-- description:
-- A URL where users can report bugs.
-- bug-reports:
-- The license under which the package is released.
license: NONE
-- The file containing the license text.
license-file: LICENSE
-- The package author(s).
author: Brian Hicks
-- An email address to which users can send suggestions, bug reports, and
-- patches.
maintainer: brian@brianthicks.com
-- A copyright notice.
-- copyright:
category: Development
-- Extra files to be distributed with the package, such as examples or a
-- README.
extra-source-files: CHANGELOG.md, README.md
executable elm-swapper
-- .hs or .lhs file containing the Main module.
main-is: Main.hs
-- Modules included in this executable, other than Main.
-- other-modules:
-- LANGUAGE extensions used by modules in this package.
-- other-extensions:
-- Other library packages from which modules are imported.
build-depends: base ^>=4.12.0.0,
directory ^>=1.3.3.0,
filepath ^>=1.4.2.1,
bytestring^>=0.10.8.2,
aeson
-- Directories containing source files.
hs-source-dirs: src
-- Base language which the package is written in.
default-language: Haskell2010

16
elm-swapper.nix

@ -0,0 +1,16 @@
{ mkDerivation, aeson, base, bytestring, directory, filepath
, stdenv
}:
mkDerivation {
pname = "elm-swapper";
version = "0.1.0.0";
src = ./.;
isLibrary = false;
isExecutable = true;
executableHaskellDepends = [
aeson base bytestring directory filepath
];
description = "automatically dispatch to the right version of Elm";
license = "unknown";
hydraPlatforms = stdenv.lib.platforms.none;
}

38
nix/sources.json

@ -0,0 +1,38 @@
{
"niv": {
"branch": "master",
"description": "Easy dependency management for Nix projects",
"homepage": "https://github.com/nmattia/niv",
"owner": "nmattia",
"repo": "niv",
"rev": "1dd094156b249586b66c16200ecfd365c7428dc0",
"sha256": "1b2vjnn8iac5iiqszjc2v1s1ygh0yri998c0k3s4x4kn0dsqik21",
"type": "tarball",
"url": "https://github.com/nmattia/niv/archive/1dd094156b249586b66c16200ecfd365c7428dc0.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"nixpkgs": {
"branch": "nixpkgs-unstable",
"description": "A read-only mirror of NixOS/nixpkgs tracking the released channels. Send issues and PRs to",
"homepage": "https://github.com/NixOS/nixpkgs",
"owner": "NixOS",
"repo": "nixpkgs-channels",
"rev": "bef773ed53f3d535792d7d7ff3ea50a3deeb1cdd",
"sha256": "0jhkh6gjdfwk398lkmzb16dgg6h6xyq5l7bh3sa3iw46byfk5i16",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs-channels/archive/bef773ed53f3d535792d7d7ff3ea50a3deeb1cdd.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"ormolu": {
"branch": "master",
"description": "A formatter for Haskell source code",
"homepage": null,
"owner": "tweag",
"repo": "ormolu",
"rev": "3abadaefa5e190ff346f9aeb309465ac890495c2",
"sha256": "0vqrb12bsp1dczff3i5pajzhjwz035rxg8vznrgj5p6j7mb2vcnd",
"type": "tarball",
"url": "https://github.com/tweag/ormolu/archive/3abadaefa5e190ff346f9aeb309465ac890495c2.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}
}

93
nix/sources.nix

@ -0,0 +1,93 @@
# This file has been generated by Niv.
# A record, from name to path, of the third-party packages
with rec
{
pkgs =
if hasNixpkgsPath
then
if hasThisAsNixpkgsPath
then import (builtins_fetchTarball { inherit (sources_nixpkgs) url sha256; }) {}
else import <nixpkgs> {}
else
import (builtins_fetchTarball { inherit (sources_nixpkgs) url sha256; }) {};
sources_nixpkgs =
if builtins.hasAttr "nixpkgs" sources
then sources.nixpkgs
else abort
''
Please specify either <nixpkgs> (through -I or NIX_PATH=nixpkgs=...) or
add a package called "nixpkgs" to your sources.json.
'';
# fetchTarball version that is compatible between all the versions of Nix
builtins_fetchTarball =
{ url, sha256 }@attrs:
let
inherit (builtins) lessThan nixVersion fetchTarball;
in
if lessThan nixVersion "1.12" then
fetchTarball { inherit url; }
else
fetchTarball attrs;
# fetchurl version that is compatible between all the versions of Nix
builtins_fetchurl =
{ url, sha256 }@attrs:
let
inherit (builtins) lessThan nixVersion fetchurl;
in
if lessThan nixVersion "1.12" then
fetchurl { inherit url; }
else
fetchurl attrs;
# A wrapper around pkgs.fetchzip that has inspectable arguments,
# annoyingly this means we have to specify them
fetchzip = { url, sha256 }@attrs: pkgs.fetchzip attrs;
# A wrapper around pkgs.fetchurl that has inspectable arguments,
# annoyingly this means we have to specify them
fetchurl = { url, sha256 }@attrs: pkgs.fetchurl attrs;
hasNixpkgsPath = (builtins.tryEval <nixpkgs>).success;
hasThisAsNixpkgsPath =
(builtins.tryEval <nixpkgs>).success && <nixpkgs> == ./.;
sources = builtins.fromJSON (builtins.readFile ./sources.json);
mapAttrs = builtins.mapAttrs or
(f: set: with builtins;
listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set)));
# borrowed from nixpkgs
functionArgs = f: f.__functionArgs or (builtins.functionArgs f);
callFunctionWith = autoArgs: f: args:
let auto = builtins.intersectAttrs (functionArgs f) autoArgs;
in f (auto // args);
getFetcher = spec:
let fetcherName =
if builtins.hasAttr "type" spec
then builtins.getAttr "type" spec
else "builtin-tarball";
in builtins.getAttr fetcherName {
"tarball" = fetchzip;
"builtin-tarball" = builtins_fetchTarball;
"file" = fetchurl;
"builtin-url" = builtins_fetchurl;
};
};
# NOTE: spec must _not_ have an "outPath" attribute
mapAttrs (_: spec:
if builtins.hasAttr "outPath" spec
then abort
"The values in sources.json should not have an 'outPath' attribute"
else
if builtins.hasAttr "url" spec && builtins.hasAttr "sha256" spec
then
spec //
{ outPath = callFunctionWith spec (getFetcher spec) { }; }
else spec
) sources

5
release.nix

@ -0,0 +1,5 @@
{ compiler ? "ghc865" }:
let
sources = import ./nix/sources.nix;
nixpkgs = import sources.nixpkgs { };
in with nixpkgs; { elm-swapper = haskell.packages.${compiler}.callPackage ./elm-swapper.nix { }; }

22
shell.nix

@ -1,12 +1,10 @@
with import (builtins.fetchTarball rec {
# grab a hash from here: https://nixos.org/channels/
name = "nixpkgs-darwin-18.09pre154171.2aead2422f8";
url = "https://github.com/nixos/nixpkgs/archive/2aead2422f85562a09619a657ecab0ca405f2d72.tar.gz";
# Hash obtained using `nix-prefetch-url --unpack <url>`
sha256 = "0hg7q8ggpwni0gswa3a74nnn5pa3gi5xw29735l7w59dw9nln8lp";
}) { };
stdenv.mkDerivation {
name = "elm-swapper";
buildInputs = [ git bash jq shellcheck elmPackages.elm bench ];
}
{ compiler ? "ghc865" }:
let
sources = import ./nix/sources.nix;
niv = import sources.niv { };
nixpkgs = import sources.nixpkgs { };
ormolu = import sources.ormolu { };
in with nixpkgs;
(import ./release.nix { inherit compiler; }).elm-swapper.env.overrideAttrs (attrs: {
buildInputs = attrs.buildInputs ++ [ bench cabal-install cabal2nix elmPackages.elm git ormolu.ormolu niv.niv ];
})

92
src/Main.hs

@ -0,0 +1,92 @@
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.Aeson
import Data.Aeson.Types
import qualified Data.ByteString.Lazy
import System.Directory
import System.FilePath
import qualified System.Info
nearestElmJson :: IO (Maybe FilePath)
nearestElmJson = getCurrentDirectory >>= nearestElmJsonHelp
nearestElmJsonHelp :: FilePath -> IO (Maybe FilePath)
nearestElmJsonHelp filepath = do
let candidate = filepath </> "elm.json"
exists <- doesFileExist candidate
if exists
then pure $ Just candidate
else
let next = takeDirectory filepath
in if next == filepath
then pure Nothing
else nearestElmJsonHelp next
data Version
= Version String
deriving (Show)
instance FromJSON Version where
parseJSON = withObject "Version" (\o -> fmap Version (o .: "elm-version"))
elmVersionFromElmJson :: IO Version
elmVersionFromElmJson = do
elmJson <- nearestElmJson
case elmJson of
Nothing -> pure $ Version "0.19.0"
Just path -> do
json <- Data.ByteString.Lazy.readFile path
case eitherDecode json of
Left message -> fail message
Right version -> pure version
downloadURL :: String -> Either String String
downloadURL version =
let possiblyOS =
case System.Info.os of
"darwin" -> Right "mac"
"linux" -> Right "linux"
-- TODO: what is the identifier for Windows?
_ ->
Left
( "I don't know how to download binaries for the "
++ System.Info.os
++ " operating system right now!"
)
possiblyArch =
case System.Info.arch of
"x86_64" -> Right "64-bit"
_ ->
Left
( "I don't know how to download binaries for the "
++ System.Info.arch
++ " architecture right now!"
)
downloadURLHelp :: String -> String -> String
downloadURLHelp os arch =
"https://github.com/elm/compiler/releases/download/"
++ version
++ "/binary-for-"
++ os
++ "-"
++ arch
++ ".gz"
in downloadURLHelp <$> possiblyOS <*> possiblyArch
cacheLocation :: String -> IO String
cacheLocation version =
getXdgDirectory XdgCache ("elm-swapper" </> version </> "elm")
main :: IO ()
main = do
(Version elmVersion) <- elmVersionFromElmJson
binary <- cacheLocation elmVersion
binaryExists <- doesFileExist binary
if not binaryExists
then case downloadURL elmVersion of
Left err -> fail err
Right url ->
fail $ "TODO: get the binary from " ++ url
else fail "TODO: handle what happens when the binary exists"
Loading…
Cancel
Save