Example #1
0
        /// <summary>
        /// Detects root paths for the specified client.
        /// </summary>
        /// <param name="UATLocation">AutomationTool.exe location</param>
        /// <param name="ThisClient">Client to detect the root paths for</param>
        /// <param name="BuildRootPath">Build root</param>
        /// <param name="LocalRootPath">Local root</param>
        /// <param name="ClientRootPath">Client root</param>
        private static void DetectRootPaths(P4Connection Connection, string LocalRootPath, P4ClientInfo ThisClient, out string BuildRootPath, out string ClientRootPath)
        {
            // Figure out the build root
            string        KnownFilePathFromRoot = CommandEnvironment.KnownFileRelativeToRoot;
            string        KnownLocalPath        = CommandUtils.MakePathSafeToUseWithCommandLine(CommandUtils.CombinePaths(PathSeparator.Slash, LocalRootPath, KnownFilePathFromRoot));
            ProcessResult P4Result = Connection.P4(String.Format("files -m 1 {0}", KnownLocalPath), AllowSpew: false);

            string KnownFileDepotMapping = P4Result.Output;

            // Get the build root
            Log.TraceVerbose("Looking for {0} in {1}", KnownFilePathFromRoot, KnownFileDepotMapping);
            int EndIdx = KnownFileDepotMapping.IndexOf(KnownFilePathFromRoot, StringComparison.CurrentCultureIgnoreCase);

            if (EndIdx < 0)
            {
                EndIdx = KnownFileDepotMapping.IndexOf(CommandUtils.ConvertSeparators(PathSeparator.Slash, KnownFilePathFromRoot), StringComparison.CurrentCultureIgnoreCase);
            }
            // Get the root path without the trailing path separator
            BuildRootPath = KnownFileDepotMapping.Substring(0, EndIdx - 1);

            // Get the client root
            if (LocalRootPath.StartsWith(CommandUtils.CombinePaths(PathSeparator.Slash, ThisClient.RootPath, "/"), StringComparison.InvariantCultureIgnoreCase) || LocalRootPath == ThisClient.RootPath)
            {
                ClientRootPath = CommandUtils.CombinePaths(PathSeparator.Depot, String.Format("//{0}/", ThisClient.Name), LocalRootPath.Substring(ThisClient.RootPath.Length));
            }
            else
            {
                throw new AutomationException("LocalRootPath ({0}) does not start with the client root path ({1})", LocalRootPath, ThisClient.RootPath);
            }
        }
Example #2
0
        /// <summary>
        /// Detects current user name.
        /// </summary>
        /// <returns></returns>
        private static string DetectUserName(P4Connection Connection)
        {
            var UserName = String.Empty;
            var P4Result = Connection.P4("info", AllowSpew: false);

            if (P4Result.ExitCode != 0)
            {
                throw new AutomationException("Perforce command failed: {0}. Please make sure your P4PORT or {1} is set properly.", P4Result.Output, EnvVarNames.P4Port);
            }

            // Retrieve the P4 user name
            var Tags = Connection.ParseTaggedP4Output(P4Result.Output);

            if (!Tags.TryGetValue("User name", out UserName) || String.IsNullOrEmpty(UserName))
            {
                if (!String.IsNullOrEmpty(UserName))
                {
                    Log.TraceWarning("Unable to retrieve perforce user name. Trying to fall back to {0} which is set to {1}.", EnvVarNames.User, UserName);
                }
                else
                {
                    throw new AutomationException("Failed to retrieve user name.");
                }
            }

            return(UserName);
        }
Example #3
0
        /// <summary>
        /// Detects the current code changelist the workspace is synced to.
        /// </summary>
        /// <param name="ClientRootPath">Workspace path.</param>
        /// <returns>Changelist number as a string.</returns>
        private static string DetectCurrentCodeCL(P4Connection Connection, string ClientRootPath)
        {
            CommandUtils.LogVerbose("uebp_CodeCL not set, detecting last code CL...");

            // Retrieve the current changelist
            StringBuilder P4Cmd = new StringBuilder("changes -m 1");

            string[] CodeExtensions = { ".cs", ".h", ".cpp", ".inl", ".usf", ".ush", ".uproject", ".uplugin" };
            foreach (string CodeExtension in CodeExtensions)
            {
                P4Cmd.AppendFormat(" \"{0}/...{1}#have\"", CommandUtils.CombinePaths(PathSeparator.Depot, ClientRootPath), CodeExtension);
            }

            IProcessResult P4Result = Connection.P4(P4Cmd.ToString(), AllowSpew: false);

            // Loop through all the lines of the output. Even though we requested one result, we'll get one for each search pattern.
            int CL = 0;

            foreach (string Line in P4Result.Output.Split('\n'))
            {
                string[] Tokens = Line.Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                if (Tokens.Length >= 2)
                {
                    int LineCL = Int32.Parse(Tokens[1]);
                    CL = Math.Max(CL, LineCL);
                }
            }
            return(CL.ToString());
        }
