@@ -16,6 +16,7 @@ package engine
1616
1717import (
1818 "context"
19+ "fmt"
1920 "maps"
2021 "os"
2122 "strconv"
@@ -595,6 +596,96 @@ func doltSessionFactory(
595596 }
596597}
597598
599+ var ErrFailedToInitCommitIdent = fmt .Errorf ("failed to initialize commit identity session variables from environment" )
600+
601+ // envSessionVar pairs an environment variable with the session variable it populates when non-empty.
602+ type envSessionVar struct {
603+ envVar string
604+ sessionVar string
605+ }
606+
607+ // commitIdentEnvOverrides lists the DOLT_AUTHOR_* and DOLT_COMMITTER_* environment variables
608+ // that [InitClientCommitIdentSession] maps to their corresponding session variables.
609+ var commitIdentEnvOverrides = []envSessionVar {
610+ {dconfig .EnvDoltAuthorName , dsess .DoltAuthorName },
611+ {dconfig .EnvDoltAuthorEmail , dsess .DoltAuthorEmail },
612+ {dconfig .EnvDoltAuthorDate , dsess .DoltAuthorDate },
613+ {dconfig .EnvDoltCommitterName , dsess .DoltCommitterName },
614+ {dconfig .EnvDoltCommitterEmail , dsess .DoltCommitterEmail },
615+ {dconfig .EnvDoltCommitterDate , dsess .DoltCommitterDate },
616+ }
617+
618+ // InitClientCommitIdentSession seeds the DOLT_ author and committer session variables on the
619+ // dolt CLI client's session so later DOLT_COMMIT calls attribute the commit correctly. |name|
620+ // and |email| supply the default identity for both author and committer; any non-empty
621+ // DOLT_AUTHOR_* or DOLT_COMMITTER_* environment variable overrides the matching field. Must run
622+ // after [sql.SessionCommandBegin] so the session is ready to accept SET statements. Silently
623+ // skips variables not recognised by |queryist|, so older servers remain usable.
624+ func InitClientCommitIdentSession (queryist cli.Queryist , sqlCtx * sql.Context , name , email string ) error {
625+ sessionVars := map [string ]string {
626+ dsess .DoltAuthorName : name ,
627+ dsess .DoltAuthorEmail : email ,
628+ dsess .DoltCommitterName : name ,
629+ dsess .DoltCommitterEmail : email ,
630+ }
631+
632+ for _ , pair := range commitIdentEnvOverrides {
633+ if val := os .Getenv (pair .envVar ); val != "" {
634+ sessionVars [pair .sessionVar ] = val
635+ }
636+ }
637+
638+ var showQuery strings.Builder
639+ showQuery .WriteString ("SHOW VARIABLES WHERE Variable_name IN (" )
640+ hasVariableNames := false
641+ for variableName , value := range sessionVars {
642+ if value == "" {
643+ continue
644+ }
645+ if hasVariableNames {
646+ showQuery .WriteByte (',' )
647+ }
648+ showQuery .WriteByte ('\'' )
649+ showQuery .WriteString (variableName )
650+ showQuery .WriteByte ('\'' )
651+ hasVariableNames = true
652+ }
653+ if ! hasVariableNames {
654+ return nil
655+ }
656+ showQuery .WriteByte (')' )
657+ variableRows , err := cli .GetRowsForSql (queryist , sqlCtx , showQuery .String ())
658+ if err != nil {
659+ return fmt .Errorf ("%w: %v" , ErrFailedToInitCommitIdent , err )
660+ }
661+
662+ var setStatement strings.Builder
663+ setStatement .WriteString ("SET " )
664+ hasAssignments := false
665+ for _ , row := range variableRows {
666+ variableName , ok := row [0 ].(string )
667+ if ! ok {
668+ continue
669+ }
670+ value , ok := sessionVars [strings .ToLower (variableName )]
671+ if ! ok {
672+ continue
673+ }
674+ if hasAssignments {
675+ setStatement .WriteString (", " )
676+ }
677+ fmt .Fprintf (& setStatement , "@@SESSION.%s = %q" , variableName , value )
678+ hasAssignments = true
679+ }
680+ if ! hasAssignments {
681+ return nil
682+ }
683+ if _ , _ , _ , err := queryist .Query (sqlCtx , setStatement .String ()); err != nil {
684+ return fmt .Errorf ("%w: %v" , ErrFailedToInitCommitIdent , err )
685+ }
686+ return nil
687+ }
688+
598689type ConfigOption func (* SqlEngineConfig )
599690
600691// NewSqlEngineForEnv returns a SqlEngine configured for the environment provided, with a single root user.
0 commit comments