2017-11-01 17:32:53 +02:00
# include "primops.hh"
# include "eval-inline.hh"
# include "store-api.hh"
2020-03-30 17:04:18 +03:00
# include "fetchers.hh"
# include "url.hh"
2020-09-21 19:22:45 +03:00
# include "url-parts.hh"
2017-11-01 17:32:53 +02:00
namespace nix {
static void prim_fetchMercurial ( EvalState & state , const Pos & pos , Value * * args , Value & v )
{
std : : string url ;
2020-03-30 17:04:18 +03:00
std : : optional < Hash > rev ;
std : : optional < std : : string > ref ;
2022-01-21 15:44:00 +02:00
std : : string_view name = " source " ;
2017-11-01 17:32:53 +02:00
PathSet context ;
2021-10-15 07:23:04 +03:00
state . forceValue ( * args [ 0 ] , pos ) ;
2017-11-01 17:32:53 +02:00
2020-12-17 15:45:45 +02:00
if ( args [ 0 ] - > type ( ) = = nAttrs ) {
2017-11-01 17:32:53 +02:00
for ( auto & attr : * args [ 0 ] - > attrs ) {
2022-01-21 15:44:00 +02:00
std : : string_view n ( attr . name ) ;
2017-11-01 17:32:53 +02:00
if ( n = = " url " )
2022-03-07 12:33:03 +02:00
url = state . coerceToString ( * attr . pos , * attr . value , context , false , false , " While evaluating the `url` attribute passed to builtins.fetchMercurial: " ) . toOwned ( ) ;
2020-03-30 17:04:18 +03:00
else if ( n = = " rev " ) {
// Ugly: unlike fetchGit, here the "rev" attribute can
// be both a revision or a branch/tag name.
2022-03-07 12:33:03 +02:00
auto value = state . forceStringNoCtx ( * attr . value , * attr . pos , " While evaluating the `rev` attribute passed to builtins.fetchMercurial: " ) ;
2022-01-21 15:44:00 +02:00
if ( std : : regex_match ( value . begin ( ) , value . end ( ) , revRegex ) )
2020-07-02 01:34:18 +03:00
rev = Hash : : parseAny ( value , htSHA1 ) ;
2020-03-30 17:04:18 +03:00
else
ref = value ;
}
2017-11-01 17:32:53 +02:00
else if ( n = = " name " )
2022-03-07 12:33:03 +02:00
name = state . forceStringNoCtx ( * attr . value , * attr . pos , " While evaluating the `name` attribute passed to builtins.fetchMercurial: " ) ;
2017-11-01 17:32:53 +02:00
else
2020-06-15 15:06:58 +03:00
throw EvalError ( {
2021-01-21 01:27:36 +02:00
. msg = hintfmt ( " unsupported argument '%s' to 'fetchMercurial' " , attr . name ) ,
2020-06-24 00:30:13 +03:00
. errPos = * attr . pos
2020-06-15 15:06:58 +03:00
} ) ;
2017-11-01 17:32:53 +02:00
}
if ( url . empty ( ) )
2020-06-15 15:06:58 +03:00
throw EvalError ( {
2021-01-21 01:27:36 +02:00
. msg = hintfmt ( " 'url' argument required " ) ,
2020-06-24 00:30:13 +03:00
. errPos = pos
2020-06-15 15:06:58 +03:00
} ) ;
2017-11-01 17:32:53 +02:00
} else
2022-03-07 12:33:03 +02:00
url = state . coerceToString ( pos , * args [ 0 ] , context , false , false , " While evaluating the first argument passed to builtins.fetchMercurial: " ) . toOwned ( ) ;
2017-11-01 17:32:53 +02:00
// FIXME: git externals probably can be used to bypass the URI
// whitelist. Ah well.
state . checkURI ( url ) ;
2020-03-30 17:04:18 +03:00
if ( evalSettings . pureEval & & ! rev )
throw Error ( " in pure evaluation mode, 'fetchMercurial' requires a Mercurial revision " ) ;
2020-04-07 15:00:12 +03:00
fetchers : : Attrs attrs ;
attrs . insert_or_assign ( " type " , " hg " ) ;
attrs . insert_or_assign ( " url " , url . find ( " :// " ) ! = std : : string : : npos ? url : " file:// " + url ) ;
2022-02-25 17:00:00 +02:00
attrs . insert_or_assign ( " name " , std : : string ( name ) ) ;
2020-04-07 15:00:12 +03:00
if ( ref ) attrs . insert_or_assign ( " ref " , * ref ) ;
if ( rev ) attrs . insert_or_assign ( " rev " , rev - > gitRev ( ) ) ;
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-30 01:44:11 +03:00
auto input = fetchers : : Input : : fromAttrs ( std : : move ( attrs ) ) ;
2020-03-30 17:04:18 +03:00
2020-04-07 15:00:12 +03:00
// FIXME: use name
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-30 01:44:11 +03:00
auto [ tree , input2 ] = input . fetch ( state . store ) ;
2017-11-01 17:32:53 +02:00
2022-01-04 18:39:16 +02:00
auto attrs2 = state . buildBindings ( 8 ) ;
2020-03-30 17:04:18 +03:00
auto storePath = state . store - > printStorePath ( tree . storePath ) ;
2022-01-04 18:39:16 +02:00
attrs2 . alloc ( state . sOutPath ) . mkString ( storePath , { storePath } ) ;
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-30 01:44:11 +03:00
if ( input2 . getRef ( ) )
2022-01-04 18:39:16 +02:00
attrs2 . alloc ( " branch " ) . mkString ( * input2 . getRef ( ) ) ;
2020-03-30 17:04:18 +03:00
// Backward compatibility: set 'rev' to
// 0000000000000000000000000000000000000000 for a dirty tree.
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-30 01:44:11 +03:00
auto rev2 = input2 . getRev ( ) . value_or ( Hash ( htSHA1 ) ) ;
2022-01-04 18:39:16 +02:00
attrs2 . alloc ( " rev " ) . mkString ( rev2 . gitRev ( ) ) ;
attrs2 . alloc ( " shortRev " ) . mkString ( rev2 . gitRev ( ) . substr ( 0 , 12 ) ) ;
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-30 01:44:11 +03:00
if ( auto revCount = input2 . getRevCount ( ) )
2022-01-04 18:39:16 +02:00
attrs2 . alloc ( " revCount " ) . mkInt ( * revCount ) ;
v . mkAttrs ( attrs2 ) ;
2018-01-16 19:50:38 +02:00
2021-10-07 15:07:51 +03:00
state . allowPath ( tree . storePath ) ;
2017-11-01 17:32:53 +02:00
}
2020-10-06 14:36:55 +03:00
static RegisterPrimOp r_fetchMercurial ( " fetchMercurial " , 1 , prim_fetchMercurial ) ;
2017-11-01 17:32:53 +02:00
}