Example #4
0
        protected virtual void InitEnvironment(P4Connection Connection, CommandEnvironment CmdEnv)
        {
            //
            // P4 Environment
            //

            P4Port     = CommandUtils.GetEnvVar(EnvVarNames.P4Port);
            ClientRoot = CommandUtils.GetEnvVar(EnvVarNames.ClientRoot);
            User       = CommandUtils.GetEnvVar(EnvVarNames.User);
            ChangelistStringInternal = CommandUtils.GetEnvVar(EnvVarNames.Changelist, null);
            Client      = CommandUtils.GetEnvVar(EnvVarNames.Client);
            BuildRootP4 = CommandUtils.GetEnvVar(EnvVarNames.BuildRootP4);
            if (BuildRootP4.EndsWith("/", StringComparison.InvariantCultureIgnoreCase) || BuildRootP4.EndsWith("\\", StringComparison.InvariantCultureIgnoreCase))
            {
                // We expect the build root to not end with a path separator
                BuildRootP4 = BuildRootP4.Substring(0, BuildRootP4.Length - 1);
                CommandUtils.SetEnvVar(EnvVarNames.BuildRootP4, BuildRootP4);
            }
            BuildRootEscaped = CommandUtils.GetEnvVar(EnvVarNames.BuildRootEscaped);
            LabelToSync      = CommandUtils.GetEnvVar(EnvVarNames.LabelToSync);

            string CodeChangelistString = CommandUtils.GetEnvVar(EnvVarNames.CodeChangelist);

            if (!String.IsNullOrEmpty(CodeChangelistString))
            {
                CodeChangelist = Int32.Parse(CodeChangelistString);
            }

            if (((CommandUtils.P4Enabled || CommandUtils.IsBuildMachine) && (ClientRoot == String.Empty || User == String.Empty ||
                                                                             (String.IsNullOrEmpty(ChangelistStringInternal) && CommandUtils.IsBuildMachine) || Client == String.Empty || BuildRootP4 == String.Empty)))
            {
                Log.TraceInformation("P4Enabled={0}", CommandUtils.P4Enabled);
                Log.TraceInformation("ClientRoot={0}", ClientRoot);
                Log.TraceInformation("User={0}", User);
                Log.TraceInformation("ChangelistString={0}", ChangelistStringInternal);
                Log.TraceInformation("Client={0}", Client);
                Log.TraceInformation("BuildRootP4={0}", BuildRootP4);

                throw new AutomationException("BUILD FAILED Perforce Environment is not set up correctly. Please check your environment variables.");
            }

            LabelPrefix = BuildRootP4 + "/";

            if (CommandUtils.P4Enabled)
            {
                if (CommandUtils.IsBuildMachine || ChangelistStringInternal != null)
                {
                    // We may not always need the changelist number if we're not a build machine.
                    // In local runs, changelist initialization can be really slow!
                    VerifyChangelistStringAndSetChangelistNumber();
                }
            }

            LogSettings();
        }
		protected virtual void InitEnvironment(P4Connection Connection, CommandEnvironment CmdEnv)
		{
			//
			// P4 Environment
			//

			P4Port = CommandUtils.GetEnvVar(EnvVarNames.P4Port);
			ClientRoot = CommandUtils.GetEnvVar(EnvVarNames.ClientRoot);
			User = CommandUtils.GetEnvVar(EnvVarNames.User);
			ChangelistStringInternal = CommandUtils.GetEnvVar(EnvVarNames.Changelist, null);
			Client = CommandUtils.GetEnvVar(EnvVarNames.Client);
			BuildRootP4 = CommandUtils.GetEnvVar(EnvVarNames.BuildRootP4);
			if (BuildRootP4.EndsWith("/", StringComparison.InvariantCultureIgnoreCase) || BuildRootP4.EndsWith("\\", StringComparison.InvariantCultureIgnoreCase))
			{
				// We expect the build root to not end with a path separator
				BuildRootP4 = BuildRootP4.Substring(0, BuildRootP4.Length - 1);
				CommandUtils.SetEnvVar(EnvVarNames.BuildRootP4, BuildRootP4);
			}
			BuildRootEscaped = CommandUtils.GetEnvVar(EnvVarNames.BuildRootEscaped);
			LabelToSync = CommandUtils.GetEnvVar(EnvVarNames.LabelToSync);

			string CodeChangelistString = CommandUtils.GetEnvVar(EnvVarNames.CodeChangelist);
			if(!String.IsNullOrEmpty(CodeChangelistString))
			{
				CodeChangelist = Int32.Parse(CodeChangelistString);
			}

			if (((CommandUtils.P4Enabled || CommandUtils.IsBuildMachine) && (ClientRoot == String.Empty || User == String.Empty ||
				(String.IsNullOrEmpty(ChangelistStringInternal) && CommandUtils.IsBuildMachine) || Client == String.Empty || BuildRootP4 == String.Empty)))
			{
                Log.TraceInformation("P4Enabled={0}", CommandUtils.P4Enabled);
                Log.TraceInformation("ClientRoot={0}",ClientRoot );
                Log.TraceInformation("User={0}", User);
                Log.TraceInformation("ChangelistString={0}", ChangelistStringInternal);
                Log.TraceInformation("Client={0}", Client);
                Log.TraceInformation("BuildRootP4={0}", BuildRootP4);

				throw new AutomationException("BUILD FAILED Perforce Environment is not set up correctly. Please check your environment variables.");
			}

			LabelPrefix = BuildRootP4 + "/";

			if (CommandUtils.P4Enabled)
			{
				if (CommandUtils.IsBuildMachine || ChangelistStringInternal != null)
				{
					// We may not always need the changelist number if we're not a build machine.
					// In local runs, changelist initialization can be really slow!
					VerifyChangelistStringAndSetChangelistNumber();
				}
			}

			LogSettings();
		}
        public override void ExecuteBuild()
        {
            // Parse the parameters
            string DepotPath = ParseParamValue("DepotPath");

            if (DepotPath == null)
            {
                throw new AutomationException("Missing -DepotPath=... parameter");
            }

            string OutputDir = ParseParamValue("OutputDir");

            if (OutputDir == null)
            {
                throw new AutomationException("Missing -OutputDir=... parameter");
            }

            // Create a temporary client to sync down the folder
            string ClientName = String.Format("{0}_{1}_SyncDepotPath_Temp", P4Env.User, Environment.MachineName);

            List <KeyValuePair <string, string> > RequiredView = new List <KeyValuePair <string, string> >();

            RequiredView.Add(new KeyValuePair <string, string>(DepotPath, "/..."));

            if (P4.DoesClientExist(ClientName))
            {
                P4.DeleteClient(ClientName);
            }

            P4ClientInfo Client = new P4ClientInfo();

            Client.Owner    = P4Env.User;
            Client.Host     = Environment.MachineName;
            Client.RootPath = OutputDir;
            Client.Name     = ClientName;
            Client.View     = RequiredView;
            Client.Stream   = null;
            Client.Options  = P4ClientOption.NoAllWrite | P4ClientOption.Clobber | P4ClientOption.NoCompress | P4ClientOption.Unlocked | P4ClientOption.NoModTime | P4ClientOption.RmDir;
            Client.LineEnd  = P4LineEnd.Local;
            P4.CreateClient(Client);

            // Sync the workspace, then delete the client
            try
            {
                P4Connection Perforce = new P4Connection(P4Env.User, ClientName);
                Perforce.Sync("-f //...");
            }
            finally
            {
                P4.DeleteClient(ClientName);
            }
        }
Example #7
0
        /// <summary>
        /// Detects a workspace given the current user name, host name and depot path.
        /// </summary>
        /// <param name="UserName">User name</param>
        /// <param name="HostName">Host</param>
        /// <param name="UATLocation">Path to UAT exe, this will be checked agains the root path.</param>
        /// <returns>Client to use.</returns>
        private static P4ClientInfo DetectClient(P4Connection Connection, string UserName, string HostName, string UATLocation)
        {
            CommandUtils.LogVerbose("uebp_CLIENT not set, detecting current client...");

            var MatchingClients = new List <P4ClientInfo>();

            P4ClientInfo[] P4Clients = Connection.GetClientsForUser(UserName, UATLocation);
            foreach (var Client in P4Clients)
            {
                if (!String.IsNullOrEmpty(Client.Host) && String.Compare(Client.Host, HostName, true) != 0)
                {
                    Log.TraceInformation("Rejecting client because of different Host {0} \"{1}\" != \"{2}\"", Client.Name, Client.Host, HostName);
                    continue;
                }

                MatchingClients.Add(Client);
            }

            P4ClientInfo ClientToUse = null;

            if (MatchingClients.Count == 0)
            {
                throw new AutomationException("No matching clientspecs found!");
            }
            else if (MatchingClients.Count == 1)
            {
                ClientToUse = MatchingClients[0];
            }
            else
            {
                // We may have empty host clients here, so pick the first non-empty one if possible
                foreach (var Client in MatchingClients)
                {
                    if (!String.IsNullOrEmpty(Client.Host) && String.Compare(Client.Host, HostName, true) == 0)
                    {
                        ClientToUse = Client;
                        break;
                    }
                }
                if (ClientToUse == null)
                {
                    Log.TraceWarning("{0} clients found that match the current host and root path. The most recently accessed client will be used.", MatchingClients.Count);
                    ClientToUse = GetMostRecentClient(MatchingClients);
                }
            }

            return(ClientToUse);
        }
Example #8
0
        /// <summary>
        /// Detects the current changelist the workspace is synced to.
        /// </summary>
        /// <param name="ClientRootPath">Workspace path.</param>
        /// <returns>Changelist number as a string.</returns>
        private static string DetectCurrentCL(P4Connection Connection, string ClientRootPath)
        {
            CommandUtils.LogVerbose("uebp_CL not set, detecting 'have' CL...");

            // Retrieve the current changelist
            var P4Result = Connection.P4("changes -m 1 " + CommandUtils.CombinePaths(PathSeparator.Depot, ClientRootPath, "/...#have"), AllowSpew: false);
            var CLTokens = P4Result.Output.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            var CLString = CLTokens[1];
            var CL       = Int32.Parse(CLString);

            if (CLString != CL.ToString())
            {
                throw new AutomationException("Failed to retrieve current changelist.");
            }
            return(CLString);
        }
Example #9
0
        /// <summary>
        /// Detects the current code changelist the workspace is synced to.
        /// </summary>
        /// <param name="ClientRootPath">Workspace path.</param>
        /// <returns>Changelist number as a string.</returns>
        private static string DetectCurrentCodeCL(P4Connection Connection, string ClientRootPath)
        {
            CommandUtils.LogVerbose("uebp_CodeCL not set, detecting last code CL...");

            // Retrieve the current changelist
            string         P4Cmd    = String.Format("changes -m 1 \"{0}/....cpp#have\" \"{0}/....h#have\" \"{0}/....inl#have\" \"{0}/....cs#have\" \"{0}/....usf#have\"", CommandUtils.CombinePaths(PathSeparator.Depot, ClientRootPath));
            IProcessResult P4Result = Connection.P4(P4Cmd, AllowSpew: false);

            // Loop through all the lines of the output. Even though we requested one result, we'll get one for each search pattern.
            int CL = 0;

            foreach (string Line in P4Result.Output.Split('\n'))
            {
                string[] Tokens = Line.Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                if (Tokens.Length >= 2)
                {
                    int LineCL = Int32.Parse(Tokens[1]);
                    CL = Math.Max(CL, LineCL);
                }
            }
            return(CL.ToString());
        }
