Exemple #1
0
        /// <summary>
        /// Get server information.
        /// </summary>
        /// <returns>Information about a connection's client-side application context.</returns>
        /// <remarks>
        /// <br/><b>p4 help info</b>
        /// <br/>
        /// <br/>     info -- Display client/server information
        /// <br/>
        /// <br/>     p4 info [-s]
        /// <br/>
        /// <br/>   Info lists information about the current client (user name,
        /// <br/>   client name, applicable client root, client current directory,
        /// <br/>   and the client IP address) and some server information (server
        /// <br/>   IP address, server root, date, uptime, version and license data).
        /// <br/>
        /// <br/>   The -s option produces 'short' output that omits any information
        /// <br/>   that requires a database lookup such as the client root).
        /// <br/>
        /// <br/>
        /// </remarks>
        /// <example>
        ///     To get the server root:
        ///
        /// <code>
        ///
        ///         ServerMetaData s = rep.GetServerMetaData(null);
        ///         string root = s.Root;
        ///
        /// </code>
        ///     To get the server case handling:
        ///
        /// <code>
        ///         ServerMetaData s = rep.GetServerMetaData(null);
        ///         bool caseSensitive = s.CaseSensitive;
        /// </code>
        ///
        /// </example>
        public ServerMetaData GetServerMetaData(Options options)
        {
            P4Command cmd = new P4Command(this, "info", true);

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                if ((results.TaggedOutput == null) || (results.TaggedOutput.Count <= 0))
                {
                    return(null);
                }
                ServerMetaData value = new ServerMetaData();
                foreach (TaggedObject obj in results.TaggedOutput)
                {
                    value.FromGetServerMetaDataCmdTaggedOutput(obj);
                }
                this.Server.SetMetadata(value);

                return(value);
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }
Exemple #2
0
        /// <summary>
        /// Get the integration status for a stream in the repository
        /// </summary>
        /// <param name="stream">The stream to get integration status on</param>
        /// <param name="options">options for the istat command</param>
        /// <returns>The integration status of the stream</returns>
        /// <remarks>
        /// <br/><b>p4 help istat</b>
        /// <br/>
        /// <br/>     istat -- Show/cache a stream's integration status
        /// <br/>
        /// <br/>     p4 istat [ -a -c -r -s ] stream
        /// <br/>
        /// <br/>   'p4 istat' shows a stream's cached integration status with respect
        /// <br/>   to its parent. If the cache is stale, either because newer changes
        /// <br/>   have been submitted or the stream's branch view has changed, 'p4
        /// <br/>   istat' checks for pending integrations and updates the cache before
        /// <br/>   showing status.
        /// <br/>
        /// <br/>   Pending integrations are shown only if they are expected by the
        /// <br/>   stream; that is, only if they are warranted by the stream's type
        /// <br/>   and its fromParent/toParent flow options. (See 'p4 help stream'.)
        /// <br/>
        /// <br/>   The -r flag shows the status of integration to the stream from its
        /// <br/>   parent. By default, status of integration in the other direction is
        /// <br/>   shown, from the stream to its parent.
        /// <br/>
        /// <br/>   The -a flag shows status of integration in both directions.
        /// <br/>
        /// <br/>   The -c flag forces 'p4 istat' to assume the cache is stale; it
        /// <br/>   causes a search for pending integrations.  Use of this flag can
        /// <br/>   impact server performance.
        /// <br/>
        /// <br/>   The -s flag shows cached state without refreshing stale data.
        /// <br/>
        /// <br/>
        /// </remarks>
        /// <example>
        ///
        ///     Get the direction of integration for stream "//Rocket/GUI" with respect
        ///     to its parent:
        ///     <code>
        ///
        ///         Stream s = rep.GetStream("//Rocket/GUI",null,null);
        ///         StreamMetaData smd = rep.GetStreamMetaData(s, null);
        ///         StreamMetaData.IntegAction action = smd.IntegToParentHow;
        ///
        ///     </code>
        ///
        ///     Get the direction of integration for stream "//Rocket/GUI" from its parent:
        ///     <code>
        ///
        ///         Stream s = rep.GetStream("//Rocket/GUI",null,null);
        ///         StreamMetaData smd = rep.GetStreamMetaData(s,new Options(GetStreamMetaDataCmdFlags.Reverse));
        ///         StreamMetaData.IntegAction action = smd.IntegFromParentHow;
        ///
        ///     </code>
        /// </example>
        public StreamMetaData GetStreamMetaData(Stream stream, Options options)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            P4Command cmd = new P4Command(this, "istat", true, stream.Id);

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                if ((results.TaggedOutput == null) || (results.TaggedOutput.Count <= 0))
                {
                    return(null);
                }
                StreamMetaData value = new StreamMetaData();
                value.FromIstatCmdTaggedData((results.TaggedOutput[0]));

                return(value);
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }
        /// <summary>
        /// Create a new label in the repository.
        /// </summary>
        /// <param name="label">Label specification for the new label</param>
        /// <param name="options">The '-i' flag is required when creating a new label </param>
        /// <returns>The Label object if new label was created, null if creation failed</returns>
        /// <remarks> The '-i' flag is added if not specified by the caller
        /// <br/>
        /// <br/><b>p4 help label</b>
        /// <br/>
        /// <br/>     label -- Create or edit a label specification
        /// <br/>
        /// <br/>     p4 label [-f -g -t template] name
        /// <br/>     p4 label -d [-f -g] name
        /// <br/>     p4 label -o [-t template] name
        /// <br/>     p4 label -i [-f -g]
        /// <br/>
        /// <br/>   Create  or edit a label. The name parameter is required. The
        /// <br/>   specification form is put into a temporary file and the editor
        /// <br/>   (configured by the environment variable $P4EDITOR) is invoked.
        /// <br/>
        /// <br/>   The label specification form contains the following fields:
        /// <br/>
        /// <br/>   Label:       The label name (read only.)
        /// <br/>
        /// <br/>   Owner:       The user who created this label.  Can be changed.
        /// <br/>
        /// <br/>   Update:      The date that this specification was last modified.
        /// <br/>
        /// <br/>   Access:      The date of the last 'labelsync' or use of '@label'
        /// <br/>            referencing this label.
        /// <br/>
        /// <br/>   Description: A short description of the label (optional).
        /// <br/>
        /// <br/>   Options:     Flags to change the label behavior.
        /// <br/>
        /// <br/>                locked	  Prevents users other than the label owner
        /// <br/>                unlocked     from changing the specification. Prevents
        /// <br/>                 the label from being deleted. Prevents the
        /// <br/>                 owner from running 'p4 labelsync'. For a
        /// <br/>                 loaded label, prevents 'p4 unload'.
        /// <br/>
        /// <br/>                autoreload	  For a static label, indicates where label
        /// <br/>                noautoreload revisions are stored. Specify 'noautoreload'
        /// <br/>                             to indicate that the revisions should be
        /// <br/>                             stored in the db.label table. Specify
        /// <br/>                             'autoreload' to indicate that the revisions
        /// <br/>                             should be stored in the unload depot.
        /// <br/>
        /// <br/>   Revision:    An optional revision specification for an automatic
        /// <br/>            label.  Enclose in double quotes if it contains the
        /// <br/>            # (form comment) character.  An automatic label can
        /// <br/>            be treated as a pure alias of a single revision
        /// <br/>            specification (excluding @label) provided that the
        /// <br/>            View mapping is empty.
        /// <br/>
        /// <br/>   View:        A mapping that selects files from the depot. The
        /// <br/>            default view selects all depot files. Only the left
        /// <br/>            side of the mapping is used for labels.  Leave this
        /// <br/>            field blank when creating an automatic label as
        /// <br/>            a pure alias. See 'p4 help views'.
        /// <br/>
        /// <br/>   ServerID:    If set, restricts usage to the named server.
        /// <br/>            If unset, usage is allowed on any server.
        /// <br/>
        /// <br/>   A label is a named collection of revisions.  A label is either
        /// <br/>   automatic or static.  An automatic label refers to the revisions
        /// <br/>   given in the View: and Revision: fields.  A static label refers to
        /// <br/>   the revisions that are associated with the label using the 'p4 tag'
        /// <br/>   or 'p4 labelsync' commands.  A static label cannot have a Revison:
        /// <br/>   field. See 'p4 help revisions' for information on using labels as
        /// <br/>   revision specifiers.
        /// <br/>
        /// <br/>   Only the label owner can run 'p4 labelsync', and only if the label
        /// <br/>   is unlocked. A label without an owner can be labelsync'd by any user.
        /// <br/>
        /// <br/>   Flag -d deletes the specified label. You cannot delete a locked label.
        /// <br/>   The -f flag forces the delete.
        /// <br/>
        /// <br/>   The -o flag writes the label specification to standard output.  The
        /// <br/>   user's editor is not invoked.
        /// <br/>
        /// <br/>   The -i flag reads a label specification from standard input.  The
        /// <br/>   user's editor is not invoked.
        /// <br/>
        /// <br/>   The -t flag copies the view and options from the template label to
        /// <br/>   the new label.
        /// <br/>
        /// <br/>   The -f flag forces the deletion of a label. By default, locked labels
        /// <br/>   can only be deleted by their owner.  The -f flag also permits the
        /// <br/>   Last Modified date to be set.  The -f flag requires 'admin' access,
        /// <br/>   which is granted by 'p4 protect'.
        /// <br/>
        /// <br/>   The -g flag should be used on an Edge Server to update a global
        /// <br/>   label. Without -g, the label definition is visible only to users
        /// <br/>   of this Edge Server. Configuring rpl.labels.global=1 reverses this
        /// <br/>   default and causes this flag to have the opposite meaning.
        /// <br/>
        /// <br/>
        /// </remarks>
        /// <example>
        ///     To create a new label:
        ///
        /// <code>
        ///
        ///         Label l = new Label();
        ///         l.Id = "newLabel";
        ///         l.Owner = "admin";
        ///         l.Description = "created by admin";
        ///         l.Options = "unlocked";
        ///         l.ViewMap = new ViewMap();
        ///         string v0 = "//depot/main/...";
        ///         string v1 = "//depot/rel1/...";
        ///         string v2 = "//depot/rel2/...";
        ///         string v3 = "//depot/dev/...";
        ///         l.ViewMap.Add(v0);
        ///         l.ViewMap.Add(v1);
        ///         l.ViewMap.Add(v2);
        ///         l.ViewMap.Add(v3);
        ///         Label newLabel = rep.CreateLabel(l, null);
        ///
        /// </code>
        ///
        ///     To create a label using another label as a template:
        /// <code>
        ///
        ///         Label newLabel2 = rep.CreateLabel(newLabel,
        ///             new LabelCmdOptions(LabelCmdFlags.None, newLabel.Id));
        /// </code>
        /// </example>
        public Label CreateLabel(Label label, Options options)
        {
            if (label == null)
            {
                throw new ArgumentNullException("label");
            }
            P4Command cmd = new P4Command(this, "label", true);

            cmd.DataSet = label.ToString();

            if (options == null)
            {
                options = new Options((LabelCmdFlags.Input), null);
            }
            if (options.ContainsKey("-i") == false)
            {
                options["-i"] = null;
            }

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                return(label);
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }
Exemple #4
0
        /// <summary>
        /// Create a new branch in the repository.
        /// </summary>
        /// <param name="branch">Branch specification for the new branch</param>
        /// <param name="options">The '-i' flag is required when creating a new branch </param>
        /// <returns>The Branch object if new branch was created, null if creation failed</returns>
        /// <remarks>
        /// <br/>
        /// <br/><b>p4 help branch</b>
        /// <br/>
        /// <br/>     branch -- Create, modify, or delete a branch view specification
        /// <br/>
        /// <br/>     p4 branch [-f] name
        /// <br/>     p4 branch -d [-f] name
        /// <br/>     p4 branch [ -S stream ] [ -P parent ] -o name
        /// <br/>     p4 branch -i [-f]
        /// <br/>
        /// <br/>   A branch specification ('spec') is a named, user-defined mapping of
        /// <br/>   depot files to depot files. It can be used with most of the commands
        /// <br/>   that operate on two sets of files ('copy', 'merge', 'integrate',
        /// <br/>   'diff2', etc.)
        /// <br/>
        /// <br/>   Creating a branch spec does not branch files.  To branch files, use
        /// <br/>   'p4 copy', with or without a branch spec.
        /// <br/>
        /// <br/>   The 'branch' command puts the branch spec into a temporary file and
        /// <br/>   invokes the editor configured by the environment variable $P4EDITOR.
        /// <br/>   Saving the file creates or modifies the branch spec.
        /// <br/>
        /// <br/>   The branch spec contains the following fields:
        /// <br/>
        /// <br/>   Branch:      The branch spec name (read only).
        /// <br/>
        /// <br/>   Owner:       The user who created this branch spec. Can be changed.
        /// <br/>
        /// <br/>   Update:      The date this branch spec was last modified.
        /// <br/>
        /// <br/>   Access:      The date of the last command used with this spec.
        /// <br/>
        /// <br/>   Description: A description of the branch spec (optional).
        /// <br/>
        /// <br/>   Options:     Flags to change the branch spec behavior. The defaults
        /// <br/>            are marked with *.
        /// <br/>
        /// <br/>       locked      Permits only the owner to change the spec.
        /// <br/>       unlocked *	Prevents the branch spec from being deleted.
        /// <br/>
        /// <br/>   View:        Lines mapping of one view of depot files to another.
        /// <br/>            Both the left and right-hand sides of the mappings refer
        /// <br/>            to the depot namespace.  See 'p4 help views' for more on
        /// <br/>            view syntax.
        /// <br/>
        /// <br/>   New branch specs are created with a default view that maps all depot
        /// <br/>   files to themselves.  This view must be changed before the branch
        /// <br/>   spec can be saved.
        /// <br/>
        /// <br/>   The -d flag deletes the named branch spec.
        /// <br/>
        /// <br/>   The -o flag writes the branch spec to standard output. The user's
        /// <br/>   editor is not invoked.
        /// <br/>
        /// <br/>   The -i flag causes a branch spec to be read from the standard input.
        /// <br/>   The user's editor is not invoked.
        /// <br/>
        /// <br/>   The -f flag enables a user with 'admin' privilege to delete the spec
        /// <br/>   or set the 'last modified' date.  By default, specs can be deleted
        /// <br/>   only by their owner.
        /// <br/>
        /// <br/>   A branch spec can also be used to expose the internally generated
        /// <br/>   mapping of a stream to its parent. (See 'p4 help stream' and 'p4
        /// <br/>   help streamintro'.)
        /// <br/>
        /// <br/>   The -S stream flag will expose the internally generated mapping.
        /// <br/>   The -P flag may be used with -S to treat the stream as if it were a
        /// <br/>   child of a different parent. The -o flag is required with -S.
        /// <br/>
        /// <br/>
        /// </remarks>
        /// <example>
        ///		To create a branch spec [-i]:
        ///		<code>
        ///
        ///			BranchSpec newBranchSpec = new BranchSpec();
        ///			newBranchSpec.Id = "newBranchSpec";
        ///			newBranchSpec.Owner = "admin";
        ///			newBranchSpec.Description = " created by perforce";
        ///			newBranchSpec.ViewMap = new ViewMap();
        ///			string v0 = "//depot/main/... //depot/rel1/...";
        ///			string v1 = "//depot/main/... //depot/rel2/...";
        ///			string v2 = "//depot/dev/... //depot/main/...";
        ///			newBranchSpec.ViewMap.Add(v0);
        ///			newBranchSpec.ViewMap.Add(v1);
        ///			newBranchSpec.ViewMap.Add(v2);
        ///			Options opts = new Options(BranchSpecCmdFlags.Input);
        ///			_repository.CreateBranchSpec(newBranchSpec, opts);
        ///
        ///		</code>
        /// </example>
        /// <seealso cref="BranchSpecCmdFlags"/>
        public BranchSpec CreateBranchSpec(BranchSpec branch, Options options)
        {
            if (branch == null)
            {
                throw new ArgumentNullException("branch");
            }
            P4Command cmd = new P4Command(this, "branch", true);

            cmd.DataSet = branch.ToString();

            if (options == null)
            {
                options = new Options((BranchSpecCmdFlags.Input), null, null);
            }
            if (options.ContainsKey("-i") == false)
            {
                options["-i"] = null;
            }

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                return(branch);
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }
Exemple #5
0
        /// <summary>
        /// Go to the server to get details about this changelist
        /// </summary>
        /// <param name="connection">connection to server</param>
        public void initialize(Connection connection)
        {
            if (connection == null)
            {
                P4Exception.Throw(ErrorSeverity.E_FAILED, "Changelist cannot be initialized");
                return;
            }
            Connection = connection;

            if (!connection.connectionEstablished())
            {
                // not connected to the server yet
                return;
            }
            if (Id < 0)
            {
                // new change list
                _initialized = true;
                return;
            }
            P4Command cmd = new P4Command(connection, "change", true, "-o", Id.ToString());

            P4CommandResult results = cmd.Run();

            if ((results.Success) && (results.TaggedOutput != null) && (results.TaggedOutput.Count > 0))
            {
                FromChangeCmdTaggedOutput(results.TaggedOutput[0], string.Empty, false);
                _initialized = true;
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
        }
        /// <summary>
        /// Delete a label from the repository
        /// </summary>
        /// <param name="label">The label to be deleted</param>
        /// <param name="options">The 'f' and '-d' flags are valid when deleting an
        /// existing label</param>
        /// <example>
        ///
        ///  To delete the label admin_label:
        ///
        /// <code>
        ///
        ///     Label deleteTarget = new Label();
        ///     deleteTarget.Id = "admin_label";
        ///     rep.DeleteLabel(deleteTarget, null);
        ///
        /// </code>
        ///
        /// </example>
        public void DeleteLabel(Label label, Options options)
        {
            if (label == null)
            {
                throw new ArgumentNullException("label");
            }
            P4Command cmd = new P4Command(this, "label", true, label.Id);

            if (options == null)
            {
                options = new Options(LabelCmdFlags.Delete, null);
            }

            if (options.ContainsKey("-d") == false)
            {
                options["-d"] = null;
            }

            P4CommandResult results = cmd.Run(options);

            if (results.Success == false)
            {
                P4Exception.Throw(results.ErrorList);
            }
        }
        /// <summary>
        /// Get the record for an existing group from the repository.
        /// </summary>
        /// <param name="group">Group name</param>
        /// <param name="options">The Owner Access flag (-a) needs to be used if a user
        ///  without 'super' access is an 'owner' of that group.</param>
        /// <returns>The Group object if new group was found, null if creation failed</returns>
        /// <example>
        ///		To get the group 'everyone' when connected as a user with super access:
        ///		<code>
        ///
        ///			string targetGroup = "everyone";
        ///			Group group = _repository.GetGroup(targetGroup, null);
        ///
        ///		</code>
        ///		To get the group 'Mygroup' when connected as a without super access
        ///		who is the owner of that group:
        ///		<code>
        ///
        ///           string targetGroup = "everyone";
        ///           GroupCmdOptions opts = new GroupCmdOptions(GroupCmdFlags.OwnerAccess);
        ///           Group group = _repository.GetGroup(targetGroup, opts);
        ///
        ///		</code>
        /// </example>
        /// <seealso cref="GroupCmdFlags"/>
        public Group GetGroup(string group, Options options)
        {
            if (group == null)
            {
                throw new ArgumentNullException("group");
            }
            P4Command cmd = new P4Command(this, "group", true, group);

            if (options == null)
            {
                options = new Options();
            }
            options["-o"] = null;

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                if ((results.TaggedOutput == null) || (results.TaggedOutput.Count <= 0))
                {
                    return(null);
                }
                Group value = new Group();
                value.FromGroupCmdTaggedOutput((results.TaggedOutput[0]));

                return(value);
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }
        /// <summary>
        /// Create a new depot in the repository.
        /// </summary>
        /// <param name="depot">Depot specification for the new depot</param>
        /// <param name="options">The '-i' flag is required when creating a new depot</param>
        /// <returns>The Depot object if new depot was created, null if creation failed</returns>
        /// <remarks> The '-i' flag is added if not specified by the caller
        /// <br/>
        /// <br/><b>p4 help depot</b>
        /// <br/>
        /// <br/>     depot -- Create or edit a depot specification
        /// <br/>
        /// <br/>     p4 depot name
        /// <br/>     p4 depot -d [-f] name
        /// <br/>     p4 depot -o name
        /// <br/>     p4 depot -i
        /// <br/>
        /// <br/>   Create a new depot specification or edit an existing depot
        /// <br/>   specification. The specification form is put into a temporary file
        /// <br/>   and the editor (configured by the environment variable $P4EDITOR)
        /// <br/>   is invoked.
        /// <br/>
        /// <br/>   The depot specification contains the following fields:
        /// <br/>
        /// <br/>   Depot:       The name of the depot.  This name cannot be the same as
        /// <br/>            any branch, client, or label name.
        /// <br/>
        /// <br/>   Owner:       The user who created this depot.
        /// <br/>
        /// <br/>   Date:        The date that this specification was last modified.
        /// <br/>
        /// <br/>   Description: A short description of the depot (optional).
        /// <br/>
        /// <br/>   Type:        One of the types: 'local', 'stream', 'remote', 'spec',
        /// <br/>            'archive', or 'unload'.
        /// <br/>
        /// <br/>            A 'local' depot (the default) is managed directly by
        /// <br/>            the server and its files reside in the server's root
        /// <br/>            directory.
        /// <br/>
        /// <br/>            A 'stream' depot is a local depot dedicated to the
        /// <br/>            storage of files in a stream.
        /// <br/>
        /// <br/>            A 'remote' depot refers to files in another Perforce
        /// <br/>            server.
        /// <br/>
        /// <br/>            A 'spec' depot automatically archives all edited forms
        /// <br/>            (branch, change, client, depot, group, job, jobspec,
        /// <br/>            protect, triggers, typemap, and user) in special,
        /// <br/>            read-only files.  The files are named:
        /// <br/>            //depotname/formtype/name[suffix].  Updates to jobs made
        /// <br/>            by the 'p4 change', 'p4 fix', and 'p4 submit' commands
        /// <br/>            are also saved, but other automatic updates such as
        /// <br/>            as access times or opened files (for changes) are not.
        /// <br/>            A server can contain only one 'spec' depot.
        /// <br/>
        /// <br/>            A 'archive' depot defines a storage location to which
        /// <br/>            obsolete revisions may be relocated.
        /// <br/>
        /// <br/>            An 'unload' depot defines a storage location to which
        /// <br/>            database records may be unloaded and from which they
        /// <br/>            may be reloaded.
        /// <br/>
        /// <br/>   Address:     For remote depots, the $P4PORT (connection address)
        /// <br/>            of the remote server.
        /// <br/>
        /// <br/>   Suffix:      For spec depots, the optional suffix to be used
        /// <br/>            for generated paths. The default is '.p4s'.
        /// <br/>
        /// <br/>   Map:         Path translation information, in the form of a file
        /// <br/>            pattern with a single ... in it.  For local depots,
        /// <br/>            this path is relative to the server's root directory
        /// <br/>            or to server.depot.root if it has been configured
        /// <br/>            (Example: depot/...).  For remote depots, this path
        /// <br/>            refers to the remote server's namespace
        /// <br/>            (Example: //depot/...).
        /// <br/>
        /// <br/>   SpecMap:     For spec depots, the optional description of which
        /// <br/>                specs should be saved, as one or more patterns.
        /// <br/>
        /// <br/>   The -d flag deletes the specified depot.  If any files reside in the
        /// <br/>   depot, they must be removed with 'p4 obliterate' before deleting the
        /// <br/>   depot. If any archive files remain in the depot directory, they may
        /// <br/>   be referenced by lazy copies in other depots; use 'p4 snap' to break
        /// <br/>   those linkages. Snap lazy copies prior to obliterating the old depot
        /// <br/>   files to allow the obliterate command to remove any unreferenced
        /// <br/>   archives from the depot directory. If the depot directory is not
        /// <br/>   empty, you must specify the -f flag to delete the depot.
        /// <br/>
        /// <br/>   The -o flag writes the depot specification to standard output. The
        /// <br/>   user's editor is not invoked.
        /// <br/>
        /// <br/>   The -i flag reads a depot specification from standard input. The
        /// <br/>   user's editor is not invoked.
        /// <br/>
        /// <br/>
        /// </remarks>
        /// <example>
        ///		To create a streams depot named MobileApp:
        ///		<code>
        ///		    Depot d = new Depot();
        ///
        ///		    d.Id = "MobileApp";
        ///		    d.Description = "Stream depot for mobile app project";
        ///		    d.Owner = "admin";
        ///		    d.Type = DepotType.Stream;
        ///		    d.Map = "MobileApp/...";
        ///
        ///		    Depot MobileApp = Repository.CreateDepot(d, null);
        ///		</code>
        /// </example>
        /// <seealso cref="DepotCmdFlags"/>
        public Depot CreateDepot(Depot depot, Options options)
        {
            if (depot == null)
            {
                throw new ArgumentNullException("depot");
            }
            P4Command cmd = new P4Command(this, "depot", true);

            cmd.DataSet = depot.ToString();

            if (options == null)
            {
                options = new Options(DepotCmdFlags.Input);
            }
            if (options.ContainsKey("-i") == false)
            {
                options["-i"] = null;
            }

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                return(depot);
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }
Exemple #9
0
        /// <summary>
        /// Create a new stream in the repository.
        /// </summary>
        /// <param name="stream">Stream specification for the new stream</param>
        /// <param name="options">The '-i' flag is required when creating a new stream</param>
        /// <returns>The Stream object if new stream was created, null if creation failed</returns>
        /// <remarks> The '-i' flag is added if not specified by the caller
        /// <br/>
        /// <br/><b>p4 help stream</b>
        /// <br/>
        /// <br/>     stream -- Create, delete, or modify a stream specification
        /// <br/>
        /// <br/>     p4 stream [-P parent] -t type name
        /// <br/>     p4 stream [-f] [-d] [-o [-v]] [-P parent] -t type name
        /// <br/>     p4 stream -i [-f]
        /// <br/>
        /// <br/>   A stream specification ('spec') names a path in a stream depot to be
        /// <br/>   treated as a stream.  (See 'p4 help streamintro'.)  The spec also
        /// <br/>   defines the stream's lineage, its view, and its expected flow of
        /// <br/>   change.
        /// <br/>
        /// <br/>   The 'p4 stream' command puts the stream spec into a temporary file and
        /// <br/>   invokes the editor configured by the environment variable $P4EDITOR.
        /// <br/>   When creating a stream, the type of the stream must be specified with
        /// <br/>   the '-t' flag.  Saving the file creates or modifies the stream spec.
        /// <br/>
        /// <br/>   Creating a stream spec does not branch a new stream.  To branch a
        /// <br/>   stream, use 'p4 copy -r -S stream', where 'stream' is the name of a
        /// <br/>   stream spec.
        /// <br/>
        /// <br/>   The stream spec contains the following fields:
        /// <br/>
        /// <br/>   Stream:   The stream's path in a stream depot, of the form
        /// <br/>             //depotname/streamname. This is both the name of the stream
        /// <br/>             spec and the permanent, unique identifier of the stream.
        /// <br/>
        /// <br/>   Update:   The date this stream spec was last changed.
        /// <br/>
        /// <br/>   Access:   The date of the last command used with this spec.
        /// <br/>
        /// <br/>   Owner:    The stream's owner. A stream can be owned by a user, or
        /// <br/>             owned by a group. Can be changed.
        /// <br/>
        /// <br/>   Name:     An alternate name of the stream, for use in display outputs.
        /// <br/>             Defaults to the 'streamname' portion of the stream path.
        /// <br/>             Can be changed.
        /// <br/>
        /// <br/>   Parent:   The parent of this stream. Can be 'none' if the stream type
        /// <br/>             is 'mainline',  otherwise must be set to an existing stream
        /// <br/>             identifier, of the form //depotname/streamname.
        /// <br/>             Can be changed.
        /// <br/>
        /// <br/>   Type:     'mainline', 'virtual', 'development', 'release' or 'task'.
        /// <br/>             Defines the role of a stream: A 'mainline' may not have a
        /// <br/>             parent. A 'virtual' stream is not a stream but an alternate
        /// <br/>             view of its parent stream.  The 'development' and 'release'
        /// <br/>             streams have controlled flow. Can be changed.  A 'task'
        /// <br/>             stream is a lightweight short-lived stream that only
        /// <br/>             promotes edited files to the repository; branched and
        /// <br/>             integrated files are stored in shadow tables that are
        /// <br/>             removed when the task stream is deleted or unloaded.
        /// <br/>
        /// <br/>             Flow control is provided by 'p4 copy -S' and 'p4 merge -S'.
        /// <br/>             These commands restrict the flow of change as follows:
        /// <br/>
        /// <br/>             Stream Type   Direction of flow     Allowed with
        /// <br/>             -----------   -----------------     ------------
        /// <br/>             development   to parent stream      'p4 copy'
        /// <br/>             task          to parent stream      'p4 copy'
        /// <br/>             release       to parent stream      'p4 merge'
        /// <br/>             development   from parent stream    'p4 merge'
        /// <br/>             release       from parent stream    'p4 copy'
        /// <br/>
        /// <br/>   Description: An optional description of the stream.
        /// <br/>
        /// <br/>   Options:  Flags to configure stream behavior. Defaults are marked *:
        /// <br/>
        /// <br/>             unlocked *      Indicates whether the stream spec is locked
        /// <br/>             locked          against modifications. If locked, the spec
        /// <br/>                             may not be deleted, and only its owner or
        /// <br/>                             group users can modify it.
        /// <br/>
        /// <br/>             allsubmit *     Indicates whether all users or only the
        /// <br/>             ownersubmit     owner (or group users) of the stream may
        /// <br/>                             submit changes to the stream path.
        /// <br/>
        /// <br/>             toparent *      Indicates if controlled flow from the
        /// <br/>             notoparent      stream to its parent is expected to occur.
        /// <br/>
        /// <br/>             fromparent *    Indicates if controlled flow to the stream
        /// <br/>             nofromparent    from its parent is expected to occur.
        /// <br/>
        /// <br/>             mergedown *     Indicates if merge flow is restricted or
        /// <br/>             mergeany        merge is permitted from any other stream.
        /// <br/>
        /// <br/>             The [no]fromparent and [no]toparent options determine if
        /// <br/>             'p4 copy -S' and 'p4 merge -S' allow change to flow between
        /// <br/>             a stream and its parent. A 'virtual' stream must have its
        /// <br/>             flow options set as 'notoparent' and 'nofromparent'. Flow
        /// <br/>             options are ignored for 'mainline' streams.
        /// <br/>
        /// <br/>   Paths:    One or more lines that define file paths in the stream view.
        /// <br/>             Each line is of the form:
        /// <br/>
        /// <br/>                 &lt;path_type&gt; &lt;view_path&gt; [&lt;depot_path&gt;]
        /// <br/>
        /// <br/>             where &lt;path_type&gt; is a single keyword, &lt;view_path&gt; is a file
        /// <br/>             path with no leading slashes, and the optional &lt;depot_path&gt;
        /// <br/>             is a file path beginning with '//'.  Both &lt;view_path&gt; and
        /// <br/>             &lt;depot_path&gt; may contain trailing wildcards, but no leading
        /// <br/>             or embedded wildcards.  Lines in the Paths field may appear
        /// <br/>             in any order.  A duplicated &lt;view_path&gt; overrides its
        /// <br/>             preceding entry.
        /// <br/>
        /// <br/>             For example:
        /// <br/>
        /// <br/>                 share   src/...
        /// <br/>                 import  lib/abc/...  //over/there/abc/...
        /// <br/>                 isolate bin/*
        /// <br/>
        /// <br/>             Default is:
        /// <br/>
        /// <br/>                 share   ...
        /// <br/>
        /// <br/>             The &lt;path_type&gt; keyword must be one of:
        /// <br/>
        /// <br/>             share:  &lt;view_path&gt; will be included in client views and
        /// <br/>                     in branch views. Files in this path are accessible
        /// <br/>                     to workspaces, can be submitted to the stream, and
        /// <br/>                     can be integrated with the parent stream.
        /// <br/>
        /// <br/>             isolate: &lt;view_path&gt; will be included in client views but
        /// <br/>                      not in branch views. Files in this path are
        /// <br/>                      accessible to workspaces, can be submitted to the
        /// <br/>                      stream, but are not integratable with the parent
        /// <br/>                      stream.
        /// <br/>
        /// <br/>             import: &lt;view_path&gt; will be included in client views but
        /// <br/>                     not in branch views. Files in this path are mapped
        /// <br/>                     as in the parent stream's view (the default) or to
        /// <br/>                     &lt;depot_path&gt; (optional); they are accessible to
        /// <br/>                     workspaces, but can not be submitted or integrated
        /// <br/>                     to the stream.  If &lt;depot_path&gt; is used it may
        /// <br/>                     include a changelist specifier; clients of that
        /// <br/>                     stream will be limited to seeing revisions at that
        /// <br/>                     change or lower within that depot path.
        /// <br/>
        /// <br/>             import+: &lt;view_path&gt; same as 'import' except that files can
        /// <br/>                      be submitted to the import path.
        /// <br/>
        /// <br/>             exclude: &lt;view_path&gt; will be excluded from client views
        /// <br/>                      and branch views. Files in this path are not
        /// <br/>                      accessible to workspaces, and can't be submitted
        /// <br/>                      or integrated to the stream.
        /// <br/>
        /// <br/>             Paths are inherited by child stream views. A child stream's
        /// <br/>             paths can downgrade the inherited view, but not upgrade it.
        /// <br/>             (For instance, a child stream can downgrade a shared path to
        /// <br/>             an isolated path, but it can't upgrade an isolated path to a
        /// <br/>             shared path.) Note that &lt;depot_path&gt; is relevant only when
        /// <br/>             &lt;path_type&gt; is 'import'.
        /// <br/>
        /// <br/>   Remapped: Optional; one or more lines that define how stream view paths
        /// <br/>             are to be remapped in client views. Each line is of the form:
        /// <br/>
        /// <br/>                 &lt;view_path_1&gt; &lt;view_path_2&gt;
        /// <br/>
        /// <br/>             where &lt;view_path_1&gt; and &lt;view_path_2&gt; are Perforce view paths
        /// <br/>             with no leading slashes and no leading or embedded wildcards.
        /// <br/>             For example:
        /// <br/>
        /// <br/>                 ...    x/...
        /// <br/>                 y/*    y/z/*
        /// <br/>
        /// <br/>             Line ordering in the Remapped field is significant; if more
        /// <br/>             than one line remaps the same files, the later line has
        /// <br/>             precedence.  Remapping is inherited by child stream client
        /// <br/>             views.
        /// <br/>
        /// <br/>   Ignored: Optional; a list of file or directory names to be ignored in
        /// <br/>            client views. For example:
        /// <br/>
        /// <br/>                /tmp      # ignores files named 'tmp'
        /// <br/>                /tmp/...  # ignores dirs named 'tmp'
        /// <br/>                .tmp      # ignores file names ending in '.tmp'
        /// <br/>
        /// <br/>            Lines in the Ignored field may appear in any order.  Ignored
        /// <br/>            names are inherited by child stream client views.
        /// <br/>
        /// <br/>   The -d flag causes the stream spec to be deleted.  A stream spec may
        /// <br/>   not be deleted if it is referenced by child streams or stream clients.
        /// <br/>   Deleting a stream spec does not remove stream files, but it does mean
        /// <br/>   changes can no longer be submitted to the stream's path.
        /// <br/>
        /// <br/>   The -o flag causes the stream spec to be written to the standard
        /// <br/>   output. The user's editor is not invoked. -v may be used with -o to
        /// <br/>   expose the automatically generated client view for this stream.
        /// <br/>   ('p4 help branch' describes how to expose the branch view.)
        /// <br/>
        /// <br/>   The -P flag can be used to insert a value into the Parent field of a
        /// <br/>   new stream spec. It has no effect on an existing spec.
        /// <br/>
        /// <br/>   The -t flag is used to insert a value into the type field of a
        /// <br/>   new stream spec and to adjust the default fromparent option
        /// <br/>   for a new 'release' -type stream. The flag has no effect on an
        /// <br/>   existing spec.
        /// <br/>
        /// <br/>   The -i flag causes a stream spec to be read from the standard input.
        /// <br/>   The user's editor is not invoked.
        /// <br/>
        /// <br/>   The -f flag allows a user other than the owner to modify or delete a
        /// <br/>   locked stream. It requires 'admin' access granted by 'p4 protect'.
        /// <br/>
        /// <br/>
        /// </remarks>
        /// <example>
        ///
        ///     To create a new mainline stream:
        ///     <code>
        ///
        ///         Stream main  = new Stream();
        ///         string mainTargetId = "//Rocket/mainline";
        ///         main.Id = mainTargetId;
        ///         main.Type = StreamType.Mainline;
        ///         main.Parent = new DepotPath("none");
        ///         main.Options = new StreamOptionEnum(StreamOption.None);
        ///         main.Name = "mainline";
        ///         main.Paths = new ViewMap();
        ///         MapEntry p1 = new MapEntry(MapType.Import, new DepotPath("..."), null);
        ///         main.Paths.Add(p1);
        ///         MapEntry p2 = new MapEntry(MapType.Share, new DepotPath("core/gui/..."), null);
        ///         main.Paths.Add(p2);
        ///         main.OwnerName = "admin";
        ///         Stream mainline = rep.CreateStream(main, null);
        ///
        ///     </code>
        ///
        ///     To create a new development type stream with the parent //Rocket/mainline:
        ///     <code>
        ///
        ///          Stream dev = new Stream();
        ///          string developmentTargetId = "//Rocket/dev";
        ///          dev.Id = developmentTargetId;
        ///          dev.Type = StreamType.Development;
        ///          dev.Parent = new DepotPath("//Rocket/mainline");
        ///          dev.Name = "releasetest";
        ///          dev.Options = new StreamOptionEnum(StreamOption.None);
        ///          dev.Paths = new ViewMap();
        ///          MapEntry devp1 = new MapEntry(MapType.Share, new DepotPath("..."), null);
        ///          dev.Paths.Add(devp1);
        ///          dev.OwnerName = "admin";
        ///          Stream dev1 = rep.CreateStream(dev, null);
        ///
        ///     </code>
        ///
        /// </example>
        /// <seealso cref="StreamCmdFlags"/>
        public Stream CreateStream(Stream stream, Options options)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            P4Command cmd = new P4Command(this, "stream", true);

            stream.ParentView = GetParentView(stream);

            cmd.DataSet = stream.ToString();

            if (options == null)
            {
                options = new Options();
            }
            options["-i"] = null;

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                return(stream);
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }
        /// <summary>
        /// Create a new group in the repository.
        /// </summary>
        /// <param name="group">Group specification for the new group</param>
        /// <param name="options">The  '-i' flags are required when creating a new group</param>
        /// <returns>The Group object if new group was created, null if creation failed</returns>
        /// <remarks> The '-i' flag is added if not specified by the caller
        /// <br/>
        /// <br/><b>p4 help group</b>
        /// <br/>
        /// <br/>     group -- Change members of user group
        /// <br/>
        /// <br/>     p4 group [-a|-A] name
        /// <br/>     p4 group -d [-a] name
        /// <br/>     p4 group -o name
        /// <br/>     p4 group -i [-a|-A]
        /// <br/>
        /// <br/>   Create a group or modify the membership of an existing group.
        /// <br/>   A group can contain users and other groups. The group specification
        /// <br/>   is put into a temporary file and the editor (configured by the
        /// <br/>   environment variable $P4EDITOR) is invoked.
        /// <br/>
        /// <br/>   A group exists when it has any users or other groups in it, and
        /// <br/>   ceases to exist if all users and groups in it are removed.
        /// <br/>
        /// <br/>   Each group has MaxResults, MaxScanRows, and MaxLockTime fields,
        /// <br/>   which limit the resources committed to operations performed by
        /// <br/>   members of the group.  For these fields, 'unlimited' or 'unset'
        /// <br/>   means no limit for that	group.  An individual user's limit is the
        /// <br/>   highest of any group with a limit to which he belongs, unlimited if
        /// <br/>   any of his groups has 'unlimited' for that field, or unlimited
        /// <br/>   if he belongs to no group with a limit.  See 'p4 help maxresults'
        /// <br/>   for more information on MaxResults, MaxScanRows and MaxLockTime.
        /// <br/>
        /// <br/>   Each group also has a Timeout field, which specifies how long (in
        /// <br/>   seconds)  a 'p4 login' ticket remains valid.  A value of 'unset' or
        /// <br/>   'unlimited' is equivalent to no timeout. An individual's timeout is
        /// <br/>   the highest of any group with a limit to which he belongs, unlimited
        /// <br/>   if any of his groups has 'unlimited' for the timeout value, or
        /// <br/>   unlimited if he belongs to no group with a limit. See 'p4 help login'
        /// <br/>   for more information.
        /// <br/>
        /// <br/>   Each group has a PasswordTimeout field, which determines how long a
        /// <br/>   password remains valid for members of the group.
        /// <br/>
        /// <br/>   A group may be synchronized with an LDAP group by setting the three
        /// <br/>   fields: LdapConfig, LdapSearchQuery and LdapUserAttribute. This takes
        /// <br/>   the LDAP configuration (see 'p4 ldap') specified by LdapConfig and uses
        /// <br/>   it to execute the query stored by LdapSearchQuery. The LDAP attribute
        /// <br/>   specified by LdapUserAttribute is taken to be user's username and is
        /// <br/>   added to the group's user list. At least one group owner must be set if
        /// <br/>   these LDAP fields are used. If the LDAP server requires login for
        /// <br/>   read-only queries, then the LDAP configuration must contain valid bind
        /// <br/>   credentials in the LDAP spec's SearchBindDN and SearchPasswd fields
        /// <br/>
        /// <br/>   The -d flag deletes a group.
        /// <br/>
        /// <br/>   The -o flag writes the group specification to standard output. The
        /// <br/>   user's editor is not invoked.
        /// <br/>
        /// <br/>   The -i flag reads a group specification from standard input. The
        /// <br/>   user's editor is not invoked.  The new group specification replaces
        /// <br/>   the previous one.
        /// <br/>
        /// <br/>   The -a flag enables a user without 'super' access to modify the group
        /// <br/>   if that user is an 'owner' of that group. Group owners	are specified
        /// <br/>   in the 'Owners' field of the group spec.
        /// <br/>
        /// <br/>   The -A flag enables a user with 'admin' access to add a new group.
        /// <br/>   Existing groups may not be modified when this flag is used.
        /// <br/>
        /// <br/>   All commands that require access granted by 'p4 protect' consider a
        /// <br/>   user's groups when calculating access levels.
        /// <br/>
        /// <br/>   'p4 group' requires 'super' access granted by 'p4 protect' unless
        /// <br/>   invoked with the '-a' or '-A' flag by a qualified user.
        /// <br/>
        /// <br/>
        /// </remarks>
        /// <example>
        ///     To create the group 'Mygroup' with the owner 'Bob' and a user 'Ted'
        ///     when connected as super user:
        ///     <code>
        ///
        ///         string targetGroup = "Mygroup";
        ///         Group group = new Group();
        ///         group.Id = targetGroup;
        ///         group.UserNames = new  List&lt;string&gt; { "Ted" };
        ///			group.OwnerNames = new List&lt;string&gt; { "Bob" };
        ///         _repository.CreateGroup(group, null);
        ///
        ///     </code>
        ///     To create a group "everyone" when connected as a user with admin level
        ///     rights:
        ///     <code>
        ///
        ///         string targetGroup = "everyone";
        ///         Group group = new Group();
        ///         group.Id = targetGroup;
        ///         group.UserNames = new  List&lt;string&gt; { "Ted" };
        ///			group.OwnerNames = new List&lt;string&gt; { "Bob" };
        ///         _repository.CreateGroup(group, new Options(GroupCmdFlags.AdminAdd));
        ///
        ///     </code>
        /// </example>
        /// <seealso cref="GroupCmdFlags"/>
        public Group CreateGroup(Group group, Options options)
        {
            if (group == null)
            {
                throw new ArgumentNullException("group");
            }
            P4Command cmd = new P4Command(this, "group", true);

            cmd.DataSet = group.ToString();

            if (options == null)
            {
                options = new Options();
            }
            options["-i"] = null;

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                return(group);
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }
Exemple #11
0
        /// <summary>
        /// Delete a branch from the repository
        /// </summary>
        /// <param name="branch">The branch to be deleted</param>
        /// <param name="options">The '-f' and '-d' flags are valid when deleting an
        /// existing branch</param>
        /// <example>
        ///		To delete a branch spec owned by you [-d implied]:
        ///		<code>
        ///
        ///         BranchSpec deleteBranchSpec = new BranchSpec();
        ///         deleteBranchSpec.Id = "newBranchSpec";
        ///         _repository.DeleteBranchSpec(deleteBranchSpec, null);
        ///
        ///		</code>
        ///		To delete a branch owned by someone other than you [-d implied] [-f requires admin privileges]:
        ///		<code>
        ///
        ///         BranchSpec deleteBranchSpec = new BranchSpec();
        ///         deleteBranchSpec.Id = "newBranchSpec";
        ///			Options opts = new Options(BranchSpecsCmdFlags.Force);
        ///         _repository.DeleteBranchSpec(deleteBranchSpec, opts);
        ///
        ///		</code>
        /// </example>
        /// <seealso cref="BranchSpecCmdFlags"/>
        public void DeleteBranchSpec(BranchSpec branch, Options options)
        {
            if (branch == null)
            {
                throw new ArgumentNullException("branch");
            }
            P4Command cmd = new P4Command(this, "branch", true, branch.Id);

            if (options == null)
            {
                options = new Options(BranchSpecCmdFlags.Delete, null, null);
            }

            if (options.ContainsKey("-d") == false)
            {
                options["-d"] = null;
            }

            P4CommandResult results = cmd.Run(options);

            if (results.Success == false)
            {
                P4Exception.Throw(results.ErrorList);
            }
        }
