ConnectCommandRunner extends AbstractServerCommandRunner { private DeleteFileResult deleteFile(IClient client, ClientConfig config, DeleteFileAction action) throws P4JavaException { if (LOG.isDebugEnabled()) { LOG.debug("Running delete against the server for " + action.getFile()); } List<IFileSpec> files = FileSpecBuildUtil.escapedForFilePaths(action.getFile()); OpenFileStatus status = new OpenFileStatus(cmd.getFileDetailsForOpenedSpecs(client.getServer(), files, 1000)); status.throwIfError(); if (status.hasDelete()) { LOG.info("Skipping delete on file already open for delete: " + action.getFile()); return new DeleteFileResult( config, P4RemoteFileImpl.createForExtended(status.getDelete()), MessageStatusUtil.getExtendedMessages(status.getFilesWithMessages(), "\n")); } if (status.hasAdd()) { SpecialFileEventMessage.send(project).fileReverted(new SpecialFileEventMessage.SpecialFileEvent( status.getAdd().stream().map(IFileSpec::toString).collect(Collectors.toList()), "File marked as open for add, and delete request reverted the add, but does not alter the on-disk" + " file contents.")); List<IFileSpec> res = cmd.revertFileChangesPreserveFiles(client, new ArrayList<>(status.getAdd())); LOG.info("Reverted files open for add rather than deleting them: " + status.getAdd() + "; results = " + MessageStatusUtil.getMessages(res, "\n")); MessageStatusUtil.throwIfError(res); return new DeleteFileResult(config, P4RemoteFileImpl.createFor(files), MessageStatusUtil.getMessages(res, "\n")); } if (status.hasEdit()) { SpecialFileEventMessage.send(project).fileReverted(new SpecialFileEventMessage.SpecialFileEvent( status.getEdit().stream().map(IFileSpec::toString).collect(Collectors.toList()), "File marked for delete in changelist, so Add request reverted delete but does not alter the " + "on-disk file contents.")); List<IFileSpec> res = cmd.revertFileChangesPreserveFiles(client, new ArrayList<>(status.getEdit())); LOG.info("Reverting files open for edit in preparation for delete: " + action.getFile() + "; results = " + MessageStatusUtil.getMessages(res, "\n")); MessageStatusUtil.throwIfError(res); } if (LOG.isDebugEnabled()) { LOG.debug("Opening " + files + " for delete"); } List<IFileSpec> res = cmd.deleteFiles(client, files, action.getChangelistId()); MessageStatusUtil.throwIf(res, (msg) -> { if (msg.isWarning() || msg.isError()) { LOG.warn("FIXME check if the error message says that the file isn't on the server, and, if so, " + "don't raise this as an error: " + msg.getSubSystem() + "/" + msg.getGeneric() + "/" + msg.getSubCode() + " - " + msg); return true; } return false; }); return new DeleteFileResult(config, P4RemoteFileImpl.createFor(res), MessageStatusUtil.getMessages(res, "\n")); } ConnectCommandRunner(
            @NotNull Project project,
            @NotNull ConnectionManager connectionManager); @Override void disconnect(@NotNull P4ServerName config); @NotNull @Override P4CommandRunner.QueryAnswer<AnnotateFileResult> getFileAnnotation(
            @NotNull ClientConfig config,
            @NotNull final AnnotateFileQuery query); @NotNull @Override P4CommandRunner.QueryAnswer<DescribeChangelistResult> describeChangelist(
            @NotNull OptionalClientServerConfig config,
            @NotNull DescribeChangelistQuery query); @NotNull @Override P4CommandRunner.QueryAnswer<GetJobSpecResult> getJobSpec(
            @NotNull OptionalClientServerConfig config); @NotNull @Override P4CommandRunner.QueryAnswer<ListOpenedFilesChangesResult> listOpenedFilesChanges(@NotNull ClientConfig config,
            @NotNull ListOpenedFilesChangesQuery query); @NotNull @Override P4CommandRunner.QueryAnswer<ListClientsForUserResult> getClientsForUser(
            @NotNull OptionalClientServerConfig config,
            @NotNull ListClientsForUserQuery query); @NotNull @Override P4CommandRunner.QueryAnswer<ListSubmittedChangelistsResult> listSubmittedChangelists(
            @NotNull final ClientConfig config, @NotNull final ListSubmittedChangelistsQuery query); @NotNull @Override P4CommandRunner.QueryAnswer<GetFileContentsResult> getFileContents(
            @NotNull ClientConfig config,
            @NotNull final GetFileContentsQuery query); @NotNull @Override P4CommandRunner.QueryAnswer<ListFileHistoryResult> listFilesHistory(
            @NotNull ClientConfig config,
            @NotNull final ListFileHistoryQuery query); @NotNull @Override P4CommandRunner.QueryAnswer<ListFilesDetailsResult> listFilesDetails(
            @NotNull ClientConfig config,
            @NotNull final ListFilesDetailsQuery query); @NotNull @Override P4CommandRunner.QueryAnswer<ListJobsResult> listJobs(
            @NotNull OptionalClientServerConfig config,
            @NotNull final ListJobsQuery query); @NotNull @Override P4CommandRunner.QueryAnswer<ListLabelsResult> listLabels(
            @NotNull OptionalClientServerConfig config,
            @NotNull final ListLabelsQuery query); @NotNull @Override P4CommandRunner.QueryAnswer<ListUsersResult> listUsers(
            @NotNull OptionalClientServerConfig config,
            @NotNull final ListUsersQuery query); @NotNull @Override P4CommandRunner.QueryAnswer<SwarmConfigResult> getSwarmConfig(
            @NotNull OptionalClientServerConfig config,
            @NotNull final SwarmConfigQuery query);  }