Example #10
0
        /// <summary>
        /// Detects the current changelist the workspace is synced to.
        /// </summary>
        /// <param name="ClientRootPath">Workspace path.</param>
        /// <returns>Changelist number as a string.</returns>
        private static string DetectCurrentCL(P4Connection Connection, string ClientRootPath)
        {
            CommandUtils.LogVerbose("uebp_CL not set, detecting 'have' CL...");

            // Retrieve the current changelist
            IProcessResult P4Result = Connection.P4("changes -m 1 " + CommandUtils.CombinePaths(PathSeparator.Depot, ClientRootPath, "/...#have"), AllowSpew: false);

            string[] CLTokens = P4Result.Output.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            if (CLTokens.Length == 0)
            {
                throw new AutomationException("Unable to find current changelist (no output from 'p4 changes' command)");
            }

            string CLString = CLTokens[1];

            int CL;

            if (!Int32.TryParse(CLString, out CL) || CLString != CL.ToString())
            {
                throw new AutomationException("Unable to parse current changelist from Perforce output:\n{0}", P4Result.Output);
            }

            return(CLString);
        }
Example #11
0
        /// <summary>
        /// Initializes the environment. Tries to autodetect all source control settings.
        /// </summary>
        /// <param name="CompilationEnv">Compilation environment</param>
        protected override void InitEnvironment(P4Connection Connection, CommandEnvironment CmdEnv)
        {
            var HostName  = Environment.MachineName.ToLower();
            var P4PortEnv = Environment.GetEnvironmentVariable("P4PORT");

            if (String.IsNullOrEmpty(P4PortEnv))
            {
                P4PortEnv = DetectP4Port();
            }

            var UserName = CommandUtils.GetEnvVar(EnvVarNames.User);

            if (String.IsNullOrEmpty(UserName))
            {
                UserName = DetectUserName(Connection);
            }

            var          CommandLineClient = CommandUtils.GetEnvVar(EnvVarNames.Client);
            P4ClientInfo ThisClient        = null;

            if (String.IsNullOrEmpty(CommandLineClient) == false)
            {
                ThisClient = Connection.GetClientInfo(CommandLineClient);
                if (ThisClient == null)
                {
                    throw new AutomationException("Unable to find client {0}", CommandLineClient);
                }
                if (String.Compare(ThisClient.Owner, UserName, true) != 0)
                {
                    throw new AutomationException("Client specified with {0}={1} has a different owner then the detected user name (has: {2}, expected: {3})",
                                                  EnvVarNames.Client, CommandLineClient, ThisClient.Owner, UserName);
                }
            }
            else
            {
                ThisClient = DetectClient(Connection, UserName, HostName, CmdEnv.UATExe);
            }

            Log.TraceInformation("Using user {0} clientspec {1} {2}", UserName, ThisClient.Name, ThisClient.RootPath);
            Environment.SetEnvironmentVariable("P4CLIENT", ThisClient.Name);

            string BuildRootPath;
            string ClientRootPath;

            DetectRootPaths(Connection, CmdEnv.LocalRoot, ThisClient, out BuildRootPath, out ClientRootPath);

            CommandUtils.ConditionallySetEnvVar(EnvVarNames.P4Port, P4PortEnv);
            CommandUtils.ConditionallySetEnvVar(EnvVarNames.User, UserName);
            CommandUtils.ConditionallySetEnvVar(EnvVarNames.Client, ThisClient.Name);
            CommandUtils.ConditionallySetEnvVar(EnvVarNames.BuildRootP4, BuildRootPath);
            CommandUtils.ConditionallySetEnvVar(EnvVarNames.ClientRoot, ClientRootPath);

            var CLString = CommandUtils.GetEnvVar(EnvVarNames.Changelist, null);

            if (String.IsNullOrEmpty(CLString) && CommandUtils.P4CLRequired)
            {
                CLString = DetectCurrentCL(Connection, ClientRootPath);
            }
            if (!String.IsNullOrEmpty(CLString))
            {
                CommandUtils.ConditionallySetEnvVar(EnvVarNames.Changelist, CLString);
            }

            CommandUtils.ConditionallySetEnvVar(EnvVarNames.LabelToSync, "");
            CommandUtils.ConditionallySetEnvVar("P4USER", UserName);
            CommandUtils.ConditionallySetEnvVar("P4CLIENT", ThisClient.Name);

            var P4Password = Environment.GetEnvironmentVariable(EnvVarNames.P4Password);

            if (!String.IsNullOrEmpty(P4Password))
            {
                CommandUtils.ConditionallySetEnvVar("P4PASSWD", P4Password);
            }

            SetBuildRootEscaped();

            base.InitEnvironment(Connection, CmdEnv);
        }
Example #12
0
 internal LocalP4Environment(P4Connection Connection, CommandEnvironment CmdEnv)
     : base(Connection, CmdEnv)
 {
 }
Example #13
0
        /// <summary>
        /// Detects a workspace given the current user name, host name and depot path.
        /// </summary>
        /// <param name="UserName">User name</param>
        /// <param name="HostName">Host</param>
        /// <param name="UATLocation">Path to UAT exe, this will be checked agains the root path.</param>
        /// <returns>Client to use.</returns>
        private static P4ClientInfo DetectClient(P4Connection Connection, string UserName, string HostName, string UATLocation)
        {
            CommandUtils.LogVerbose("uebp_CLIENT not set, detecting current client...");

            // Check the default client. If it matches we can save any guess work.
            IProcessResult Result = CommandUtils.Run(HostPlatform.Current.P4Exe, "set -q P4CLIENT", null, CommandUtils.ERunOptions.NoLoggingOfRunCommand);

            if (Result.ExitCode == 0)
            {
                const string KeyName = "P4CLIENT=";
                if (Result.Output.StartsWith(KeyName))
                {
                    string       ClientName = Result.Output.Substring(KeyName.Length).Trim();
                    P4ClientInfo ClientInfo = Connection.GetClientInfo(ClientName, true);
                    if (Connection.IsValidClientForFile(ClientInfo, UATLocation))
                    {
                        return(ClientInfo);
                    }
                }
            }

            // Otherwise search for all clients that match
            List <P4ClientInfo> MatchingClients = new List <P4ClientInfo>();

            P4ClientInfo[] P4Clients = Connection.GetClientsForUser(UserName, UATLocation);
            foreach (P4ClientInfo Client in P4Clients)
            {
                if (!String.IsNullOrEmpty(Client.Host) && String.Compare(Client.Host, HostName, true) != 0)
                {
                    Log.TraceInformation("Rejecting client because of different Host {0} \"{1}\" != \"{2}\"", Client.Name, Client.Host, HostName);
                    continue;
                }

                MatchingClients.Add(Client);
            }

            P4ClientInfo ClientToUse = null;

            if (MatchingClients.Count == 0)
            {
                throw new AutomationException("No matching clientspecs found!");
            }
            else if (MatchingClients.Count == 1)
            {
                ClientToUse = MatchingClients[0];
            }
            else
            {
                // We may have empty host clients here, so pick the first non-empty one if possible
                foreach (P4ClientInfo Client in MatchingClients)
                {
                    if (!String.IsNullOrEmpty(Client.Host) && String.Compare(Client.Host, HostName, true) == 0)
                    {
                        ClientToUse = Client;
                        break;
                    }
                }
                if (ClientToUse == null)
                {
                    Log.TraceWarning("{0} clients found that match the current host and root path. The most recently accessed client will be used.", MatchingClients.Count);
                    ClientToUse = GetMostRecentClient(MatchingClients);
                }
            }

            return(ClientToUse);
        }
		/// <summary>
		/// Detects current user name.
		/// </summary>
		/// <returns></returns>
		private static string DetectUserName(P4Connection Connection)
		{
			var UserName = String.Empty;
			var P4Result = Connection.P4("info", AllowSpew: false);
			if (P4Result.ExitCode != 0)
			{
				throw new AutomationException("Perforce command failed: {0}. Please make sure your P4PORT or {1} is set properly.", P4Result.Output, EnvVarNames.P4Port);
			}

			// Retrieve the P4 user name			
			var Tags = Connection.ParseTaggedP4Output(P4Result.Output);
			Tags.TryGetValue("User name", out UserName);

			if (String.IsNullOrEmpty(UserName))
			{
				UserName = Environment.GetEnvironmentVariable(EnvVarNames.User);

				if (!String.IsNullOrEmpty(UserName))
				{
					Log.TraceWarning("Unable to retrieve perforce user name. Trying to fall back to {0} which is set to {1}.", EnvVarNames.User, UserName);
				}
				else
				{
					throw new AutomationException("Failed to retrieve user name.");
				}
			}

			Environment.SetEnvironmentVariable("P4USER", UserName);

			return UserName;
		}