Exemple #12
0
        /// <summary>
        /// Create a new user in the repository.
        /// </summary>
        /// <param name="user">User specification for the new user</param>
        /// <param name="options">The '-f' and '-i' flags are required when creating a new user</param>
        /// <returns>The User object if new user was created, null if creation failed</returns>
        /// <remarks> The '-i' flag is added if not specified by the caller
        /// <br/>
        /// <br/><b>p4 help user</b>
        /// <br/>
        /// <br/>     user -- Create or edit a user specification
        /// <br/>
        /// <br/>     p4 user [-f] [name]
        /// <br/>     p4 user -d [-f] name
        /// <br/>     p4 user -o [name]
        /// <br/>     p4 user -i [-f]
        /// <br/>
        /// <br/>   Create a new user specification or edit an existing user specification.
        /// <br/>   The specification form is put into a temporary file and the editor
        /// <br/>   (configured by the environment variable $P4EDITOR) is invoked.
        /// <br/>
        /// <br/>   Normally, a user specification is created automatically the first
        /// <br/>   time that the user issues any command that updates the depot. The
        /// <br/>   'p4 user' command is typically used to edit the user's subscription
        /// <br/>   list for change review.
        /// <br/>
        /// <br/>   The user specification form contains the following fields:
        /// <br/>
        /// <br/>   User:        The user name (read-only).
        /// <br/>
        /// <br/>   Email:       The user's email address (Default: user@client).
        /// <br/>
        /// <br/>   Update:      The date the specification was last modified (read-only).
        /// <br/>
        /// <br/>   Access:      The date that the user last issued a client command.
        /// <br/>
        /// <br/>   FullName:    The user's real name.
        /// <br/>
        /// <br/>   JobView:     Selects jobs that are displayed when the user creates
        /// <br/>            a changelist. These jobs can be closed automatically
        /// <br/>            when the user submits the changelist. For a description
        /// <br/>            of jobview syntax, see 'p4 help jobview'
        /// <br/>
        /// <br/>   Reviews:     The subscription list for change review.  There is no
        /// <br/>                limit on the number of lines that this field can contain.
        /// <br/>            You can include the following wildcards:
        /// <br/>
        /// <br/>            ...            matches any characters including /
        /// <br/>            *              matches any character except /
        /// <br/>
        /// <br/>   Password:    The user's password.  See 'p4 help passwd'.
        /// <br/>
        /// <br/>   Type:        Must be 'service', operator, or 'standard'. Default is
        /// <br/>            'standard'. Once set, the user type cannot be changed.
        /// <br/>
        /// <br/>   AuthMethod:  Must be 'perforce' or 'ldap'. Default is 'perforce'
        /// <br/>            Unless overridden by the 'auth.default.method'
        /// <br/>            configurable, see 'p4 help configurables'. AuthMethod
        /// <br/>            can only be changed when the -f flag has been provided.
        /// <br/>
        /// <br/>   The -d flag deletes the specified user (unless the user has files
        /// <br/>   open).
        /// <br/>
        /// <br/>   The -o flag writes the user specification to the standard output.
        /// <br/>   The user's editor is not invoked.
        /// <br/>
        /// <br/>   The -i flag reads a user specification from the standard input.
        /// <br/>   The user's editor is not invoked.
        /// <br/>
        /// <br/>   The -f flag forces the creation, update or deletion of the specified
        /// <br/>   user, and enables you to change the Last Modified date. By default,
        /// <br/>   users can only delete or modify their own user specifications.  The
        /// <br/>   -f flag requires 'super' access, which is granted by 'p4 protect'.
        /// <br/>
        /// <br/>
        /// </remarks>
        /// <example>
        ///		To create a user with the username bsmith (when connected with
        ///		Connection.UserName = "******"):
        ///		<code>
        ///			User u = new User();
        ///			u.Id = "bsmith";
        ///			u.FullName = "Brian Smith";
        ///			u.EmailAddress = "*****@*****.**";
        ///
        ///         u = Repository.CreateUser(u, null);
        ///		</code>
        ///		To create a user with the username bsmith (when connected with
        ///		a user that has super access):
        ///		<code>
        ///			User u = new User();
        ///			u.Id = "bsmith";
        ///			u.FullName = "Brian Smith";
        ///			u.EmailAddress = "*****@*****.**";
        ///
        ///         UserCmdOptions opts = new UserCmdOptions(UserCmdFlags.Force);
        ///
        ///         u = Repository.CreateUser(u, opts);
        ///		</code>
        /// </example>
        /// <seealso cref="UserCmdFlags"/>
        public User CreateUser(User user, Options options)
        {
            if (user == null)
            {
                throw new ArgumentNullException("user");
            }
            P4Command cmd = new P4Command(this, "user", true);

            cmd.DataSet = user.ToString();

            if (options == null)
            {
                options = new Options();
            }
            options["-i"] = null;

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                return(user);
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }
Exemple #13
0
 /// <summary>
 /// Run the command supplying additional arguments
 /// </summary>
 /// <param name="flags">Additional arguments inserted in front of the current arguments</param>
 /// <returns>Success/Failure</returns>
 public P4CommandResult Run(StringList flags)
 {
     lock (this)
     {
         P4CommandResult results = null;
         results = new P4CommandResult(this, flags);
         return(results);
     }
 }