@ExtendWith(TemporaryFolderExtension.class) @Test void deleteFile(TemporaryFolder tmpDir) throws IOException { idea.useInlineThreading(null); MockConfigPart part = new MockConfigPart() .withServerName(server.getRshUrl()) .withUsername(server.getUser()) .withNoPassword() .withClientname("client1"); final ServerConfig serverConfig = ServerConfig.createFrom(part); final ClientConfig clientConfig = ClientConfig.createFrom(serverConfig, part); final File clientRoot = tmpDir.newFile("clientRoot"); final FilePath newFile = VcsUtil.getFilePath(touchFile(clientRoot, "a@b.txt")); final TestableP4RequestErrorHandler errorHandler = new TestableP4RequestErrorHandler(idea.getMockProject()); final List<IFileSpec> specs = FileSpecBuildUtil.forFilePaths(newFile); final P4CommandUtil cmd = new P4CommandUtil(); setupClient(clientConfig, tmpDir, clientRoot, errorHandler) .mapAsync((runner) -> runner.withConnection(clientConfig, (client) -> { List<IFileSpec> msgs = cmd.addFiles(client, specs, null, null, null); MessageStatusUtil.throwIfError(msgs); IChangelist change = client.getServer().getChangelist(IChangelist.DEFAULT); change.setDescription("add initial file"); msgs = cmd.submitChangelist(client, null, null, change, Collections.singletonList(newFile)); MessageStatusUtil.throwIfError(msgs); return runner; }) ) .map((cm) -> new ConnectCommandRunner(idea.getMockProject(), cm)) .futureMap((runner, sink) -> runner.perform(clientConfig, new DeleteFileAction(newFile, new P4ChangelistIdImpl(0, clientConfig.getClientServerRef()))) .whenCompleted(sink::resolve) .whenServerError(sink::reject) ) .whenCompleted((r) -> { assertThat(r, instanceOf(DeleteFileResult.class)); DeleteFileResult res = (DeleteFileResult) r; assertSame(clientConfig, res.getClientConfig()); assertEquals("", res.getMessage()); assertSize(1, res.getFiles()); P4RemoteFile remote = res.getFiles().get(0); assertEquals(" assertEquals(" }) .whenFailed(Assertions::fail); }