Example #15
0
		/// <summary>
		/// Initializes build environment. If the build command needs a specific env-var mapping or
		/// has an extended BuildEnvironment, it must implement this method accordingly.
		/// </summary>
		static internal void InitP4Environment()
		{
			CheckP4Enabled();

			// Temporary connection - will use only the currently set env vars to connect to P4
			var DefaultConnection = new P4Connection(User: null, Client: null);
			PerforceEnvironment = Automation.IsBuildMachine ? new P4Environment(DefaultConnection, CmdEnv) : new LocalP4Environment(DefaultConnection, CmdEnv);
		}
		public override void ExecuteBuild()
		{
			// Parse the target list
			string[] Targets = ParseParamValues("Target");
			if(Targets.Length == 0)
			{
				throw new AutomationException("No targets specified (eg. -Target=\"UE4Editor Win64 Development\")");
			}

			// Parse the archive path
			string ArchivePath = ParseParamValue("Archive");
			if(ArchivePath != null && (!ArchivePath.StartsWith("//") || ArchivePath.Sum(x => (x == '/')? 1 : 0) < 4))
			{
				throw new AutomationException("Archive path is not a valid depot filename");
			}

			// Prepare the build agenda
			UE4Build.BuildAgenda Agenda = new UE4Build.BuildAgenda();
			foreach(string Target in Targets)
			{
				string[] Tokens = Target.Split(new char[]{ ' ' }, StringSplitOptions.RemoveEmptyEntries);

				UnrealTargetPlatform Platform;
				UnrealTargetConfiguration Configuration;
				if(Tokens.Length < 3 || !Enum.TryParse(Tokens[1], true, out Platform) || !Enum.TryParse(Tokens[2], true, out Configuration))
				{
					throw new AutomationException("Invalid target '{0}' - expected <TargetName> <Platform> <Configuration>");
				}

				Agenda.AddTarget(Tokens[0], Platform, Configuration, InAddArgs: String.Join(" ", Tokens.Skip(3)));
			}

			// Build everything
			UE4Build Builder = new UE4Build(this);
			Builder.Build(Agenda, InUpdateVersionFiles: ArchivePath != null);

			// Include the build products for UAT and UBT if required
			if(ParseParam("WithUAT"))
			{
				Builder.AddUATFilesToBuildProducts();
			}
			if(ParseParam("WithUBT"))
			{
				Builder.AddUBTFilesToBuildProducts();
			}

			// Archive the build products
			if(ArchivePath != null)
			{
				// Create an output folder
				string OutputFolder = Path.Combine(CommandUtils.CmdEnv.LocalRoot, "ArchiveForUGS");
				Directory.CreateDirectory(OutputFolder);

				// Create a temp folder for storing stripped PDB files
				string SymbolsFolder = Path.Combine(OutputFolder, "Symbols");
				Directory.CreateDirectory(SymbolsFolder);

				// Get the Windows toolchain
				UEToolChain WindowsToolChain = UEBuildPlatform.GetBuildPlatform(UnrealTargetPlatform.Win64).CreateContext(null).CreateToolChain(CPPTargetPlatform.Win64);

				// Figure out all the files for the archive
				Ionic.Zip.ZipFile Zip = new Ionic.Zip.ZipFile();
				Zip.UseZip64WhenSaving = Ionic.Zip.Zip64Option.Always;
				foreach(string BuildProduct in Builder.BuildProductFiles)
				{
					if(!File.Exists(BuildProduct))
					{
						throw new AutomationException("Missing build product: {0}", BuildProduct);
					}
					if(BuildProduct.EndsWith(".pdb", StringComparison.InvariantCultureIgnoreCase))
					{
						string StrippedFileName = CommandUtils.MakeRerootedFilePath(BuildProduct, CommandUtils.CmdEnv.LocalRoot, SymbolsFolder);
						Directory.CreateDirectory(Path.GetDirectoryName(StrippedFileName));
						WindowsToolChain.StripSymbols(BuildProduct, StrippedFileName);
						Zip.AddFile(StrippedFileName, Path.GetDirectoryName(CommandUtils.StripBaseDirectory(StrippedFileName, SymbolsFolder)));
					}
					else
					{
						Zip.AddFile(BuildProduct, Path.GetDirectoryName(CommandUtils.StripBaseDirectory(BuildProduct, CommandUtils.CmdEnv.LocalRoot)));
					}
				}
				// Create the zip file
				string ZipFileName = Path.Combine(OutputFolder, "Archive.zip");
				Console.WriteLine("Writing {0}...", ZipFileName);
				Zip.Save(ZipFileName);

				// Submit it to Perforce if required
				if(CommandUtils.AllowSubmit)
				{
					// Delete any existing clientspec for submitting
					string ClientName = Environment.MachineName + "_BuildForUGS";

					// Create a brand new one
					P4ClientInfo Client = new P4ClientInfo();
					Client.Owner = CommandUtils.P4Env.User;
					Client.Host = Environment.MachineName;
					Client.Stream = ArchivePath.Substring(0, ArchivePath.IndexOf('/', ArchivePath.IndexOf('/', 2) + 1));
					Client.RootPath = Path.Combine(OutputFolder, "Perforce");
					Client.Name = ClientName;
					Client.Options = P4ClientOption.NoAllWrite | P4ClientOption.NoClobber | P4ClientOption.NoCompress | P4ClientOption.Unlocked | P4ClientOption.NoModTime | P4ClientOption.RmDir;
					Client.LineEnd = P4LineEnd.Local;
					P4.CreateClient(Client, AllowSpew: false);

					// Create a new P4 connection for this workspace
					P4Connection SubmitP4 = new P4Connection(Client.Owner, Client.Name, P4Env.P4Port);
					SubmitP4.Revert("-k //...");

					// Figure out where the zip file has to go in Perforce
					P4WhereRecord WhereZipFile = SubmitP4.Where(ArchivePath, false).FirstOrDefault(x => !x.bUnmap && x.Path != null);
					if(WhereZipFile == null)
					{
						throw new AutomationException("Couldn't locate {0} in this workspace");
					}

					// Get the latest version of it
					int NewCL = SubmitP4.CreateChange(Description: String.Format("[CL {0}] Updated binaries", P4Env.Changelist));
					SubmitP4.Sync(String.Format("-k \"{0}\"", ArchivePath), AllowSpew:false);
					CommandUtils.CopyFile(ZipFileName, WhereZipFile.Path);
					SubmitP4.Add(NewCL, String.Format("\"{0}\"", ArchivePath));
					SubmitP4.Edit(NewCL, String.Format("\"{0}\"", ArchivePath));

					// Submit it
					int SubmittedCL;
					SubmitP4.Submit(NewCL, out SubmittedCL);
					if(SubmittedCL <= 0)
					{
						throw new AutomationException("Submit failed.");
					}
					Console.WriteLine("Submitted in changelist {0}", SubmittedCL);
				}
			}
		}
		/// <summary>
		/// Detects root paths for the specified client.
		/// </summary>
		/// <param name="UATLocation">AutomationTool.exe location</param>
		/// <param name="ThisClient">Client to detect the root paths for</param>
		/// <param name="BuildRootPath">Build root</param>
		/// <param name="LocalRootPath">Local root</param>
		/// <param name="ClientRootPath">Client root</param>
		private static void DetectRootPaths(P4Connection Connection, string LocalRootPath, P4ClientInfo ThisClient, out string BuildRootPath, out string ClientRootPath)
		{
			if(!String.IsNullOrEmpty(ThisClient.Stream))
			{
				BuildRootPath = ThisClient.Stream;
				ClientRootPath = String.Format("//{0}", ThisClient.Name);
			}
			else
			{
			// Figure out the build root
			string KnownFilePathFromRoot = CommandEnvironment.KnownFileRelativeToRoot;
			string KnownLocalPath = CommandUtils.MakePathSafeToUseWithCommandLine(CommandUtils.CombinePaths(PathSeparator.Slash, LocalRootPath, KnownFilePathFromRoot));
			IProcessResult P4Result = Connection.P4(String.Format("files -m 1 {0}", KnownLocalPath), AllowSpew: false);

			string KnownFileDepotMapping = P4Result.Output;

			// Get the build root
			Log.TraceVerbose("Looking for {0} in {1}", KnownFilePathFromRoot, KnownFileDepotMapping);
			int EndIdx = KnownFileDepotMapping.IndexOf(KnownFilePathFromRoot, StringComparison.CurrentCultureIgnoreCase);
			if (EndIdx < 0)
			{
				EndIdx = KnownFileDepotMapping.IndexOf(CommandUtils.ConvertSeparators(PathSeparator.Slash, KnownFilePathFromRoot), StringComparison.CurrentCultureIgnoreCase);
			}
			// Get the root path without the trailing path separator
			BuildRootPath = KnownFileDepotMapping.Substring(0, EndIdx - 1);

			// Get the client root
				if (LocalRootPath.StartsWith(CommandUtils.CombinePaths(PathSeparator.Slash, ThisClient.RootPath, "/"), StringComparison.InvariantCultureIgnoreCase) || LocalRootPath == CommandUtils.CombinePaths(PathSeparator.Slash, ThisClient.RootPath))
			{
				ClientRootPath = CommandUtils.CombinePaths(PathSeparator.Depot, String.Format("//{0}/", ThisClient.Name), LocalRootPath.Substring(ThisClient.RootPath.Length));
			}
			else
			{
				throw new AutomationException("LocalRootPath ({0}) does not start with the client root path ({1})", LocalRootPath, ThisClient.RootPath);
			}
		}
		}
        public override void ExecuteBuild()
        {
            var Params = new ProjectParams
                         (
                Command: this,
                // Shared
                RawProjectPath: ProjectPath
                         );

            Log("********** CRYPTOKEYS COMMAND STARTED **********");

            string UE4EditorExe = HostPlatform.Current.GetUE4ExePath(Params.UE4Exe);

            if (!FileExists(UE4EditorExe))
            {
                throw new AutomationException("Missing " + UE4EditorExe + " executable. Needs to be built first.");
            }

            bool bCycleAllKeys       = ParseParam("updateallkeys");
            bool bCycleEncryptionKey = bCycleAllKeys || ParseParam("updateencryptionkey");
            bool bCycleSigningKey    = bCycleAllKeys || ParseParam("updatesigningkey");

            if (!bCycleAllKeys && !bCycleEncryptionKey && !bCycleSigningKey)
            {
                throw new Exception("A target for key cycling must be specified when using the cryptokeys automation script\n\t-updateallkeys: Update all keys\n\t-updateencryptionkey: Update encryption key\n\t-updatesigningkey: Update signing key");
            }

            FileReference OutputFile         = FileReference.Combine(ProjectPath.Directory, "Config", "DefaultCrypto.ini");
            FileReference NoRedistOutputFile = FileReference.Combine(ProjectPath.Directory, "Config", "NoRedist", "DefaultCrypto.ini");
            FileReference DestinationFile    = OutputFile;

            // If the project has a DefaultCrypto.ini in a NoRedist folder, we want to copy the newly generated file into that location
            if (FileReference.Exists(NoRedistOutputFile))
            {
                DestinationFile = NoRedistOutputFile;
            }

            string ChangeDescription = "Automated update of ";

            if (bCycleEncryptionKey)
            {
                ChangeDescription += "encryption";
            }

            if (bCycleSigningKey)
            {
                if (bCycleEncryptionKey)
                {
                    ChangeDescription += " and ";
                }
                ChangeDescription += "signing";
            }

            ChangeDescription += " key";

            if (bCycleEncryptionKey && bCycleSigningKey)
            {
                ChangeDescription += "s";
            }

            ChangeDescription += " for project " + Params.ShortProjectName;

            P4Connection SubmitP4 = null;
            int          NewCL    = 0;

            if (CommandUtils.P4Enabled)
            {
                SubmitP4 = CommandUtils.P4;

                NewCL = SubmitP4.CreateChange(Description: ChangeDescription);
                SubmitP4.Revert(String.Format("-k \"{0}\"", DestinationFile.FullName));
                SubmitP4.Sync(String.Format("-k \"{0}\"", DestinationFile.FullName), AllowSpew: false);
                SubmitP4.Add(NewCL, String.Format("\"{0}\"", DestinationFile.FullName));
                SubmitP4.Edit(NewCL, String.Format("\"{0}\"", DestinationFile.FullName));
            }
            else
            {
                Log(ChangeDescription);
                FileReference.MakeWriteable(OutputFile);
            }

            string CommandletParams = "";

            if (bCycleAllKeys)
            {
                CommandletParams = "-updateallkeys";
            }
            else if (bCycleEncryptionKey)
            {
                CommandletParams = "-updateencryptionkey";
            }
            else if (bCycleSigningKey)
            {
                CommandletParams = "-updatesigningkey";
            }

            RunCommandlet(ProjectPath, UE4EditorExe, "CryptoKeys", CommandletParams);

            if (DestinationFile != OutputFile)
            {
                File.Delete(DestinationFile.FullName);
                FileReference.Move(OutputFile, DestinationFile);
            }

            if (SubmitP4 != null)
            {
                int ActualCL;
                SubmitP4.Submit(NewCL, out ActualCL);
            }
        }
        public override void ExecuteBuild()
        {
            // Parse the target list
            string[] Targets = ParseParamValues("Target");
            if (Targets.Length == 0)
            {
                throw new AutomationException("No targets specified (eg. -Target=\"UE4Editor Win64 Development\")");
            }

            // Parse the archive path
            string ArchivePath = ParseParamValue("Archive");

            if (ArchivePath != null && (!ArchivePath.StartsWith("//") || ArchivePath.Sum(x => (x == '/')? 1 : 0) < 4))
            {
                throw new AutomationException("Archive path is not a valid depot filename");
            }

            // Prepare the build agenda
            UE4Build.BuildAgenda Agenda = new UE4Build.BuildAgenda();
            foreach (string Target in Targets)
            {
                string[] Tokens = Target.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                UnrealTargetPlatform      Platform;
                UnrealTargetConfiguration Configuration;
                if (Tokens.Length < 3 || !Enum.TryParse(Tokens[1], true, out Platform) || !Enum.TryParse(Tokens[2], true, out Configuration))
                {
                    throw new AutomationException("Invalid target '{0}' - expected <TargetName> <Platform> <Configuration>");
                }

                Agenda.AddTarget(Tokens[0], Platform, Configuration, InAddArgs: String.Join(" ", Tokens.Skip(3)));
            }

            // Build everything
            UE4Build Builder = new UE4Build(this);

            Builder.Build(Agenda, InUpdateVersionFiles: ArchivePath != null);

            // Include the build products for UAT and UBT if required
            if (ParseParam("WithUAT"))
            {
                Builder.AddUATFilesToBuildProducts();
            }
            if (ParseParam("WithUBT"))
            {
                Builder.AddUBTFilesToBuildProducts();
            }

            // Archive the build products
            if (ArchivePath != null)
            {
                // Create an output folder
                string OutputFolder = Path.Combine(CommandUtils.CmdEnv.LocalRoot, "ArchiveForUGS");
                Directory.CreateDirectory(OutputFolder);

                // Create a temp folder for storing stripped PDB files
                string SymbolsFolder = Path.Combine(OutputFolder, "Symbols");
                Directory.CreateDirectory(SymbolsFolder);

                // Get the Windows toolchain
                Platform WindowsTargetPlatform = Platform.GetPlatform(UnrealTargetPlatform.Win64);

                // Figure out all the files for the archive
                string ZipFileName = Path.Combine(OutputFolder, "Archive.zip");
                using (Ionic.Zip.ZipFile Zip = new Ionic.Zip.ZipFile())
                {
                    Zip.UseZip64WhenSaving = Ionic.Zip.Zip64Option.Always;
                    foreach (string BuildProduct in Builder.BuildProductFiles)
                    {
                        if (!File.Exists(BuildProduct))
                        {
                            throw new AutomationException("Missing build product: {0}", BuildProduct);
                        }
                        if (BuildProduct.EndsWith(".pdb", StringComparison.InvariantCultureIgnoreCase))
                        {
                            string StrippedFileName = CommandUtils.MakeRerootedFilePath(BuildProduct, CommandUtils.CmdEnv.LocalRoot, SymbolsFolder);
                            Directory.CreateDirectory(Path.GetDirectoryName(StrippedFileName));
                            WindowsTargetPlatform.StripSymbols(new FileReference(BuildProduct), new FileReference(StrippedFileName));
                            Zip.AddFile(StrippedFileName, Path.GetDirectoryName(CommandUtils.StripBaseDirectory(StrippedFileName, SymbolsFolder)));
                        }
                        else
                        {
                            Zip.AddFile(BuildProduct, Path.GetDirectoryName(CommandUtils.StripBaseDirectory(BuildProduct, CommandUtils.CmdEnv.LocalRoot)));
                        }
                    }
                    // Create the zip file
                    Console.WriteLine("Writing {0}...", ZipFileName);
                    Zip.Save(ZipFileName);
                }

                // Submit it to Perforce if required
                if (CommandUtils.AllowSubmit)
                {
                    // Delete any existing clientspec for submitting
                    string ClientName = Environment.MachineName + "_BuildForUGS";

                    // Create a brand new one
                    P4ClientInfo Client = new P4ClientInfo();
                    Client.Owner    = CommandUtils.P4Env.User;
                    Client.Host     = Environment.MachineName;
                    Client.Stream   = ArchivePath.Substring(0, ArchivePath.IndexOf('/', ArchivePath.IndexOf('/', 2) + 1));
                    Client.RootPath = Path.Combine(OutputFolder, "Perforce");
                    Client.Name     = ClientName;
                    Client.Options  = P4ClientOption.NoAllWrite | P4ClientOption.NoClobber | P4ClientOption.NoCompress | P4ClientOption.Unlocked | P4ClientOption.NoModTime | P4ClientOption.RmDir;
                    Client.LineEnd  = P4LineEnd.Local;
                    P4.CreateClient(Client, AllowSpew: false);

                    // Create a new P4 connection for this workspace
                    P4Connection SubmitP4 = new P4Connection(Client.Owner, Client.Name, P4Env.ServerAndPort);
                    SubmitP4.Revert("-k //...");

                    // Figure out where the zip file has to go in Perforce
                    P4WhereRecord WhereZipFile = SubmitP4.Where(ArchivePath, false).FirstOrDefault(x => !x.bUnmap && x.Path != null);
                    if (WhereZipFile == null)
                    {
                        throw new AutomationException("Couldn't locate {0} in this workspace");
                    }

                    // Get the latest version of it
                    int NewCL = SubmitP4.CreateChange(Description: String.Format("[CL {0}] Updated binaries", P4Env.Changelist));
                    SubmitP4.Sync(String.Format("-k \"{0}\"", ArchivePath), AllowSpew: false);
                    CommandUtils.CopyFile(ZipFileName, WhereZipFile.Path);
                    SubmitP4.Add(NewCL, String.Format("\"{0}\"", ArchivePath));
                    SubmitP4.Edit(NewCL, String.Format("\"{0}\"", ArchivePath));

                    // Submit it
                    int SubmittedCL;
                    SubmitP4.Submit(NewCL, out SubmittedCL);
                    if (SubmittedCL <= 0)
                    {
                        throw new AutomationException("Submit failed.");
                    }
                    Console.WriteLine("Submitted in changelist {0}", SubmittedCL);
                }
            }
        }
		/// <summary>
		/// Detects the current changelist the workspace is synced to.
		/// </summary>
		/// <param name="ClientRootPath">Workspace path.</param>
		/// <returns>Changelist number as a string.</returns>
		private static string DetectCurrentCL(P4Connection Connection, string ClientRootPath)
		{
			CommandUtils.LogVerbose("uebp_CL not set, detecting 'have' CL...");

			// Retrieve the current changelist 
			var P4Result = Connection.P4("changes -m 1 " + CommandUtils.CombinePaths(PathSeparator.Depot, ClientRootPath, "/...#have"), AllowSpew: false);
			var CLTokens = P4Result.Output.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
			var CLString = CLTokens[1];
			var CL = Int32.Parse(CLString);
			if (CLString != CL.ToString())
			{
				throw new AutomationException("Failed to retrieve current changelist.");
			}
			return CLString;
		}
 internal P4Environment(P4Connection Connection, CommandEnvironment CmdEnv)
 {
     InitEnvironment(Connection, CmdEnv);
 }
    void ExecuteInner(string Dir, int PR)
    {
        string PRNum = PR.ToString();

        // Discard any old changes we may have committed
        RunGit("reset --hard");

        // show-ref is just a double check that the PR exists
        //var Refs = RunGit("show-ref");
        /*if (!Refs.Contains("refs/remotes/origin/pr/" + PRNum))
        {
            throw new AutomationException("This is not among the refs: refs/remotes/origin/pr/{0}", PRNum);
        }*/
        RunGit(String.Format("fetch origin refs/pull/{0}/head:pr/{1}", PRNum, PRNum));
        RunGit(String.Format("checkout pr/{0} --", PRNum));

        int CLBase;
        string DepotBase;
        ScanForBranchAndCL_BaseVersion(String.Format("log --author=TimSweeney --author=UnrealBot -100 pr/{0} --", PRNum), out DepotBase, out CLBase);

        int CLLive;
        string DepotLive;
        ScanForBranchAndCL_LiveVersion(String.Format("log -100 pr/{0} --", PRNum), out DepotLive, out CLLive);

        if (CLLive == 0 && CLBase == 0)
        {
            throw new AutomationException("Could not find a base change and branch using either method.");
        }

        int CL = 0;
        string Depot = "";

        if (CLBase > CLLive)
        {
            CL = CLBase;
            Depot = DepotBase;
        }
        else
        {
            CL = CLLive;
            Depot = DepotLive;
        }
        if (CL < 2000000 || String.IsNullOrWhiteSpace(Depot))
        {
            throw new AutomationException("Could not find a base change and branch using either method.");
        }

        P4ClientInfo NewClient = P4.GetClientInfo(P4Env.Client);

        foreach (var p in NewClient.View)
        {
            Log("{0} = {1}", p.Key, p.Value);
        }

        string TestClient = P4Env.User + "_" + Environment.MachineName + "_PullRequests_" + Depot.Replace("/", "_");
        NewClient.Owner = P4Env.User;
        NewClient.Host = Environment.MachineName;
        NewClient.RootPath = Dir;
        NewClient.Name = TestClient;
        NewClient.View = new List<KeyValuePair<string, string>>();
        NewClient.View.Add(new KeyValuePair<string, string>(Depot + "/...", "/..."));
        if (!P4.DoesClientExist(TestClient))
        {
            P4.CreateClient(NewClient);
        }

        var P4Sub = new P4Connection(P4Env.User, TestClient, P4Env.P4Port);

        P4Sub.Sync(String.Format("-f -k -q {0}/...@{1}", Depot, CL));

        var Change = P4Sub.CreateChange(null, String.Format("GitHub pull request #{0}", PRNum));
        P4Sub.ReconcileNoDeletes(Change, CommandUtils.MakePathSafeToUseWithCommandLine(CombinePaths(Dir, bDoingUT ? "UnrealTournament" : "Engine", "...")));
        P4Sub.Shelve(Change);
        P4Sub.Revert(Change, "-k //...");
    }
