2016-02-09 20:28:29 +00:00
# pragma once
2019-10-14 12:40:16 +00:00
# include "installables.hh"
2016-02-09 20:28:29 +00:00
# include "args.hh"
2017-10-24 10:45:11 +00:00
# include "common-eval-args.hh"
2019-12-05 18:11:09 +00:00
# include "path.hh"
2020-01-29 13:57:57 +00:00
# include "flake/lockfile.hh"
2019-10-14 12:40:16 +00:00
2019-03-21 08:30:16 +00:00
# include <optional>
2016-02-09 20:28:29 +00:00
namespace nix {
2018-01-31 15:14:47 +00:00
extern std : : string programPath ;
2021-01-13 23:05:04 +00:00
extern char * * savedArgv ;
2017-04-25 10:06:32 +00:00
class EvalState ;
2019-11-08 14:13:32 +00:00
struct Pos ;
2016-02-09 20:28:29 +00:00
class Store ;
2019-05-29 13:31:07 +00:00
2020-05-05 13:18:23 +00:00
static constexpr Command : : Category catSecondary = 100 ;
static constexpr Command : : Category catUtility = 101 ;
static constexpr Command : : Category catNixInstallation = 102 ;
2021-01-25 18:03:13 +00:00
static constexpr auto installablesCategory = " Options that change the interpretation of installables " ;
2020-08-17 15:44:52 +00:00
struct NixMultiCommand : virtual MultiCommand , virtual Command
{
nlohmann : : json toJSON ( ) override ;
} ;
2019-10-27 17:45:02 +00:00
/* A command that requires a Nix store. */
2016-02-09 20:28:29 +00:00
struct StoreCommand : virtual Command
{
2016-03-21 17:03:36 +00:00
StoreCommand ( ) ;
2016-02-09 20:28:29 +00:00
void run ( ) override ;
2017-04-25 09:20:37 +00:00
ref < Store > getStore ( ) ;
2017-03-16 13:25:54 +00:00
virtual ref < Store > createStore ( ) ;
2016-02-09 20:28:29 +00:00
virtual void run ( ref < Store > ) = 0 ;
2017-04-25 09:20:37 +00:00
private :
std : : shared_ptr < Store > _store ;
2016-02-09 20:28:29 +00:00
} ;
2022-01-17 18:45:21 +00:00
/* A command that copies something between `--from` and `--to`
stores . */
struct CopyCommand : virtual StoreCommand
{
std : : string srcUri , dstUri ;
CopyCommand ( ) ;
ref < Store > createStore ( ) override ;
ref < Store > getDstStore ( ) ;
} ;
2019-05-16 20:48:16 +00:00
struct EvalCommand : virtual StoreCommand , MixEvalArgs
{
2021-06-29 19:09:48 +00:00
EvalCommand ( ) ;
~ EvalCommand ( ) ;
ref < Store > getEvalStore ( ) ;
2019-05-16 20:48:16 +00:00
ref < EvalState > getEvalState ( ) ;
2021-06-29 19:09:48 +00:00
private :
std : : shared_ptr < Store > evalStore ;
std : : shared_ptr < EvalState > evalState ;
2019-05-16 20:48:16 +00:00
} ;
2020-06-08 14:20:00 +00:00
struct MixFlakeOptions : virtual Args , EvalCommand
2017-04-25 10:06:32 +00:00
{
2020-01-29 13:57:57 +00:00
flake : : LockFlags lockFlags ;
2019-05-22 11:46:07 +00:00
MixFlakeOptions ( ) ;
2020-06-08 14:20:00 +00:00
virtual std : : optional < FlakeRef > getFlakeRefForCompletion ( )
{ return { } ; }
2019-05-22 11:46:07 +00:00
} ;
2020-06-08 14:20:00 +00:00
struct SourceExprCommand : virtual Args , MixFlakeOptions
2019-05-22 11:46:07 +00:00
{
std : : optional < Path > file ;
2019-11-26 23:05:30 +00:00
std : : optional < std : : string > expr ;
2019-05-22 11:46:07 +00:00
2020-07-15 18:22:52 +00:00
// FIXME: move this; not all commands (e.g. 'nix run') use it.
OperateOn operateOn = OperateOn : : Output ;
2019-05-22 11:46:07 +00:00
SourceExprCommand ( ) ;
2019-05-14 09:34:45 +00:00
2019-04-08 14:11:17 +00:00
std : : vector < std : : shared_ptr < Installable > > parseInstallables (
ref < Store > store , std : : vector < std : : string > ss ) ;
std : : shared_ptr < Installable > parseInstallable (
ref < Store > store , const std : : string & installable ) ;
Support non-x86_64-linux system types in flakes
A command like
$ nix run nixpkgs#hello
will now build the attribute 'packages.${system}.hello' rather than
'packages.hello'. Note that this does mean that the flake needs to
export an attribute for every system type it supports, and you can't
build on unsupported systems. So 'packages' typically looks like this:
packages = nixpkgs.lib.genAttrs ["x86_64-linux" "i686-linux"] (system: {
hello = ...;
});
The 'checks', 'defaultPackage', 'devShell', 'apps' and 'defaultApp'
outputs similarly are now attrsets that map system types to
derivations/apps. 'nix flake check' checks that the derivations for
all platforms evaluate correctly, but only builds the derivations in
'checks.${system}'.
Fixes #2861. (That issue also talks about access to ~/.config/nixpkgs
and --arg, but I think it's reasonable to say that flakes shouldn't
support those.)
The alternative to attribute selection is to pass the system type as
an argument to the flake's 'outputs' function, e.g. 'outputs = { self,
nixpkgs, system }: ...'. However, that approach would be at odds with
hermetic evaluation and make it impossible to enumerate the packages
provided by a flake.
2019-10-15 15:52:10 +00:00
virtual Strings getDefaultFlakeAttrPaths ( ) ;
2019-06-17 14:58:59 +00:00
Support non-x86_64-linux system types in flakes
A command like
$ nix run nixpkgs#hello
will now build the attribute 'packages.${system}.hello' rather than
'packages.hello'. Note that this does mean that the flake needs to
export an attribute for every system type it supports, and you can't
build on unsupported systems. So 'packages' typically looks like this:
packages = nixpkgs.lib.genAttrs ["x86_64-linux" "i686-linux"] (system: {
hello = ...;
});
The 'checks', 'defaultPackage', 'devShell', 'apps' and 'defaultApp'
outputs similarly are now attrsets that map system types to
derivations/apps. 'nix flake check' checks that the derivations for
all platforms evaluate correctly, but only builds the derivations in
'checks.${system}'.
Fixes #2861. (That issue also talks about access to ~/.config/nixpkgs
and --arg, but I think it's reasonable to say that flakes shouldn't
support those.)
The alternative to attribute selection is to pass the system type as
an argument to the flake's 'outputs' function, e.g. 'outputs = { self,
nixpkgs, system }: ...'. However, that approach would be at odds with
hermetic evaluation and make it impossible to enumerate the packages
provided by a flake.
2019-10-15 15:52:10 +00:00
virtual Strings getDefaultFlakeAttrPathPrefixes ( ) ;
2020-05-11 19:49:02 +00:00
void completeInstallable ( std : : string_view prefix ) ;
2017-07-17 17:02:56 +00:00
} ;
/* A command that operates on a list of "installables", which can be
store paths , attribute paths , Nix expressions , etc . */
struct InstallablesCommand : virtual Args , SourceExprCommand
{
std : : vector < std : : shared_ptr < Installable > > installables ;
2020-05-11 13:46:18 +00:00
InstallablesCommand ( ) ;
2017-07-17 17:02:56 +00:00
2017-04-25 10:06:32 +00:00
void prepare ( ) override ;
2019-04-19 14:07:37 +00:00
virtual bool useDefaultInstallables ( ) { return true ; }
2020-06-08 14:20:00 +00:00
std : : optional < FlakeRef > getFlakeRefForCompletion ( ) override ;
2017-04-25 10:06:32 +00:00
private :
2017-10-24 10:45:11 +00:00
std : : vector < std : : string > _installables ;
2017-04-25 10:06:32 +00:00
} ;
2019-10-27 17:45:02 +00:00
/* A command that operates on exactly one "installable" */
2017-08-29 14:18:00 +00:00
struct InstallableCommand : virtual Args , SourceExprCommand
{
std : : shared_ptr < Installable > installable ;
2020-05-11 19:49:02 +00:00
InstallableCommand ( ) ;
2017-08-29 14:18:00 +00:00
void prepare ( ) override ;
2020-06-08 14:20:00 +00:00
std : : optional < FlakeRef > getFlakeRefForCompletion ( ) override
{
return parseFlakeRef ( _installable , absPath ( " . " ) ) ;
}
2017-08-29 14:18:00 +00:00
private :
2019-12-14 22:15:36 +00:00
std : : string _installable { " . " } ;
2017-08-29 14:18:00 +00:00
} ;
2017-04-25 11:20:26 +00:00
/* A command that operates on zero or more store paths. */
2021-05-17 06:45:08 +00:00
struct BuiltPathsCommand : public InstallablesCommand
2017-04-25 11:20:26 +00:00
{
private :
bool recursive = false ;
bool all = false ;
2018-03-29 22:56:13 +00:00
protected :
2020-07-15 18:05:42 +00:00
Realise realiseMode = Realise : : Derivation ;
2018-03-29 22:56:13 +00:00
2017-04-25 11:20:26 +00:00
public :
2021-05-17 06:45:08 +00:00
BuiltPathsCommand ( bool recursive = false ) ;
2017-04-25 11:20:26 +00:00
using StoreCommand : : run ;
2021-09-27 08:53:09 +00:00
virtual void run ( ref < Store > store , BuiltPaths & & paths ) = 0 ;
2017-04-25 11:20:26 +00:00
void run ( ref < Store > store ) override ;
2019-04-19 14:07:37 +00:00
bool useDefaultInstallables ( ) override { return ! all ; }
2017-04-25 11:20:26 +00:00
} ;
2021-05-17 06:45:08 +00:00
struct StorePathsCommand : public BuiltPathsCommand
2020-12-14 16:24:30 +00:00
{
StorePathsCommand ( bool recursive = false ) ;
2021-05-17 06:45:08 +00:00
using BuiltPathsCommand : : run ;
2020-12-14 16:24:30 +00:00
2021-09-27 08:53:09 +00:00
virtual void run ( ref < Store > store , std : : vector < StorePath > & & storePaths ) = 0 ;
2020-12-14 16:24:30 +00:00
2021-09-27 08:53:09 +00:00
void run ( ref < Store > store , BuiltPaths & & paths ) override ;
2020-12-14 16:24:30 +00:00
} ;
2017-05-04 12:16:26 +00:00
/* A command that operates on exactly one store path. */
2021-02-12 17:33:28 +00:00
struct StorePathCommand : public StorePathsCommand
2017-05-04 12:16:26 +00:00
{
2021-02-12 17:33:28 +00:00
using StorePathsCommand : : run ;
2017-05-04 12:16:26 +00:00
2019-12-05 18:11:09 +00:00
virtual void run ( ref < Store > store , const StorePath & storePath ) = 0 ;
2017-05-04 12:16:26 +00:00
2021-09-27 08:53:09 +00:00
void run ( ref < Store > store , std : : vector < StorePath > & & storePaths ) override ;
2017-05-04 12:16:26 +00:00
} ;
2016-02-09 20:28:29 +00:00
/* A helper class for registering commands globally. */
struct RegisterCommand
{
2020-12-03 16:55:27 +00:00
typedef std : : map < std : : vector < std : : string > , std : : function < ref < Command > ( ) > > Commands ;
2019-06-18 14:01:35 +00:00
static Commands * commands ;
2016-02-09 20:28:29 +00:00
2020-12-03 16:55:27 +00:00
RegisterCommand ( std : : vector < std : : string > & & name ,
2019-06-18 14:01:35 +00:00
std : : function < ref < Command > ( ) > command )
2016-02-09 20:28:29 +00:00
{
2019-06-18 14:01:35 +00:00
if ( ! commands ) commands = new Commands ;
commands - > emplace ( name , command ) ;
2016-02-09 20:28:29 +00:00
}
2020-12-03 16:55:27 +00:00
static nix : : Commands getCommandsFor ( const std : : vector < std : : string > & prefix ) ;
2016-02-09 20:28:29 +00:00
} ;
2019-06-18 14:01:35 +00:00
template < class T >
static RegisterCommand registerCommand ( const std : : string & name )
{
2020-12-03 16:55:27 +00:00
return RegisterCommand ( { name } , [ ] ( ) { return make_ref < T > ( ) ; } ) ;
}
template < class T >
static RegisterCommand registerCommand2 ( std : : vector < std : : string > & & name )
{
return RegisterCommand ( std : : move ( name ) , [ ] ( ) { return make_ref < T > ( ) ; } ) ;
2019-06-18 14:01:35 +00:00
}
2019-11-08 14:13:32 +00:00
/* Helper function to generate args that invoke $EDITOR on
filename : lineno . */
Strings editorFor ( const Pos & pos ) ;
2020-03-30 17:14:17 +00:00
struct MixProfile : virtual StoreCommand
2019-07-12 13:32:17 +00:00
{
std : : optional < Path > profile ;
MixProfile ( ) ;
/* If 'profile' is set, make it point at 'storePath'. */
2019-12-11 13:53:30 +00:00
void updateProfile ( const StorePath & storePath ) ;
2019-07-12 13:32:17 +00:00
/* If 'profile' is set, make it point at the store path produced
by ' buildables ' . */
2021-05-12 14:19:51 +00:00
void updateProfile ( const BuiltPaths & buildables ) ;
2019-07-12 13:32:17 +00:00
} ;
2019-10-21 22:21:58 +00:00
struct MixDefaultProfile : MixProfile
{
MixDefaultProfile ( ) ;
} ;
2019-11-07 23:16:48 +00:00
struct MixEnvironment : virtual Args {
StringSet keep , unset ;
Strings stringsEnv ;
std : : vector < char * > vectorEnv ;
bool ignoreEnvironment ;
MixEnvironment ( ) ;
/* Modify global environ based on ignoreEnvironment, keep, and unset. It's expected that exec will be called before this class goes out of scope, otherwise environ will become invalid. */
void setEnviron ( ) ;
} ;
2020-06-05 12:09:12 +00:00
void completeFlakeRef ( ref < Store > store , std : : string_view prefix ) ;
void completeFlakeRefWithFragment (
ref < EvalState > evalState ,
flake : : LockFlags lockFlags ,
Strings attrPathPrefixes ,
const Strings & defaultFlakeAttrPaths ,
std : : string_view prefix ) ;
2021-01-12 22:51:07 +00:00
std : : string showVersions ( const std : : set < std : : string > & versions ) ;
2020-07-16 15:00:42 +00:00
void printClosureDiff (
ref < Store > store ,
const StorePath & beforePath ,
const StorePath & afterPath ,
std : : string_view indent ) ;
2016-02-09 20:28:29 +00:00
}