Exemple #14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="options"></param>
        /// <param name="jobs"></param>
        /// <returns></returns>
        /// <remarks>
        /// <br/><b>p4 help fix</b>
        /// <br/>
        /// <br/>     fix -- Mark jobs as being fixed by the specified changelist
        /// <br/>
        /// <br/>     p4 fix [-d] [-s status] -c changelist# jobName ...
        /// <br/>
        /// <br/>   'p4 fix' marks each named job as being fixed by the changelist
        /// <br/>   number specified with -c.  The changelist can be pending or
        /// <br/>   submitted and the jobs can be open or closed (fixed by another
        /// <br/>   changelist).
        /// <br/>
        /// <br/>   If the changelist has already been submitted and the job is still
        /// <br/>   open, then 'p4 fix' marks the job closed.  If the changelist has not
        /// <br/>   been submitted and the job is still open, the job is closed when the
        /// <br/>   changelist is submitted.  If the job is already closed, it remains
        /// <br/>   closed.
        /// <br/>
        /// <br/>   The -d flag deletes the specified fixes.  This operation does not
        /// <br/>   otherwise affect the specified changelist or jobs.
        /// <br/>
        /// <br/>   The -s flag uses the specified status instead of the default defined
        /// <br/>   in the job specification.
        /// <br/>
        /// <br/>   The fix's status is reported by 'p4 fixes', and is related to the
        /// <br/>   job's status. Certain commands set the job's status to the fix's
        /// <br/>   status for each job associated with the change. When a job is fixed
        /// <br/>   by a submitted change, the job's status is set to match the fix
        /// <br/>   status.  When a job is fixed by a pending change, the job's status
        /// <br/>   is set to match the fix status when the change is submitted. If the
        /// <br/>   fix's status is 'same', the job's status is left unchanged.
        /// <br/>
        /// <br/>
        /// </remarks>
        public IList <Fix> FixJobs(Options options, params Job[] jobs)
        {
            if (_initialized == false)
            {
                throw new ApplicationException("Changelist connection is not initialized");
            }
            IList <Fix> value = null;

            P4Command cmd = null;

            if ((jobs != null) && (jobs.Length > 0))
            {
                cmd = new P4Command(Connection, "fix", true, Job.ToStrings(jobs));
            }
            else
            {
                cmd = new P4Command(Connection, "fix", true);
            }
            if (options == null)
            {
                options = new Options();
            }
            if (options.ContainsKey("-c") == false)
            {
                options["-c"] = this.Id.ToString();
            }

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                if ((results.TaggedOutput == null) || (results.TaggedOutput.Count <= 0))
                {
                    return(null);
                }
                value = new List <Fix>();
                foreach (TaggedObject obj in results.TaggedOutput)
                {
                    Fix fix = Fix.FromFixCmdTaggedOutput(obj);
                    value.Add(fix);
                }
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }

            return(value);
        }