Example #23
0
		/// <summary>
		/// Initializes default source control connection.
		/// </summary>
		static internal void InitDefaultP4Connection()
		{
			CheckP4Enabled();

			PerforceConnection = new P4Connection(User: P4Env.User, Client: P4Env.Client, ServerAndPort: P4Env.P4Port);
		}
Example #24
0
        /// <summary>
        /// Constructor. Derives the Perforce environment settings.
        /// </summary>
        internal P4Environment(CommandEnvironment CmdEnv)
        {
            // Get the Perforce port setting
            ServerAndPort = CommandUtils.GetEnvVar(EnvVarNames.P4Port);
            if (String.IsNullOrEmpty(ServerAndPort))
            {
                ServerAndPort = DetectP4Port();
                CommandUtils.SetEnvVar(EnvVarNames.P4Port, ServerAndPort);
            }

            // Get the Perforce user setting
            User = CommandUtils.GetEnvVar(EnvVarNames.User);
            if (String.IsNullOrEmpty(User))
            {
                P4Connection DefaultConnection = new P4Connection(User: null, Client: null, ServerAndPort: ServerAndPort);
                User = DetectUserName(DefaultConnection);
                CommandUtils.SetEnvVar(EnvVarNames.User, User);
            }

            // Get the Perforce client setting
            Client = CommandUtils.GetEnvVar(EnvVarNames.Client);
            if (String.IsNullOrEmpty(Client))
            {
                P4Connection DefaultConnection = new P4Connection(User: User, Client: null, ServerAndPort: ServerAndPort);
                P4ClientInfo ThisClient        = DetectClient(DefaultConnection, User, Environment.MachineName.ToLower(), CmdEnv.UATExe);
                Log.TraceInformation("Using user {0} clientspec {1} {2}", User, ThisClient.Name, ThisClient.RootPath);

                string       BranchPath;
                string       ClientRootPath;
                P4Connection ClientConnection = new P4Connection(User: User, Client: ThisClient.Name, ServerAndPort: ServerAndPort);
                DetectRootPaths(ClientConnection, CmdEnv.LocalRoot, ThisClient, out BranchPath, out ClientRootPath);

                Client = ThisClient.Name;
                CommandUtils.SetEnvVar(EnvVarNames.Client, Client);

                Branch = BranchPath;
                CommandUtils.SetEnvVar(EnvVarNames.BuildRootP4, Branch);

                ClientRoot = ClientRootPath;
                CommandUtils.SetEnvVar(EnvVarNames.ClientRoot, ClientRootPath);
            }
            else
            {
                Branch     = CommandUtils.GetEnvVar(EnvVarNames.BuildRootP4);
                ClientRoot = CommandUtils.GetEnvVar(EnvVarNames.ClientRoot);
                if (String.IsNullOrEmpty(Branch) || String.IsNullOrEmpty(ClientRoot))
                {
                    throw new AutomationException("{0} and {1} must also be set with {2}", EnvVarNames.ClientRoot, EnvVarNames.BuildRootP4, EnvVarNames.Client);
                }
            }

            // We expect the build root to not end with a path separator
            if (Branch.EndsWith("/"))
            {
                Branch = Branch.TrimEnd('/');
                CommandUtils.SetEnvVar(EnvVarNames.BuildRootP4, Branch);
            }

            // Set the current changelist
            string ChangelistString = CommandUtils.GetEnvVar(EnvVarNames.Changelist, null);

            if (String.IsNullOrEmpty(ChangelistString) && CommandUtils.P4CLRequired)
            {
                P4Connection Connection = new P4Connection(User, Client, ServerAndPort);
                ChangelistString = DetectCurrentCL(Connection, ClientRoot);
                CommandUtils.SetEnvVar(EnvVarNames.Changelist, ChangelistString);
            }
            if (!String.IsNullOrEmpty(ChangelistString))
            {
                Changelist = int.Parse(ChangelistString);
            }

            // Set the current code changelist
            string CodeChangelistString = CommandUtils.GetEnvVar(EnvVarNames.CodeChangelist);

            if (String.IsNullOrEmpty(CodeChangelistString) && CommandUtils.P4CLRequired)
            {
                P4Connection Connection = new P4Connection(User, Client, ServerAndPort);
                CodeChangelistString = DetectCurrentCodeCL(Connection, ClientRoot);
                CommandUtils.SetEnvVar(EnvVarNames.CodeChangelist, CodeChangelistString);
            }
            if (!String.IsNullOrEmpty(CodeChangelistString))
            {
                CodeChangelist = int.Parse(CodeChangelistString);
            }

            // Set the standard environment variables based on the values we've found
            CommandUtils.SetEnvVar("P4PORT", ServerAndPort);
            CommandUtils.SetEnvVar("P4USER", User);
            CommandUtils.SetEnvVar("P4CLIENT", Client);

            // Write a summary of the settings to the output window
            if (!CommandUtils.CmdEnv.IsChildInstance)
            {
                Log.TraceInformation("Detected Perforce Settings:");
                Log.TraceInformation("  Server: {0}", ServerAndPort);
                Log.TraceInformation("  User: {0}", User);
                Log.TraceInformation("  Client: {0}", Client);
                Log.TraceInformation("  Branch: {0}", Branch);
                if (ChangelistInternal != -1)
                {
                    Log.TraceInformation("  Last Change: {0}", Changelist);
                }
                if (CodeChangelistInternal != -1)
                {
                    Log.TraceInformation("  Last Code Change: {0}", CodeChangelist);
                }
            }

            // Write all the environment variables to the log
            Log.TraceLog("Perforce Environment Variables:");
            Log.TraceLog("  {0}={1}", EnvVarNames.P4Port, InternalUtils.GetEnvironmentVariable(EnvVarNames.P4Port, "", true));
            Log.TraceLog("  {0}={1}", EnvVarNames.User, InternalUtils.GetEnvironmentVariable(EnvVarNames.User, "", true));
            Log.TraceLog("  {0}={1}", EnvVarNames.Client, InternalUtils.GetEnvironmentVariable(EnvVarNames.Client, "", true));
            Log.TraceLog("  {0}={1}", EnvVarNames.BuildRootP4, InternalUtils.GetEnvironmentVariable(EnvVarNames.BuildRootP4, "", true));
            Log.TraceLog("  {0}={1}", EnvVarNames.BuildRootEscaped, InternalUtils.GetEnvironmentVariable(EnvVarNames.BuildRootEscaped, "", true));
            Log.TraceLog("  {0}={1}", EnvVarNames.ClientRoot, InternalUtils.GetEnvironmentVariable(EnvVarNames.ClientRoot, "", true));
            Log.TraceLog("  {0}={1}", EnvVarNames.Changelist, InternalUtils.GetEnvironmentVariable(EnvVarNames.Changelist, "", true));
            Log.TraceLog("  {0}={1}", EnvVarNames.CodeChangelist, InternalUtils.GetEnvironmentVariable(EnvVarNames.CodeChangelist, "", true));
            Log.TraceLog("  {0}={1}", "P4PORT", InternalUtils.GetEnvironmentVariable("P4PORT", "", true));
            Log.TraceLog("  {0}={1}", "P4USER", InternalUtils.GetEnvironmentVariable("P4USER", "", true));
            Log.TraceLog("  {0}={1}", "P4CLIENT", InternalUtils.GetEnvironmentVariable("P4CLIENT", "", true));
        }