Exemple #15
0
        /// <summary>
        /// Get a list of streams from the repository
        /// </summary>
        /// <param name="options">options for the streams command<see cref="StreamsCmdOptions"/></param>
        /// <param name="files">files to filter results by</param>
        /// <returns>A list containing the matching streams</returns>
        /// <remarks>
        /// <br/><b>p4 help streams</b>
        /// <br/>
        /// <br/>     streams -- Display list of streams
        /// <br/>
        /// <br/>     p4 streams [-U -F filter -T fields -m max] [streamPath ...]
        /// <br/>
        /// <br/>   Reports the list of all streams currently known to the system.  If
        /// <br/>   a 'streamPath' argument is specified, the list of streams is limited
        /// <br/>   to those matching the supplied path. Unloaded task streams are not
        /// <br/>   listed by default.
        /// <br/>
        /// <br/>   For each stream, a single line of output lists the stream depot path,
        /// <br/>   the type, the parent stream depot path, and the stream name.
        /// <br/>
        /// <br/>   The -F filter flag limits the output to files satisfying the expression
        /// <br/>   given as 'filter'.  This filter expression is similar to the one used
        /// <br/>   by 'jobs -e jobview',  except that fields must match those above and
        /// <br/>   are case sensitive.
        /// <br/>
        /// <br/>           e.g. -F "Parent=//Ace/MAIN &amp; Type=development"
        /// <br/>
        /// <br/>   Note: the filtering takes place post-compute phase; there are no
        /// <br/>   indexes to optimize performance.
        /// <br/>
        /// <br/>   The -T fields flag (used with tagged output) limits the fields output
        /// <br/>   to those specified by a list given as 'fields'.  These field names can
        /// <br/>   be separated by a space or a comma.
        /// <br/>
        /// <br/>           e.g. -T "Stream, Owner"
        /// <br/>
        /// <br/>   The -m max flag limits output to the first 'max' number of streams.
        /// <br/>
        /// <br/>   The -U flag lists unloaded task streams (see 'p4 help unload').
        /// <br/>
        /// <br/>
        /// </remarks>
        /// <example>
        ///         To get the first 3 development type streams with the parent //flow/mainline:
        ///
        /// <code>
        ///         IList&#60;Stream&#62; = rep.GetStreams(new Options(StreamsCmdFlags.None,
        ///                    "Parent=//flow/mainline &amp; Type=development", null, "//...", 3));
        /// </code>
        /// </example>
        public IList <Stream> GetStreams(Options options, params FileSpec[] files)
        {
            P4Command cmd = null;

            if ((files != null) && (files.Length > 0))
            {
                cmd = new P4Command(this, "streams", true, FileSpec.ToStrings(files));
            }
            else
            {
                cmd = new P4Command(this, "streams", true);
            }

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                if ((results.TaggedOutput == null) || (results.TaggedOutput.Count <= 0))
                {
                    return(null);
                }
                List <Stream> value = new List <Stream>();

                bool   dst_mismatch = false;
                string offset       = string.Empty;

                if (Server != null && Server.Metadata != null)
                {
                    offset       = Server.Metadata.DateTimeOffset;
                    dst_mismatch = FormBase.DSTMismatch(Server.Metadata);
                }

                foreach (TaggedObject obj in results.TaggedOutput)
                {
                    Stream stream = new Stream();
                    stream.FromStreamsCmdTaggedOutput(obj, offset, dst_mismatch);
                    value.Add(stream);
                }
                return(value);
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }
Exemple #16
0
        /// <summary>
        /// Get a list of users from the repository
        /// </summary>
        /// <param name="options">Options for the users command. See: <see cref="UsersCmdFlags"/></param>
        /// <param name="user">Optional list of users. </param>
        /// <returns>A list containing the matching users</returns>
        /// <remarks>
        /// <br/><b>p4 help users</b>
        /// <br/>
        /// <br/>     users -- List Perforce users
        /// <br/>
        /// <br/>     p4 users [-l -a -r -c] [-m max] [user ...]
        /// <br/>
        /// <br/>   Lists all Perforce users or users that match the 'user' argument.
        /// <br/>   The report includes the last time that each user accessed the system.
        /// <br/>
        /// <br/>   The -m max flag limits output to the first 'max' number of users.
        /// <br/>
        /// <br/>   The -a flag includes service and operator users in the output.
        /// <br/>
        /// <br/>   The -l flag includes additional information in the output.  The -l
        /// <br/>   flag requires 'super' access, which is granted by 'p4 protect'.
        /// <br/>
        /// <br/>   The -r and -c flags are only allowed on replica servers.  When
        /// <br/>   -r is given only users who have used a replica are reported and
        /// <br/>   when -c is given only the user information from the central server
        /// <br/>   is reported.  Otherwise on a replica server, the user list will
        /// <br/>   be slightly different from the master server as the user access times
        /// <br/>   will reflect replica usage or master usage whichever is newer.
        /// <br/>
        /// <br/>
        /// </remarks>
        /// <example>
        ///		To get the first 10 users that start with the letter 'A':
        ///		<code>
        ///			UsersCmdOptions opts = new UsersCmdOptions(UsersCmdFlags.None, 10);
        ///			IList&#60;User&#62; users = Repository.getUsers(opts, "A*");
        ///		</code>
        ///		To get the users for 'Bob', 'Ted', 'Carol' and 'Alice':
        ///		<code>
        ///			UsersCmdOptions opts = new UsersCmdOptions(UsersCmdFlags.None, -1);
        ///			IList&#60;User&#62; users = Repository.getUsers(opts, "Bob", "Ted", "Carol", "Alice");
        ///		</code>
        ///		To get all the users (WARNING, will fetch all users from the repository):
        ///		<code>
        ///			UsersCmdOptions opts = new UsersCmdOptions(UsersCmdFlags.IncludeAll, -1);
        ///         IList&#60;User&#62; users = Repository.getUsers(opts, null);
        ///		</code>
        /// </example>
        /// <seealso cref="UsersCmdFlags"/>
        public IList <User> GetUsers(Options options, params string[] user)
        {
            P4Command cmd = null;

            if ((user != null) && (user.Length > 0))
            {
                cmd = new P4Command(this, "users", true, user);
            }
            else
            {
                cmd = new P4Command(this, "users", true);
            }

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                if ((results.TaggedOutput == null) || (results.TaggedOutput.Count <= 0))
                {
                    return(null);
                }
                List <User> value = new List <User>();
                foreach (TaggedObject obj in results.TaggedOutput)
                {
                    bool   dst_mismatch = false;
                    string offset       = string.Empty;

                    if (Server != null && Server.Metadata != null)
                    {
                        offset       = Server.Metadata.DateTimeOffset;
                        dst_mismatch = FormBase.DSTMismatch(Server.Metadata);
                    }
                    User u = new User();
                    u.FromUserCmdTaggedOutput(obj, offset, dst_mismatch);
                    value.Add(u);
                }
                return(value);
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }
Exemple #17
0
        /// <summary>
        /// Get the record for an existing job from the repository.
        /// </summary>
        /// <param name="job">Job name</param>
        /// <param name="options">There are no valid flags to use when fetching an existing job</param>
        /// <returns>The Job object if new job was found, null if the requested job does not exist</returns>
        /// <example>
        ///		Get the record for job 'job000001':
        ///		<code>
        ///
        ///			Job job = _repository.GetJob("job000001", null);
        ///
        ///		</code>
        /// </example>
        public Job GetJob(string job, Options options)
        {
            if (job == null)
            {
                throw new ArgumentNullException("job");
            }
            // first confirm the job exists
            if (!string.IsNullOrEmpty(job))
            {
                JobsCmdOptions opts = new JobsCmdOptions(JobsCmdFlags.LongDescriptions, "Job=" + job, 1);
                if (GetJobs(opts, null) == null)
                {
                    return(null);
                }
            }

            P4Command cmd = new P4Command(this, "job", true, job);

            if (options == null)
            {
                options = new Options();
            }
            options["-o"] = null;

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                if ((results.TaggedOutput == null) || (results.TaggedOutput.Count <= 0))
                {
                    return(null);
                }
                Job value = new Job();
                value.FromJobCmdTaggedOutput((results.TaggedOutput[0]));

                return(value);
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }
Exemple #18
0
        /// <summary>
        /// Create a new job in the repository.
        /// </summary>
        /// <param name="job">Job specification for the new job</param>
        /// <param name="options">The '-i' flags is needed when creating a new job</param>
        /// <returns>The Job object if new job was created, null if creation failed</returns>
        /// <remarks> The '-i' flags is added if not specified by the caller
        /// <br/>
        /// <br/><b>p4 help job</b>
        /// <br/>
        /// <br/>     job -- Create or edit a job (defect) specification
        /// <br/>
        /// <br/>     p4 job [-f] [jobName]
        /// <br/>     p4 job -d jobName
        /// <br/>     p4 job -o [jobName]
        /// <br/>     p4 job -i [-f]
        /// <br/>
        /// <br/>   The 'p4 job' command creates and edits job specifications using an
        /// <br/>   ASCII form. A job is a defect, enhancement, or other unit of
        /// <br/>   intended work.The 'p4 fix' command associates changelists with jobs.
        /// <br/>
        /// <br/>   With no arguments, 'p4 job' creates an empty job specification
        /// <br/>   and invokes the user's editor.  When the specification is saved,
        /// <br/>   a job name of the form jobNNNNNN is assigned.  If the jobName
        /// <br/>   parameter is specified on the command line, the job is created or
        /// <br/>   opened for editing.
        /// <br/>
        /// <br/>   As jobs are entered or updated, all fields are indexed for searching
        /// <br/>   Text fields are broken into individual alphanumeric words (punctuation
        /// <br/>   and whitespace are ignored) and each word is case-folded and entered
        /// <br/>   into the word index.  Date fields are converted to an internal
        /// <br/>   representation (seconds since 1970/01/01 00:00:00) and entered
        /// <br/>   into the date index.
        /// <br/>
        /// <br/>   The fields that compose a job are defined by the 'p4 jobspec' command.
        /// <br/>   Perforce provides a default job specification that you can edit.
        /// <br/>
        /// <br/>   The -d flag deletes the specified job. You cannot delete a job if
        /// <br/>   it has pending or submitted fixes associated with it.
        /// <br/>
        /// <br/>   The -o flag writes the job specification to the standard output.
        /// <br/>   The user's editor is not invoked.
        /// <br/>
        /// <br/>   The -i flag reads a job specification from the standard input. The
        /// <br/>   user's editor is not invoked.
        /// <br/>
        /// <br/>   The -f flag enables you set fields that are read-only by default.
        /// <br/>   The -f flag requires 'admin' access, which is granted using the
        /// <br/>   'p4 protect' command.
        /// <br/>
        /// <br/>
        /// </remarks>
        /// <example>
        ///		To create a new job with a name 'Myjob':
        ///		<code>
        ///
        ///			Job job = new Job();
        ///			job.Id = "Myjob";
        ///			job.Add("Status", "open");
        ///			job.Add("User", "admin");
        ///			job.Add("Description", "this is a test job");
        ///			Job job = _repository.CreateJob( job, null);
        ///
        ///		</code>
        ///		To create a job with name of the form jobNNNNNN:
        ///		<code>
        ///
        ///         Job job = new Job();
        ///			job.Id = "new";
        ///			job.Add("Status", "open");
        ///			job.Add("User", "admin");
        ///			job.Add("Description", "this is a test job");
        ///			Job job = _repository.CreateJob( job, JobCmdFlags.Input);
        ///
        ///		</code>
        /// </example>
        /// <seealso cref="JobCmdFlags"/>
        public Job CreateJob(Job job, Options options)
        {
            if (job == null)
            {
                throw new ArgumentNullException("job");
            }
            P4Command cmd = new P4Command(this, "job", true);

            cmd.DataSet = job.ToString();

            if (options == null)
            {
                options = new Options();
            }
            options["-i"] = null;

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                // If this a new job that was saved, we need to parse out the new job Id
                if (job.Id == "new")
                {
                    string[] words = results.InfoOutput[0].Message.Split(' ');

                    string newId  = words[1];
                    Job    newJob = GetJob(newId);
                    return(newJob);
                }
                else
                {
                    Job newJob = GetJob(job.Id);
                    return(newJob);
                }
            }

            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }
Exemple #19
0
        /// <summary>
        /// Delete a user from the repository
        /// </summary>
        /// <param name="user">The user to be deleted</param>
        /// <param name="options">Only the '-f' flag is valid when deleting an existing user</param>
        /// <remarks>
        /// <br/>
        /// <br/><b>p4 help user</b>
        /// <br/>
        /// <br/>     user -- Create or edit a user specification
        /// <br/>
        /// <br/>     p4 user [-f] [name]
        /// <br/>     p4 user -d [-f] name
        /// <br/>     p4 user -o [name]
        /// <br/>     p4 user -i [-f]
        /// <br/>
        /// <br/>   Create a new user specification or edit an existing user specification.
        /// <br/>   The specification form is put into a temporary file and the editor
        /// <br/>   (configured by the environment variable $P4EDITOR) is invoked.
        /// <br/>
        /// <br/>   Normally, a user specification is created automatically the first
        /// <br/>   time that the user issues any command that updates the depot. The
        /// <br/>   'p4 user' command is typically used to edit the user's subscription
        /// <br/>   list for change review.
        /// <br/>
        /// <br/>   The user specification form contains the following fields:
        /// <br/>
        /// <br/>   User:        The user name (read-only).
        /// <br/>
        /// <br/>   Email:       The user's email address (Default: user@client).
        /// <br/>
        /// <br/>   Update:      The date the specification was last modified (read-only).
        /// <br/>
        /// <br/>   Access:      The date that the user last issued a client command.
        /// <br/>
        /// <br/>   FullName:    The user's real name.
        /// <br/>
        /// <br/>   JobView:     Selects jobs that are displayed when the user creates
        /// <br/>            a changelist. These jobs can be closed automatically
        /// <br/>            when the user submits the changelist. For a description
        /// <br/>            of jobview syntax, see 'p4 help jobview'
        /// <br/>
        /// <br/>   Reviews:     The subscription list for change review.  There is no
        /// <br/>                limit on the number of lines that this field can contain.
        /// <br/>            You can include the following wildcards:
        /// <br/>
        /// <br/>            ...            matches any characters including /
        /// <br/>            *              matches any character except /
        /// <br/>
        /// <br/>   Password:    The user's password.  See 'p4 help passwd'.
        /// <br/>
        /// <br/>   Type:        Must be 'service', operator, or 'standard'. Default is
        /// <br/>            'standard'. Once set, the user type cannot be changed.
        /// <br/>
        /// <br/>   AuthMethod:  Must be 'perforce' or 'ldap'. Default is 'perforce'
        /// <br/>            Unless overridden by the 'auth.default.method'
        /// <br/>            configurable, see 'p4 help configurables'. AuthMethod
        /// <br/>            can only be changed when the -f flag has been provided.
        /// <br/>
        /// <br/>   The -d flag deletes the specified user (unless the user has files
        /// <br/>   open).
        /// <br/>
        /// <br/>   The -o flag writes the user specification to the standard output.
        /// <br/>   The user's editor is not invoked.
        /// <br/>
        /// <br/>   The -i flag reads a user specification from the standard input.
        /// <br/>   The user's editor is not invoked.
        /// <br/>
        /// <br/>   The -f flag forces the creation, update or deletion of the specified
        /// <br/>   user, and enables you to change the Last Modified date. By default,
        /// <br/>   users can only delete or modify their own user specifications.  The
        /// <br/>   -f flag requires 'super' access, which is granted by 'p4 protect'.
        /// <br/>
        /// <br/>
        /// </remarks>
        /// <example>
        ///		To delete a user with the username bsmith (when connected with
        ///		Connection.UserName = "******"):
        ///		<code>
        ///		    User u = Repository.GetUser("bsmith");
        ///         Repository.DeleteUser(u, null);
        ///		</code>
        ///		To delete a user with the username bsmith (when connected with
        ///		a user that has super access):
        ///		<code>
        ///         UserCmdOptions opts = new UserCmdOptions(UserCmdFlags.Force);
        ///
        ///			User u = Repository.GetUser("bsmith");
        ///         Repository.DeleteUser(u, opts);
        ///		</code>
        /// </example>
        /// <seealso cref="UserCmdFlags"/>
        public void DeleteUser(User user, Options options)
        {
            if (user == null)
            {
                throw new ArgumentNullException("user");
            }
            P4Command cmd = new P4Command(this, "user", true, user.Id);

            if (options == null)
            {
                options = new Options();
            }
            options["-d"] = null;

            P4CommandResult results = cmd.Run(options);

            if (results.Success == false)
            {
                P4Exception.Throw(results.ErrorList);
            }
        }