Example #25
0
        public override void ExecuteBuild()
        {
            string Paths = ParseParamValue("Paths", null);

            if (string.IsNullOrWhiteSpace(Paths))
            {
                throw new AutomationException("-Paths must be defined! Usage: -Paths=Path1/...;Path2.txt");
            }

            string Description = ParseParamValue("Description", null);

            if (string.IsNullOrWhiteSpace(Description))
            {
                throw new AutomationException("-Description must be defined!");
            }


            string FileType = ParseParamValue("FileType", null);

            if (!CommandUtils.AllowSubmit)
            {
                LogWarning("Submitting to Perforce is disabled by default. Run with the -submit argument to allow.");
            }
            else
            {
                // Get the connection that we're going to submit with
                P4Connection SubmitP4 = CommandUtils.P4;
                // Reconcile the path against the depot
                int NewCL = SubmitP4.CreateChange(Description: Description.Replace("\\n", "\n"));
                try
                {
                    foreach (string Path in Paths.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
                    {
                        SubmitP4.Sync(String.Format("-k \"{0}\"", Path), AllowSpew: false);
                        SubmitP4.Reconcile(NewCL, Path);
                        if (FileType != null)
                        {
                            SubmitP4.P4(String.Format("reopen -t \"{0}\" \"{1}\"", FileType, Path), AllowSpew: false);
                        }
                    }

                    if (SubmitP4.TryDeleteEmptyChange(NewCL))
                    {
                        CommandUtils.LogInformation("No files to submit; ignored.");
                        return;
                    }

                    // Submit it
                    int SubmittedCL;
                    SubmitP4.Submit(NewCL, out SubmittedCL, true);
                    if (SubmittedCL <= 0)
                    {
                        throw new AutomationException("Submit failed.");
                    }
                    CommandUtils.LogInformation("Submitted in changelist {0}", SubmittedCL);
                }
                catch (Exception Ex)
                {
                    LogError("Failed to reconcile and submit files to P4, reason: {0}, reverting and deleting change.", Ex.ToString());
                    SubmitP4.DeleteChange(NewCL);
                }
            }
        }
		/// <summary>
		/// Detects a workspace given the current user name, host name and depot path.
		/// </summary>
		/// <param name="UserName">User name</param>
		/// <param name="HostName">Host</param>
		/// <param name="UATLocation">Path to UAT exe, this will be checked agains the root path.</param>
		/// <returns>Client to use.</returns>
		private static P4ClientInfo DetectClient(P4Connection Connection, string UserName, string HostName, string UATLocation)
		{
			CommandUtils.LogVerbose("uebp_CLIENT not set, detecting current client...");

			var MatchingClients = new List<P4ClientInfo>();
			P4ClientInfo[] P4Clients = Connection.GetClientsForUser(UserName, UATLocation);
			foreach (var Client in P4Clients)
			{
				if (!String.IsNullOrEmpty(Client.Host) && String.Compare(Client.Host, HostName, true) != 0)
				{
					Log.TraceInformation("Rejecting client because of different Host {0} \"{1}\" != \"{2}\"", Client.Name, Client.Host, HostName);
					continue;
				}
				
				MatchingClients.Add(Client);
			}

			P4ClientInfo ClientToUse = null;
			if (MatchingClients.Count == 0)
			{
				throw new AutomationException("No matching clientspecs found!");
			}
			else if (MatchingClients.Count == 1)
			{
				ClientToUse = MatchingClients[0];
			}
			else
			{
				// We may have empty host clients here, so pick the first non-empty one if possible
				foreach (var Client in MatchingClients)
				{
					if (!String.IsNullOrEmpty(Client.Host) && String.Compare(Client.Host, HostName, true) == 0)
					{
						ClientToUse = Client;
						break;
					}
				}
				if (ClientToUse == null)
				{
					Log.TraceWarning("{0} clients found that match the current host and root path. The most recently accessed client will be used.", MatchingClients.Count);
					ClientToUse = GetMostRecentClient(MatchingClients);
				}
			}

			return ClientToUse;
		}
		/// <summary>
		/// Detects the current code changelist the workspace is synced to.
		/// </summary>
		/// <param name="ClientRootPath">Workspace path.</param>
		/// <returns>Changelist number as a string.</returns>
		private static string DetectCurrentCodeCL(P4Connection Connection, string ClientRootPath)
		{
			CommandUtils.LogVerbose("uebp_CodeCL not set, detecting last code CL...");

			// Retrieve the current changelist 
			string P4Cmd = String.Format("changes -m 1 \"{0}/....cpp#have\" \"{0}/....h#have\" \"{0}/....inl#have\" \"{0}/....cs#have\" \"{0}/....usf#have\"", CommandUtils.CombinePaths(PathSeparator.Depot, ClientRootPath));
			IProcessResult P4Result = Connection.P4(P4Cmd, AllowSpew: false);

			// Loop through all the lines of the output. Even though we requested one result, we'll get one for each search pattern.
			int CL = 0;
			foreach(string Line in P4Result.Output.Split('\n'))
			{
				string[] Tokens = Line.Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
				if(Tokens.Length >= 2)
				{
					int LineCL = Int32.Parse(Tokens[1]);
					CL = Math.Max(CL, LineCL);
				}
			}
			return CL.ToString();
		}
		/// <summary>
		/// Initializes the environment. Tries to autodetect all source control settings.
		/// </summary>
		/// <param name="CompilationEnv">Compilation environment</param>
		protected override void InitEnvironment(P4Connection Connection, CommandEnvironment CmdEnv)
		{
			var HostName = Environment.MachineName.ToLower();
			var P4PortEnv = DetectP4Port();

			var UserName = CommandUtils.GetEnvVar(EnvVarNames.User);
			if (String.IsNullOrEmpty(UserName))
			{
				UserName = DetectUserName(Connection);
			}

			var CommandLineClient = CommandUtils.GetEnvVar(EnvVarNames.Client);
			P4ClientInfo ThisClient = null;
			if (String.IsNullOrEmpty(CommandLineClient) == false)
			{
				ThisClient = Connection.GetClientInfo(CommandLineClient);
				if (ThisClient == null)
				{
					throw new AutomationException("Unable to find client {0}", CommandLineClient);
				}
				if (String.Compare(ThisClient.Owner, UserName, true) != 0)
				{
					throw new AutomationException("Client specified with {0}={1} has a different owner then the detected user name (has: {2}, expected: {3})",
						EnvVarNames.Client, CommandLineClient, ThisClient.Owner, UserName);
				}
			}
			else
			{
				ThisClient = DetectClient(Connection, UserName, HostName, CmdEnv.UATExe);
			}

			Log.TraceInformation("Using user {0} clientspec {1} {2}", UserName, ThisClient.Name, ThisClient.RootPath);
			Environment.SetEnvironmentVariable("P4CLIENT", ThisClient.Name);

			string BuildRootPath;
			string ClientRootPath;
			DetectRootPaths(Connection, CmdEnv.LocalRoot, ThisClient, out BuildRootPath, out ClientRootPath);

			CommandUtils.ConditionallySetEnvVar(EnvVarNames.P4Port, P4PortEnv);
			CommandUtils.ConditionallySetEnvVar(EnvVarNames.User, UserName);
			CommandUtils.ConditionallySetEnvVar(EnvVarNames.Client, ThisClient.Name);
			CommandUtils.ConditionallySetEnvVar(EnvVarNames.BuildRootP4, BuildRootPath);
			CommandUtils.ConditionallySetEnvVar(EnvVarNames.ClientRoot, ClientRootPath);

			var CLString = CommandUtils.GetEnvVar(EnvVarNames.Changelist, null);
			if (String.IsNullOrEmpty(CLString) && CommandUtils.P4CLRequired)
			{
                CLString = DetectCurrentCL(Connection, ClientRootPath);
			}
			if (!String.IsNullOrEmpty(CLString))
			{
				CommandUtils.ConditionallySetEnvVar(EnvVarNames.Changelist, CLString);
			}

			var CodeCLString = CommandUtils.GetEnvVar(EnvVarNames.CodeChangelist, null);
			if (String.IsNullOrEmpty(CodeCLString) && CommandUtils.P4CLRequired)
			{
                CodeCLString = DetectCurrentCodeCL(Connection, ClientRootPath);
			}
			if (!String.IsNullOrEmpty(CodeCLString))
			{
				CommandUtils.ConditionallySetEnvVar(EnvVarNames.CodeChangelist, CodeCLString);
			}

			CommandUtils.ConditionallySetEnvVar(EnvVarNames.LabelToSync, "");
			CommandUtils.ConditionallySetEnvVar("P4USER", UserName);
			CommandUtils.ConditionallySetEnvVar("P4CLIENT", ThisClient.Name);

			var P4Password = Environment.GetEnvironmentVariable(EnvVarNames.P4Password);
			if (!String.IsNullOrEmpty(P4Password))
			{
				CommandUtils.ConditionallySetEnvVar("P4PASSWD", P4Password);
			}

			SetBuildRootEscaped();

			base.InitEnvironment(Connection, CmdEnv);
		}
Example #29
0
 internal P4Environment(P4Connection Connection, CommandEnvironment CmdEnv)
 {
     InitEnvironment(Connection, CmdEnv);
 }
		internal LocalP4Environment(P4Connection Connection, CommandEnvironment CmdEnv)
			: base(Connection, CmdEnv)
		{
		}