Exemple #20
0
        /// <summary>
        /// Delete a job from the repository
        /// </summary>
        /// <param name="job">The job to be deleted</param>
        /// <param name="options">Only the '-f' flag is valid when deleting an existing job</param>
        /// <example>
        ///		To delete job000002 from the repository :
        ///		<code>
        ///
        ///			Job u = _repository.GetJob("job000002");
        ///			_repository.DeleteJob(u, null);
        ///
        ///		</code>
        ///	</example>
        public void DeleteJob(Job job, Options options)
        {
            if (job == null)
            {
                throw new ArgumentNullException("job");
            }
            P4Command cmd = new P4Command(this, "job", true, job.Id);

            if (options == null)
            {
                options = new Options();
            }
            options["-d"] = null;

            P4CommandResult results = cmd.Run(options);

            if (results.Success == false)
            {
                P4Exception.Throw(results.ErrorList);
            }
        }
        /// <summary>
        /// Delete a group from the repository
        /// </summary>
        /// <param name="group">The group to be deleted</param>
        /// <param name="options">The -a flag is needed to delete
        ///  a group when the user is an owner but not a superuser</param>
        /// <example>
        ///		To delete the group 'Mygroup' when the user is a superuser:
        ///		<code>
        ///
        ///			string targetGroup = "Mygroup";
        ///			Group group = new Group();
        ///			group.Id = targetGroup;
        ///			_repository.DeleteGroup(group, null);
        ///
        ///		</code>
        ///		To delete the group 'Mygroup' when the user is an owner but not a superuser:
        ///		<code>
        ///
        ///			string targetGroup = "Mygroup";
        ///			Group group = new _repository.GetGroup(targetGroup);
        ///			GroupCmdOptions opts = new GroupCmdOptions(GroupCmdFlags.OwnerAccess);
        ///			_repository.DeleteGroup(group, opts);
        ///
        ///		</code>
        /// </example>
        /// <seealso cref="GroupCmdFlags"/>
        public void DeleteGroup(Group group, Options options)
        {
            if (group == null)
            {
                throw new ArgumentNullException("group");
            }
            P4Command cmd = new P4Command(this, "group", true, group.Id);

            if (options == null)
            {
                options = new Options();
            }
            options["-d"] = null;

            P4CommandResult results = cmd.Run(options);

            if (results.Success == false)
            {
                P4Exception.Throw(results.ErrorList);
            }
        }
Exemple #22
0
        /// <summary>
        /// Get the record for an existing branch from the repository.
        /// </summary>
        /// <param name="branch">Branch name</param>
        /// <param name="stream">Stream name</param>
        /// <param name="parent">Parent stream</param>
        /// <param name="options">Options</param>
        /// <returns>The Branch object if branch was found, null if creation failed</returns>
        /// <example>
        ///		To get a branch spec:
        ///		<code>
        ///
        ///		BranchSpec getBranchSpec = _repository.GetBranchSpec("newBranchSpec");
        ///
        ///		</code>
        /// </example>
        public BranchSpec GetBranchSpec(string branch, string stream, string parent, Options options)
        {
            if (branch == null)
            {
                throw new ArgumentNullException("branch");
            }
            P4Command cmd = new P4Command(this, "branch", true, branch);

            if (options == null)
            {
                options = new Options((BranchSpecCmdFlags.Output), stream, parent);
            }

            if (options.ContainsKey("-o") == false)
            {
                options["-o"] = null;
            }

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                if ((results.TaggedOutput == null) || (results.TaggedOutput.Count <= 0))
                {
                    return(null);
                }

                BranchSpec value = new BranchSpec();
                value.FromBranchSpecCmdTaggedOutput(results.TaggedOutput[0]);

                return(value);
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }
        public IList <Depot> GetDepots(Options options)
        {
            P4Command cmd = new P4Command(this, "depots", true);


            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                if ((results.TaggedOutput == null) || (results.TaggedOutput.Count <= 0))
                {
                    return(null);
                }

                bool   dst_mismatch = false;
                string offset       = string.Empty;

                if (Server != null && Server.Metadata != null)
                {
                    offset       = Server.Metadata.DateTimeOffset;
                    dst_mismatch = FormBase.DSTMismatch(Server.Metadata);
                }

                List <Depot> value = new List <Depot>();
                foreach (TaggedObject obj in results.TaggedOutput)
                {
                    Depot depot = new Depot();
                    depot.FromDepotsCmdTaggedOutput(obj, offset, dst_mismatch);
                    value.Add(depot);
                }
                return(value);
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }
        /// <summary>
        /// Get the record for an existing label from the repository.
        /// </summary>
        /// <param name="label">Label name</param>
        /// <param name="template">Template to use (if required)</param>
        /// <param name="options">Flags used when fetching an existing label</param>
        /// <returns>The Label object if label was found, null if creation failed</returns>
        /// <example>
        ///
        ///     To get the admin_label with the gobal option:
        ///
        /// <code>
        ///
        ///         LabelCmdOptions opts = new LabelCmdOptions(LabelCmdFlags.Global,null);
        ///         Label label = rep.GetLabel("admin_label", null, opts);
        ///
        /// </code>
        /// </example>
        public Label GetLabel(string label, string template, Options options)
        {
            if (label == null)
            {
                throw new ArgumentNullException("label");
            }
            P4Command cmd = new P4Command(this, "label", true, label);

            if (options == null)
            {
                options = new Options((LabelCmdFlags.Output), template);
            }

            if (options.ContainsKey("-o") == false)
            {
                options["-o"] = null;
            }

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                if ((results.TaggedOutput == null) || (results.TaggedOutput.Count <= 0))
                {
                    return(null);
                }
                Label value = new Label();

                value.FromLabelCmdTaggedOutput(results.TaggedOutput[0]);

                return(value);
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }
Exemple #25
0
        /// <summary>
        /// Get the record for an existing stream from the repository.
        /// </summary>
        /// <param name="stream">Stream name</param>
        /// <param name="options">There are no valid flags to use when fetching an existing stream</param>
        /// <returns>The Stream object if new stream was found, null if creation failed</returns>
        /// <example>
        ///
        ///     Get the stream with the stream Id "//Rocket/GUI":
        ///     <code>
        ///
        ///         string targetStream = "//Rocket/GUI";
        ///         Stream s = rep.GetStream(targetStream, null, null);
        ///
        ///     </code>
        ///    Get stream spec for a new development type stream with the parent
        ///    //Rocket/MAIN:
        ///     <code>
        ///
        ///         string targetStream = "//Rocket/GUI2";
        ///         string parentStream = "//Rocket/MAIN";
        ///         Stream stream = rep.GetStream(targetStream,
        ///             new StreamCmdOptions(StreamCmdFlags.None, parentStream,
        ///             StreamType.Development.ToString()));
        ///
        ///     </code>
        /// </example>
        public Stream GetStream(string stream, Options options)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            P4Command cmd = new P4Command(this, "stream", true, stream);

            if (options == null)
            {
                options = new StreamCmdOptions((StreamCmdFlags.Output), null, null);
            }
            if (options.ContainsKey("-o") == false)
            {
                options["-o"] = null;
            }

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                if ((results.TaggedOutput == null) || (results.TaggedOutput.Count <= 0))
                {
                    return(null);
                }
                Stream value = new Stream();

                value.FromStreamCmdTaggedOutput(results.TaggedOutput[0]);

                return(value);
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }
        /// <summary>
        /// Get the record for an existing depot from the repository.
        /// </summary>
        /// <param name="depot">Depot name</param>
        /// <param name="options">There are no valid flags to use when fetching an existing depot</param>
        /// <returns>The Depot object if depot was found, null if not</returns>
        /// <remarks>
        /// <br/>
        /// <br/><b>p4 help depot</b>
        /// <br/>
        /// <br/>     depot -- Create or edit a depot specification
        /// <br/>
        /// <br/>     p4 depot name
        /// <br/>     p4 depot -d [-f] name
        /// <br/>     p4 depot -o name
        /// <br/>     p4 depot -i
        /// <br/>
        /// <br/>   Create a new depot specification or edit an existing depot
        /// <br/>   specification. The specification form is put into a temporary file
        /// <br/>   and the editor (configured by the environment variable $P4EDITOR)
        /// <br/>   is invoked.
        /// <br/>
        /// <br/>   The depot specification contains the following fields:
        /// <br/>
        /// <br/>   Depot:       The name of the depot.  This name cannot be the same as
        /// <br/>            any branch, client, or label name.
        /// <br/>
        /// <br/>   Owner:       The user who created this depot.
        /// <br/>
        /// <br/>   Date:        The date that this specification was last modified.
        /// <br/>
        /// <br/>   Description: A short description of the depot (optional).
        /// <br/>
        /// <br/>   Type:        One of the types: 'local', 'stream', 'remote', 'spec',
        /// <br/>            'archive', or 'unload'.
        /// <br/>
        /// <br/>            A 'local' depot (the default) is managed directly by
        /// <br/>            the server and its files reside in the server's root
        /// <br/>            directory.
        /// <br/>
        /// <br/>            A 'stream' depot is a local depot dedicated to the
        /// <br/>            storage of files in a stream.
        /// <br/>
        /// <br/>            A 'remote' depot refers to files in another Perforce
        /// <br/>            server.
        /// <br/>
        /// <br/>            A 'spec' depot automatically archives all edited forms
        /// <br/>            (branch, change, client, depot, group, job, jobspec,
        /// <br/>            protect, triggers, typemap, and user) in special,
        /// <br/>            read-only files.  The files are named:
        /// <br/>            //depotname/formtype/name[suffix].  Updates to jobs made
        /// <br/>            by the 'p4 change', 'p4 fix', and 'p4 submit' commands
        /// <br/>            are also saved, but other automatic updates such as
        /// <br/>            as access times or opened files (for changes) are not.
        /// <br/>            A server can contain only one 'spec' depot.
        /// <br/>
        /// <br/>            A 'archive' depot defines a storage location to which
        /// <br/>            obsolete revisions may be relocated.
        /// <br/>
        /// <br/>            An 'unload' depot defines a storage location to which
        /// <br/>            database records may be unloaded and from which they
        /// <br/>            may be reloaded.
        /// <br/>
        /// <br/>   Address:     For remote depots, the $P4PORT (connection address)
        /// <br/>            of the remote server.
        /// <br/>
        /// <br/>   Suffix:      For spec depots, the optional suffix to be used
        /// <br/>            for generated paths. The default is '.p4s'.
        /// <br/>
        /// <br/>   Map:         Path translation information, in the form of a file
        /// <br/>            pattern with a single ... in it.  For local depots,
        /// <br/>            this path is relative to the server's root directory
        /// <br/>            or to server.depot.root if it has been configured
        /// <br/>            (Example: depot/...).  For remote depots, this path
        /// <br/>            refers to the remote server's namespace
        /// <br/>            (Example: //depot/...).
        /// <br/>
        /// <br/>   SpecMap:     For spec depots, the optional description of which
        /// <br/>                specs should be saved, as one or more patterns.
        /// <br/>
        /// <br/>   The -d flag deletes the specified depot.  If any files reside in the
        /// <br/>   depot, they must be removed with 'p4 obliterate' before deleting the
        /// <br/>   depot. If any archive files remain in the depot directory, they may
        /// <br/>   be referenced by lazy copies in other depots; use 'p4 snap' to break
        /// <br/>   those linkages. Snap lazy copies prior to obliterating the old depot
        /// <br/>   files to allow the obliterate command to remove any unreferenced
        /// <br/>   archives from the depot directory. If the depot directory is not
        /// <br/>   empty, you must specify the -f flag to delete the depot.
        /// <br/>
        /// <br/>   The -o flag writes the depot specification to standard output. The
        /// <br/>   user's editor is not invoked.
        /// <br/>
        /// <br/>   The -i flag reads a depot specification from standard input. The
        /// <br/>   user's editor is not invoked.
        /// <br/>
        /// <br/>
        /// </remarks>
        /// <example>
        ///		To get the spec for a streams depot named MobileApp:
        ///		<code>
        ///		    Depot MobileApp = Repository.GetDepot("MobileApp", null);
        ///		</code>
        /// </example>
        /// <seealso cref="DepotCmdFlags"/>
        public Depot GetDepot(string depot, Options options)
        {
            if (depot == null)
            {
                throw new ArgumentNullException("depot");
            }
            P4Command cmd = new P4Command(this, "depot", true, depot);

            if (options == null)
            {
                options = new Options(DepotCmdFlags.Output);
            }
            if (options.ContainsKey("-o") == false)
            {
                options["-o"] = null;
            }

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                if ((results.TaggedOutput == null) || (results.TaggedOutput.Count <= 0))
                {
                    return(null);
                }
                Depot value = new Depot();

                value.FromDepotCmdTaggedOutput(results.TaggedOutput[0]);

                return(value);
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }
Exemple #27
0
        /// <summary>
        /// Get a list of jobs from the repository
        /// </summary>
        /// <param name="options">options for the jobs command<see cref="JobsCmdFlags"/></param>
        /// <param name="files">list of files to filter jobs by</param>
        /// <returns>A list containing the matching jobs</returns>
        /// <remarks>
        /// <br/><b>p4 help jobs</b>
        /// <br/>
        /// <br/>     jobs -- Display list of jobs
        /// <br/>
        /// <br/>     p4 jobs [-e jobview -i -l -m max -r] [file[revRange] ...]
        /// <br/>     p4 jobs -R
        /// <br/>
        /// <br/>   Lists jobs in the server. If a file specification is included, fixes
        /// <br/>   for submitted changelists affecting the specified files are listed.
        /// <br/>   The file specification can include wildcards and a revision range.
        /// <br/>    See 'p4 help revisions' for details about specifying revisions.
        /// <br/>
        /// <br/>   The -e flag lists jobs matching the expression specified in the
        /// <br/>   jobview parameter. For a description of jobview syntax, see 'p4 help
        /// <br/>   jobview'.
        /// <br/>
        /// <br/>   The -i flag includes any fixes made by changelists integrated into
        /// <br/>   the specified files.
        /// <br/>
        /// <br/>   The -l flag produces long output with the full text of the job
        /// <br/>   descriptions.
        /// <br/>
        /// <br/>   The -m max flag limits the output to the first 'max' jobs, ordered
        /// <br/>   by their job name.
        /// <br/>
        /// <br/>   The -r flag sorts the jobs in reverse order (by job name).
        /// <br/>
        /// <br/>   The -R flag rebuilds the jobs table and reindexes each job, which
        /// <br/>   is necessary after upgrading to 98.2.  'p4 jobs -R' requires that the
        /// <br/>   user be an operator or have 'super' access granted by 'p4 protect'.
        /// <br/>
        /// <br/>
        /// </remarks>
        /// <example>
        ///
        ///		To get a list of 100 jobs that include files under a given filepath:
        ///		<code>
        ///
        ///         FileSpec path = new FileSpec(new DepotPath(@"//depot/..."), null);
        ///         IList&#60;Job&#62; jobs = rep.GetJobs((new Options(JobsCmdFlags.LongDescriptions, null, 100)), path);
        ///
        ///		</code>
        ///
        ///		To get a list of 100 jobs with the status "open":
        ///		<code>
        ///
        ///         string jobView = "status=open";
        ///         IList&#60;Job&#62; jobs = rep.GetJobs((new Options(JobsCmdFlags.LongDescriptions, jobView, 100)), path);
        ///
        ///		</code>
        ///		To get a list of 10 jobs in reverse order:
        ///     <code>
        ///
        ///        IList&#60;Job&#62; jobs = rep.GetJobs((new Options(JobsCmdFlags.ReverseSort, null, 10));
        ///
        ///		</code>
        ///
        ///     To get a list of 10 jobs that include any fixes made by changelists integrated into
        ///     the specified files:
        ///     <code>
        ///
        ///         FileSpec path = new FileSpec(new DepotPath(@"//depot/..."), null);
        ///         IList&#60;Job&#62; jobs = rep.GetJobs((new Options(JobsCmdFlags.IncludeIntegratedFixes, null, 10)), path);
        ///
        ///     </code>
        ///
        /// </example>
        /// <seealso cref="JobsCmdFlags"/>
        public IList <Job> GetJobs(Options options, params FileSpec[] files)
        {
            P4Command cmd = null;

            if ((files != null) && (files.Length > 0))
            {
                cmd = new P4Command(this, "jobs", true, FileSpec.ToStrings(files));
            }
            else
            {
                cmd = new P4Command(this, "jobs", true);
            }

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                if ((results.TaggedOutput == null) || (results.TaggedOutput.Count <= 0))
                {
                    return(null);
                }
                List <Job> value             = new List <Job>();
                Dictionary <string, Job> map = new Dictionary <string, Job>();
                foreach (TaggedObject obj in results.TaggedOutput)
                {
                    Job job = new Job();
                    job.FromJobCmdTaggedOutput(obj);
                    value.Add(job);
                }
                return(value);
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }
Exemple #28
0
        /// <summary>
        /// Delete a stream from the repository
        /// </summary>
        /// <param name="stream">The stream to be deleted</param>
        /// <param name="options">Only the '-f' flag is valid when deleting an existing stream</param>
        /// <example>
        ///  To delete a locked stream with no child streams or active clients as an admin user:
        ///  <code>
        ///     Stream stream = rep.GetStream("//Rocket/GUI");
        ///     StreamCmdOptions opts = new StreamCmdOptions(StreamCmdFlags.Force,
        ///                                            null, null);
        ///     rep.DeleteStream(stream, opts);
        ///  </code>
        /// </example>
        public void DeleteStream(Stream stream, Options options)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            P4Command cmd = new P4Command(this, "stream", true, stream.Id);

            if (options == null)
            {
                options = new Options((StreamCmdFlags.Delete), null, null);
            }
            if (options.ContainsKey("-d") == false)
            {
                options["-d"] = null;
            }

            P4CommandResult results = cmd.Run(options);

            if (results.Success == false)
            {
                P4Exception.Throw(results.ErrorList);
            }
        }
        /// <summary>
        /// Delete a depot from the repository
        /// </summary>
        /// <param name="depot">The depot to be deleted</param>
        /// <param name="options">Only the '-d' flag is valid when deleting an existing depot</param>
        /// <remarks>
        /// <br/>
        /// <br/><b>p4 help depot</b>
        /// <br/>
        /// <br/>     depot -- Create or edit a depot specification
        /// <br/>
        /// <br/>     p4 depot name
        /// <br/>     p4 depot -d [-f] name
        /// <br/>     p4 depot -o name
        /// <br/>     p4 depot -i
        /// <br/>
        /// <br/>   Create a new depot specification or edit an existing depot
        /// <br/>   specification. The specification form is put into a temporary file
        /// <br/>   and the editor (configured by the environment variable $P4EDITOR)
        /// <br/>   is invoked.
        /// <br/>
        /// <br/>   The depot specification contains the following fields:
        /// <br/>
        /// <br/>   Depot:       The name of the depot.  This name cannot be the same as
        /// <br/>            any branch, client, or label name.
        /// <br/>
        /// <br/>   Owner:       The user who created this depot.
        /// <br/>
        /// <br/>   Date:        The date that this specification was last modified.
        /// <br/>
        /// <br/>   Description: A short description of the depot (optional).
        /// <br/>
        /// <br/>   Type:        One of the types: 'local', 'stream', 'remote', 'spec',
        /// <br/>            'archive', or 'unload'.
        /// <br/>
        /// <br/>            A 'local' depot (the default) is managed directly by
        /// <br/>            the server and its files reside in the server's root
        /// <br/>            directory.
        /// <br/>
        /// <br/>            A 'stream' depot is a local depot dedicated to the
        /// <br/>            storage of files in a stream.
        /// <br/>
        /// <br/>            A 'remote' depot refers to files in another Perforce
        /// <br/>            server.
        /// <br/>
        /// <br/>            A 'spec' depot automatically archives all edited forms
        /// <br/>            (branch, change, client, depot, group, job, jobspec,
        /// <br/>            protect, triggers, typemap, and user) in special,
        /// <br/>            read-only files.  The files are named:
        /// <br/>            //depotname/formtype/name[suffix].  Updates to jobs made
        /// <br/>            by the 'p4 change', 'p4 fix', and 'p4 submit' commands
        /// <br/>            are also saved, but other automatic updates such as
        /// <br/>            as access times or opened files (for changes) are not.
        /// <br/>            A server can contain only one 'spec' depot.
        /// <br/>
        /// <br/>            A 'archive' depot defines a storage location to which
        /// <br/>            obsolete revisions may be relocated.
        /// <br/>
        /// <br/>            An 'unload' depot defines a storage location to which
        /// <br/>            database records may be unloaded and from which they
        /// <br/>            may be reloaded.
        /// <br/>
        /// <br/>   Address:     For remote depots, the $P4PORT (connection address)
        /// <br/>            of the remote server.
        /// <br/>
        /// <br/>   Suffix:      For spec depots, the optional suffix to be used
        /// <br/>            for generated paths. The default is '.p4s'.
        /// <br/>
        /// <br/>   Map:         Path translation information, in the form of a file
        /// <br/>            pattern with a single ... in it.  For local depots,
        /// <br/>            this path is relative to the server's root directory
        /// <br/>            or to server.depot.root if it has been configured
        /// <br/>            (Example: depot/...).  For remote depots, this path
        /// <br/>            refers to the remote server's namespace
        /// <br/>            (Example: //depot/...).
        /// <br/>
        /// <br/>   SpecMap:     For spec depots, the optional description of which
        /// <br/>                specs should be saved, as one or more patterns.
        /// <br/>
        /// <br/>   The -d flag deletes the specified depot.  If any files reside in the
        /// <br/>   depot, they must be removed with 'p4 obliterate' before deleting the
        /// <br/>   depot. If any archive files remain in the depot directory, they may
        /// <br/>   be referenced by lazy copies in other depots; use 'p4 snap' to break
        /// <br/>   those linkages. Snap lazy copies prior to obliterating the old depot
        /// <br/>   files to allow the obliterate command to remove any unreferenced
        /// <br/>   archives from the depot directory. If the depot directory is not
        /// <br/>   empty, you must specify the -f flag to delete the depot.
        /// <br/>
        /// <br/>   The -o flag writes the depot specification to standard output. The
        /// <br/>   user's editor is not invoked.
        /// <br/>
        /// <br/>   The -i flag reads a depot specification from standard input. The
        /// <br/>   user's editor is not invoked.
        /// <br/>
        /// <br/>
        /// </remarks>
        /// <example>
        ///		To delete a streams depot named MobileApp:
        ///		<code>
        ///		    Depot d = Repository.GetDepot("MobileApp");
        ///
        ///		    Repository.DeleteDepot(d, null);
        ///		</code>
        /// </example>
        /// <seealso cref="DepotCmdFlags"/>
        public void DeleteDepot(Depot depot, Options options)
        {
            if (depot == null)
            {
                throw new ArgumentNullException("depot");
            }
            P4Command cmd = new P4Command(this, "depot", true, depot.Id);

            if (options == null)
            {
                options = new Options(DepotCmdFlags.Delete);
            }
            if (options.ContainsKey("-d") == false)
            {
                options["-d"] = null;
            }

            P4CommandResult results = cmd.Run(options);

            if (results.Success == false)
            {
                P4Exception.Throw(results.ErrorList);
            }
        }
        /// <summary>
        /// Get a list of groups from the repository
        /// </summary>
        /// <param name="options">options for the groups command<see cref="GroupsCmdOptions"/></param>
        /// <param name="groups">groups</param>
        /// <returns>A list containing the matching groups</returns>
        /// <remarks>
        /// <br/><b>p4 help groups</b>
        /// <br/>
        /// <br/>     groups -- List groups (of users)
        /// <br/>
        /// <br/>     p4 groups [-m max] [-v] [group]
        /// <br/>     p4 groups [-m max] [-i [-v]] user | group
        /// <br/>     p4 groups [-m max] [-g | -u | -o] name
        /// <br/>
        /// <br/>   The first form lists all user groups defined in the server, or just
        /// <br/>   the specified group.
        /// <br/>
        /// <br/>   The second form displays subgroup relationships. If a user argument is
        /// <br/>   specified, only groups containing that user are displayed. If a group
        /// <br/>   argument is specified, only groups containing the group are displayed.
        /// <br/>
        /// <br/>   The third form is useful when there are groups and users with the
        /// <br/>   same name, or when requesting all groups owned by a certain user.
        /// <br/>
        /// <br/>   The -i flag also displays groups that the user or group belongs to
        /// <br/>   indirectly by means of membership in subgroups.
        /// <br/>
        /// <br/>   The -m max flag limits output to the specified number of groups.
        /// <br/>
        /// <br/>   The -v flag displays the MaxResults, MaxScanRows, MaxLockTime, and
        /// <br/>   Timeout values for each group that is displayed.
        /// <br/>
        /// <br/>   The -g flag indicates that the 'name' argument is a group.
        /// <br/>
        /// <br/>   The -u flag indicates that the 'name' argument is a user.
        /// <br/>
        /// <br/>   The -o flag indicates that the 'name' argument is an owner.
        /// <br/>
        /// <br/>
        /// </remarks>
        /// <example>
        ///		To get the first 10 groups:
        ///		<code>
        ///
        ///			Options opts = new Options(GroupsCmdFlags.None, 10);
        ///			IList&#60;Group&#62; groups = _repository.getGroups(opts);
        ///
        ///		</code>
        ///		To get all groups that 'Bob' belongs to, including subgroups:
        ///		<code>
        ///
        ///			Options opts = new Options(GroupsCmdFlags.IncludeIndirect, -1);
        ///			IList&#60;Group&#62; groups = _repository.getGroups(opts, "Bob");
        ///
        ///		</code>
        ///		To get all the groups with the MaxResults, MaxScanRows, MaxLockTime, and
        ///		Timeout values for the specified group:
        ///		<code>
        ///
        ///			Options opts = new Options(GroupsCmdFlags.IncludeAllValues, -1);
        ///         IList&#60;Group&#62; groups = _repository.getGroups(opts);
        ///
        ///		</code>
        /// </example>
        /// <seealso cref="GroupsCmdFlags"/>
        public IList <Group> GetGroups(Options options, params string[] groups)
        {
            P4Command cmd = null;

            if ((groups != null) && (groups.Length > 0))
            {
                cmd = new P4Command(this, "groups", true, groups);
            }
            else
            {
                cmd = new P4Command(this, "groups", true);
            }

            P4CommandResult results = cmd.Run(options);

            if (results.Success)
            {
                if ((results.TaggedOutput == null) || (results.TaggedOutput.Count <= 0))
                {
                    return(null);
                }
                List <Group> value             = new List <Group>();
                Dictionary <string, Group> map = new Dictionary <string, Group>();
                foreach (TaggedObject obj in results.TaggedOutput)
                {
                    string groupName = obj["group"];
                    Group  group     = null;
                    if (map.ContainsKey(groupName))
                    {
                        group = map[groupName];
                    }
                    else
                    {
                        group = new Group(groupName);

                        int v = -1;
                        if (obj.ContainsKey("maxResults"))
                        {
                            int.TryParse(obj["maxResults"], out v);
                        }
                        group.MaxResults = v;

                        v = -1;
                        if (obj.ContainsKey("maxScanRows"))
                        {
                            int.TryParse(obj["maxScanRows"], out v);
                        }
                        group.MaxScanRows = v;

                        v = -1;
                        if (obj.ContainsKey("maxLockTime"))
                        {
                            int.TryParse(obj["maxLockTime"], out v);
                        }
                        group.MaxLockTime = v;

                        v = -1;
                        if (obj.ContainsKey("timeout"))
                        {
                            int.TryParse(obj["timeout"], out v);
                        }
                        group.TimeOut = v;

                        v = -1;
                        if (obj.ContainsKey("passTimeout"))
                        {
                            int.TryParse(obj["passTimeout"], out v);
                        }
                        group.MaxResults = v;

                        map[groupName] = group;
                        value.Add(group);
                    }
                    string user = null;
                    if (obj.ContainsKey("user"))
                    {
                        user = obj["user"];
                    }
                    else
                    {
                        // no user name, can't continue
                    }
                    if ((obj.ContainsKey("isUser")) && (obj["isUser"] == "1"))
                    {
                        if (group.UserNames == null)
                        {
                            group.UserNames = new List <string>();
                        }
                        group.UserNames.Add(user);
                    }
                    if ((obj.ContainsKey("isOwner")) && (obj["isOwner"] == "1"))
                    {
                        if (group.OwnerNames == null)
                        {
                            group.OwnerNames = new List <string>();
                        }
                        group.OwnerNames.Add(user);
                    }
                    if ((obj.ContainsKey("isSubGroup")) && (obj["isSubGroup"] == "1"))
                    {
                        if (group.SubGroups == null)
                        {
                            group.SubGroups = new List <string>();
                        }
                        group.SubGroups.Add(user);
                    }
                }
                return(value);
            }
            else
            {
                P4Exception.Throw(results.ErrorList);
            }
            return(null);
        }