diff --git a/api/swagger.yml b/api/swagger.yml index c941675019f..e4d1fc5f51b 100644 --- a/api/swagger.yml +++ b/api/swagger.yml @@ -1742,33 +1742,34 @@ components: type: string PullRequest: - type: object - required: - - id - - status - - creation_date - - title - - author - - description - - source_branch - - destination_branch allOf: - - $ref: '#/components/schemas/PullRequestBasic' - properties: - id: - type: string - creation_date: - type: integer - format: int64 - author: - type: string - source_branch: - type: string - destination_branch: - type: string - commit_id: - type: string - description: the commit id of merged PRs + - $ref: '#/components/schemas/PullRequestBasic' + - required: + - status + - title + - description + - type: object + required: + - id + - creation_date + - author + - source_branch + - destination_branch + properties: + id: + type: string + creation_date: + type: string + format: date-time + author: + type: string + source_branch: + type: string + destination_branch: + type: string + merged_commit_id: + type: string + description: the commit id of merged PRs PullRequestsList: type: object diff --git a/clients/java-legacy/.openapi-generator/FILES b/clients/java-legacy/.openapi-generator/FILES index 8e60cdd4624..1b1387317a6 100644 --- a/clients/java-legacy/.openapi-generator/FILES +++ b/clients/java-legacy/.openapi-generator/FILES @@ -84,6 +84,7 @@ docs/PrepareGCUncommittedRequest.md docs/PrepareGCUncommittedResponse.md docs/PresignMultipartUpload.md docs/PullRequest.md +docs/PullRequestAllOf.md docs/PullRequestBasic.md docs/PullRequestCreation.md docs/PullRequestsList.md @@ -236,6 +237,7 @@ src/main/java/io/lakefs/clients/api/model/PrepareGCUncommittedRequest.java src/main/java/io/lakefs/clients/api/model/PrepareGCUncommittedResponse.java src/main/java/io/lakefs/clients/api/model/PresignMultipartUpload.java src/main/java/io/lakefs/clients/api/model/PullRequest.java +src/main/java/io/lakefs/clients/api/model/PullRequestAllOf.java src/main/java/io/lakefs/clients/api/model/PullRequestBasic.java src/main/java/io/lakefs/clients/api/model/PullRequestCreation.java src/main/java/io/lakefs/clients/api/model/PullRequestsList.java @@ -356,6 +358,7 @@ src/test/java/io/lakefs/clients/api/model/PolicyTest.java src/test/java/io/lakefs/clients/api/model/PrepareGCUncommittedRequestTest.java src/test/java/io/lakefs/clients/api/model/PrepareGCUncommittedResponseTest.java src/test/java/io/lakefs/clients/api/model/PresignMultipartUploadTest.java +src/test/java/io/lakefs/clients/api/model/PullRequestAllOfTest.java src/test/java/io/lakefs/clients/api/model/PullRequestBasicTest.java src/test/java/io/lakefs/clients/api/model/PullRequestCreationTest.java src/test/java/io/lakefs/clients/api/model/PullRequestTest.java diff --git a/clients/java-legacy/README.md b/clients/java-legacy/README.md index 63d45187320..64a2cf31622 100644 --- a/clients/java-legacy/README.md +++ b/clients/java-legacy/README.md @@ -349,6 +349,7 @@ Class | Method | HTTP request | Description - [PrepareGCUncommittedResponse](docs/PrepareGCUncommittedResponse.md) - [PresignMultipartUpload](docs/PresignMultipartUpload.md) - [PullRequest](docs/PullRequest.md) + - [PullRequestAllOf](docs/PullRequestAllOf.md) - [PullRequestBasic](docs/PullRequestBasic.md) - [PullRequestCreation](docs/PullRequestCreation.md) - [PullRequestsList](docs/PullRequestsList.md) diff --git a/clients/java-legacy/api/openapi.yaml b/clients/java-legacy/api/openapi.yaml index 227fe8eab9f..d3762515863 100644 --- a/clients/java-legacy/api/openapi.yaml +++ b/clients/java-legacy/api/openapi.yaml @@ -9605,38 +9605,11 @@ components: PullRequest: allOf: - $ref: '#/components/schemas/PullRequestBasic' - example: - author: author - destination_branch: destination_branch - id: id - creation_date: 0 - commit_id: commit_id - source_branch: source_branch - properties: - id: - type: string - creation_date: - format: int64 - type: integer - author: - type: string - source_branch: - type: string - destination_branch: - type: string - commit_id: - description: the commit id of merged PRs - type: string - required: - - author - - creation_date - - description - - destination_branch - - id - - source_branch - - status - - title - type: object + - required: + - description + - status + - title + - $ref: '#/components/schemas/PullRequest_allOf' PullRequestsList: example: pagination: @@ -9645,18 +9618,8 @@ components: next_offset: next_offset results: 0 results: - - author: author - destination_branch: destination_branch - id: id - creation_date: 0 - commit_id: commit_id - source_branch: source_branch - - author: author - destination_branch: destination_branch - id: id - creation_date: 0 - commit_id: commit_id - source_branch: source_branch + - null + - null properties: pagination: $ref: '#/components/schemas/Pagination' @@ -9703,6 +9666,29 @@ components: required: - pattern type: object + PullRequest_allOf: + properties: + id: + type: string + creation_date: + format: date-time + type: string + author: + type: string + source_branch: + type: string + destination_branch: + type: string + merged_commit_id: + description: the commit id of merged PRs + type: string + required: + - author + - creation_date + - destination_branch + - id + - source_branch + type: object securitySchemes: basic_auth: scheme: basic diff --git a/clients/java-legacy/docs/PullRequest.md b/clients/java-legacy/docs/PullRequest.md index 49ff6f9f75a..418c2d1b2b1 100644 --- a/clients/java-legacy/docs/PullRequest.md +++ b/clients/java-legacy/docs/PullRequest.md @@ -7,15 +7,15 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**status** | [**StatusEnum**](#StatusEnum) | | +**title** | **String** | | +**description** | **String** | | **id** | **String** | | -**creationDate** | **Long** | | +**creationDate** | **OffsetDateTime** | | **author** | **String** | | **sourceBranch** | **String** | | **destinationBranch** | **String** | | -**commitId** | **String** | the commit id of merged PRs | [optional] -**status** | [**StatusEnum**](#StatusEnum) | | -**title** | **String** | | -**description** | **String** | | +**mergedCommitId** | **String** | the commit id of merged PRs | [optional] diff --git a/clients/java-legacy/docs/PullRequestAllOf.md b/clients/java-legacy/docs/PullRequestAllOf.md new file mode 100644 index 00000000000..aec08cdc9e5 --- /dev/null +++ b/clients/java-legacy/docs/PullRequestAllOf.md @@ -0,0 +1,18 @@ + + +# PullRequestAllOf + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **String** | | +**creationDate** | **OffsetDateTime** | | +**author** | **String** | | +**sourceBranch** | **String** | | +**destinationBranch** | **String** | | +**mergedCommitId** | **String** | the commit id of merged PRs | [optional] + + + diff --git a/clients/java-legacy/src/main/java/io/lakefs/clients/api/model/PullRequest.java b/clients/java-legacy/src/main/java/io/lakefs/clients/api/model/PullRequest.java index 99cd121e590..6fa1f467127 100644 --- a/clients/java-legacy/src/main/java/io/lakefs/clients/api/model/PullRequest.java +++ b/clients/java-legacy/src/main/java/io/lakefs/clients/api/model/PullRequest.java @@ -20,40 +20,18 @@ import com.google.gson.annotations.SerializedName; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; +import io.lakefs.clients.api.model.PullRequestAllOf; import io.lakefs.clients.api.model.PullRequestBasic; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import java.io.IOException; +import org.threeten.bp.OffsetDateTime; /** * PullRequest */ @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") public class PullRequest { - public static final String SERIALIZED_NAME_ID = "id"; - @SerializedName(SERIALIZED_NAME_ID) - private String id; - - public static final String SERIALIZED_NAME_CREATION_DATE = "creation_date"; - @SerializedName(SERIALIZED_NAME_CREATION_DATE) - private Long creationDate; - - public static final String SERIALIZED_NAME_AUTHOR = "author"; - @SerializedName(SERIALIZED_NAME_AUTHOR) - private String author; - - public static final String SERIALIZED_NAME_SOURCE_BRANCH = "source_branch"; - @SerializedName(SERIALIZED_NAME_SOURCE_BRANCH) - private String sourceBranch; - - public static final String SERIALIZED_NAME_DESTINATION_BRANCH = "destination_branch"; - @SerializedName(SERIALIZED_NAME_DESTINATION_BRANCH) - private String destinationBranch; - - public static final String SERIALIZED_NAME_COMMIT_ID = "commit_id"; - @SerializedName(SERIALIZED_NAME_COMMIT_ID) - private String commitId; - /** * Gets or Sets status */ @@ -115,211 +93,235 @@ public StatusEnum read(final JsonReader jsonReader) throws IOException { @SerializedName(SERIALIZED_NAME_DESCRIPTION) private String description; + public static final String SERIALIZED_NAME_ID = "id"; + @SerializedName(SERIALIZED_NAME_ID) + private String id; - public PullRequest id(String id) { + public static final String SERIALIZED_NAME_CREATION_DATE = "creation_date"; + @SerializedName(SERIALIZED_NAME_CREATION_DATE) + private OffsetDateTime creationDate; + + public static final String SERIALIZED_NAME_AUTHOR = "author"; + @SerializedName(SERIALIZED_NAME_AUTHOR) + private String author; + + public static final String SERIALIZED_NAME_SOURCE_BRANCH = "source_branch"; + @SerializedName(SERIALIZED_NAME_SOURCE_BRANCH) + private String sourceBranch; + + public static final String SERIALIZED_NAME_DESTINATION_BRANCH = "destination_branch"; + @SerializedName(SERIALIZED_NAME_DESTINATION_BRANCH) + private String destinationBranch; + + public static final String SERIALIZED_NAME_MERGED_COMMIT_ID = "merged_commit_id"; + @SerializedName(SERIALIZED_NAME_MERGED_COMMIT_ID) + private String mergedCommitId; + + + public PullRequest status(StatusEnum status) { - this.id = id; + this.status = status; return this; } /** - * Get id - * @return id + * Get status + * @return status **/ @javax.annotation.Nonnull @ApiModelProperty(required = true, value = "") - public String getId() { - return id; + public StatusEnum getStatus() { + return status; } - public void setId(String id) { - this.id = id; + public void setStatus(StatusEnum status) { + this.status = status; } - public PullRequest creationDate(Long creationDate) { + public PullRequest title(String title) { - this.creationDate = creationDate; + this.title = title; return this; } /** - * Get creationDate - * @return creationDate + * Get title + * @return title **/ @javax.annotation.Nonnull @ApiModelProperty(required = true, value = "") - public Long getCreationDate() { - return creationDate; + public String getTitle() { + return title; } - public void setCreationDate(Long creationDate) { - this.creationDate = creationDate; + public void setTitle(String title) { + this.title = title; } - public PullRequest author(String author) { + public PullRequest description(String description) { - this.author = author; + this.description = description; return this; } /** - * Get author - * @return author + * Get description + * @return description **/ @javax.annotation.Nonnull @ApiModelProperty(required = true, value = "") - public String getAuthor() { - return author; + public String getDescription() { + return description; } - public void setAuthor(String author) { - this.author = author; + public void setDescription(String description) { + this.description = description; } - public PullRequest sourceBranch(String sourceBranch) { + public PullRequest id(String id) { - this.sourceBranch = sourceBranch; + this.id = id; return this; } /** - * Get sourceBranch - * @return sourceBranch + * Get id + * @return id **/ @javax.annotation.Nonnull @ApiModelProperty(required = true, value = "") - public String getSourceBranch() { - return sourceBranch; + public String getId() { + return id; } - public void setSourceBranch(String sourceBranch) { - this.sourceBranch = sourceBranch; + public void setId(String id) { + this.id = id; } - public PullRequest destinationBranch(String destinationBranch) { + public PullRequest creationDate(OffsetDateTime creationDate) { - this.destinationBranch = destinationBranch; + this.creationDate = creationDate; return this; } /** - * Get destinationBranch - * @return destinationBranch + * Get creationDate + * @return creationDate **/ @javax.annotation.Nonnull @ApiModelProperty(required = true, value = "") - public String getDestinationBranch() { - return destinationBranch; + public OffsetDateTime getCreationDate() { + return creationDate; } - public void setDestinationBranch(String destinationBranch) { - this.destinationBranch = destinationBranch; + public void setCreationDate(OffsetDateTime creationDate) { + this.creationDate = creationDate; } - public PullRequest commitId(String commitId) { + public PullRequest author(String author) { - this.commitId = commitId; + this.author = author; return this; } /** - * the commit id of merged PRs - * @return commitId + * Get author + * @return author **/ - @javax.annotation.Nullable - @ApiModelProperty(value = "the commit id of merged PRs") + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") - public String getCommitId() { - return commitId; + public String getAuthor() { + return author; } - public void setCommitId(String commitId) { - this.commitId = commitId; + public void setAuthor(String author) { + this.author = author; } - public PullRequest status(StatusEnum status) { + public PullRequest sourceBranch(String sourceBranch) { - this.status = status; + this.sourceBranch = sourceBranch; return this; } /** - * Get status - * @return status + * Get sourceBranch + * @return sourceBranch **/ @javax.annotation.Nonnull @ApiModelProperty(required = true, value = "") - public StatusEnum getStatus() { - return status; + public String getSourceBranch() { + return sourceBranch; } - public void setStatus(StatusEnum status) { - this.status = status; + public void setSourceBranch(String sourceBranch) { + this.sourceBranch = sourceBranch; } - public PullRequest title(String title) { + public PullRequest destinationBranch(String destinationBranch) { - this.title = title; + this.destinationBranch = destinationBranch; return this; } /** - * Get title - * @return title + * Get destinationBranch + * @return destinationBranch **/ @javax.annotation.Nonnull @ApiModelProperty(required = true, value = "") - public String getTitle() { - return title; + public String getDestinationBranch() { + return destinationBranch; } - public void setTitle(String title) { - this.title = title; + public void setDestinationBranch(String destinationBranch) { + this.destinationBranch = destinationBranch; } - public PullRequest description(String description) { + public PullRequest mergedCommitId(String mergedCommitId) { - this.description = description; + this.mergedCommitId = mergedCommitId; return this; } /** - * Get description - * @return description + * the commit id of merged PRs + * @return mergedCommitId **/ - @javax.annotation.Nonnull - @ApiModelProperty(required = true, value = "") + @javax.annotation.Nullable + @ApiModelProperty(value = "the commit id of merged PRs") - public String getDescription() { - return description; + public String getMergedCommitId() { + return mergedCommitId; } - public void setDescription(String description) { - this.description = description; + public void setMergedCommitId(String mergedCommitId) { + this.mergedCommitId = mergedCommitId; } @@ -332,35 +334,35 @@ public boolean equals(Object o) { return false; } PullRequest pullRequest = (PullRequest) o; - return Objects.equals(this.id, pullRequest.id) && + return Objects.equals(this.status, pullRequest.status) && + Objects.equals(this.title, pullRequest.title) && + Objects.equals(this.description, pullRequest.description) && + Objects.equals(this.id, pullRequest.id) && Objects.equals(this.creationDate, pullRequest.creationDate) && Objects.equals(this.author, pullRequest.author) && Objects.equals(this.sourceBranch, pullRequest.sourceBranch) && Objects.equals(this.destinationBranch, pullRequest.destinationBranch) && - Objects.equals(this.commitId, pullRequest.commitId) && - Objects.equals(this.status, pullRequest.status) && - Objects.equals(this.title, pullRequest.title) && - Objects.equals(this.description, pullRequest.description); + Objects.equals(this.mergedCommitId, pullRequest.mergedCommitId); } @Override public int hashCode() { - return Objects.hash(id, creationDate, author, sourceBranch, destinationBranch, commitId, status, title, description); + return Objects.hash(status, title, description, id, creationDate, author, sourceBranch, destinationBranch, mergedCommitId); } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("class PullRequest {\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append(" title: ").append(toIndentedString(title)).append("\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); sb.append(" id: ").append(toIndentedString(id)).append("\n"); sb.append(" creationDate: ").append(toIndentedString(creationDate)).append("\n"); sb.append(" author: ").append(toIndentedString(author)).append("\n"); sb.append(" sourceBranch: ").append(toIndentedString(sourceBranch)).append("\n"); sb.append(" destinationBranch: ").append(toIndentedString(destinationBranch)).append("\n"); - sb.append(" commitId: ").append(toIndentedString(commitId)).append("\n"); - sb.append(" status: ").append(toIndentedString(status)).append("\n"); - sb.append(" title: ").append(toIndentedString(title)).append("\n"); - sb.append(" description: ").append(toIndentedString(description)).append("\n"); + sb.append(" mergedCommitId: ").append(toIndentedString(mergedCommitId)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/clients/java-legacy/src/main/java/io/lakefs/clients/api/model/PullRequestAllOf.java b/clients/java-legacy/src/main/java/io/lakefs/clients/api/model/PullRequestAllOf.java new file mode 100644 index 00000000000..13445a70efa --- /dev/null +++ b/clients/java-legacy/src/main/java/io/lakefs/clients/api/model/PullRequestAllOf.java @@ -0,0 +1,244 @@ +/* + * lakeFS API + * lakeFS HTTP API + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package io.lakefs.clients.api.model; + +import java.util.Objects; +import java.util.Arrays; +import com.google.gson.TypeAdapter; +import com.google.gson.annotations.JsonAdapter; +import com.google.gson.annotations.SerializedName; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.io.IOException; +import org.threeten.bp.OffsetDateTime; + +/** + * PullRequestAllOf + */ +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class PullRequestAllOf { + public static final String SERIALIZED_NAME_ID = "id"; + @SerializedName(SERIALIZED_NAME_ID) + private String id; + + public static final String SERIALIZED_NAME_CREATION_DATE = "creation_date"; + @SerializedName(SERIALIZED_NAME_CREATION_DATE) + private OffsetDateTime creationDate; + + public static final String SERIALIZED_NAME_AUTHOR = "author"; + @SerializedName(SERIALIZED_NAME_AUTHOR) + private String author; + + public static final String SERIALIZED_NAME_SOURCE_BRANCH = "source_branch"; + @SerializedName(SERIALIZED_NAME_SOURCE_BRANCH) + private String sourceBranch; + + public static final String SERIALIZED_NAME_DESTINATION_BRANCH = "destination_branch"; + @SerializedName(SERIALIZED_NAME_DESTINATION_BRANCH) + private String destinationBranch; + + public static final String SERIALIZED_NAME_MERGED_COMMIT_ID = "merged_commit_id"; + @SerializedName(SERIALIZED_NAME_MERGED_COMMIT_ID) + private String mergedCommitId; + + + public PullRequestAllOf id(String id) { + + this.id = id; + return this; + } + + /** + * Get id + * @return id + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + + public String getId() { + return id; + } + + + public void setId(String id) { + this.id = id; + } + + + public PullRequestAllOf creationDate(OffsetDateTime creationDate) { + + this.creationDate = creationDate; + return this; + } + + /** + * Get creationDate + * @return creationDate + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + + public OffsetDateTime getCreationDate() { + return creationDate; + } + + + public void setCreationDate(OffsetDateTime creationDate) { + this.creationDate = creationDate; + } + + + public PullRequestAllOf author(String author) { + + this.author = author; + return this; + } + + /** + * Get author + * @return author + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + + public String getAuthor() { + return author; + } + + + public void setAuthor(String author) { + this.author = author; + } + + + public PullRequestAllOf sourceBranch(String sourceBranch) { + + this.sourceBranch = sourceBranch; + return this; + } + + /** + * Get sourceBranch + * @return sourceBranch + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + + public String getSourceBranch() { + return sourceBranch; + } + + + public void setSourceBranch(String sourceBranch) { + this.sourceBranch = sourceBranch; + } + + + public PullRequestAllOf destinationBranch(String destinationBranch) { + + this.destinationBranch = destinationBranch; + return this; + } + + /** + * Get destinationBranch + * @return destinationBranch + **/ + @javax.annotation.Nonnull + @ApiModelProperty(required = true, value = "") + + public String getDestinationBranch() { + return destinationBranch; + } + + + public void setDestinationBranch(String destinationBranch) { + this.destinationBranch = destinationBranch; + } + + + public PullRequestAllOf mergedCommitId(String mergedCommitId) { + + this.mergedCommitId = mergedCommitId; + return this; + } + + /** + * the commit id of merged PRs + * @return mergedCommitId + **/ + @javax.annotation.Nullable + @ApiModelProperty(value = "the commit id of merged PRs") + + public String getMergedCommitId() { + return mergedCommitId; + } + + + public void setMergedCommitId(String mergedCommitId) { + this.mergedCommitId = mergedCommitId; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PullRequestAllOf pullRequestAllOf = (PullRequestAllOf) o; + return Objects.equals(this.id, pullRequestAllOf.id) && + Objects.equals(this.creationDate, pullRequestAllOf.creationDate) && + Objects.equals(this.author, pullRequestAllOf.author) && + Objects.equals(this.sourceBranch, pullRequestAllOf.sourceBranch) && + Objects.equals(this.destinationBranch, pullRequestAllOf.destinationBranch) && + Objects.equals(this.mergedCommitId, pullRequestAllOf.mergedCommitId); + } + + @Override + public int hashCode() { + return Objects.hash(id, creationDate, author, sourceBranch, destinationBranch, mergedCommitId); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class PullRequestAllOf {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" creationDate: ").append(toIndentedString(creationDate)).append("\n"); + sb.append(" author: ").append(toIndentedString(author)).append("\n"); + sb.append(" sourceBranch: ").append(toIndentedString(sourceBranch)).append("\n"); + sb.append(" destinationBranch: ").append(toIndentedString(destinationBranch)).append("\n"); + sb.append(" mergedCommitId: ").append(toIndentedString(mergedCommitId)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/clients/java-legacy/src/test/java/io/lakefs/clients/api/model/PullRequestAllOfTest.java b/clients/java-legacy/src/test/java/io/lakefs/clients/api/model/PullRequestAllOfTest.java new file mode 100644 index 00000000000..88ff9db3ead --- /dev/null +++ b/clients/java-legacy/src/test/java/io/lakefs/clients/api/model/PullRequestAllOfTest.java @@ -0,0 +1,92 @@ +/* + * lakeFS API + * lakeFS HTTP API + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package io.lakefs.clients.api.model; + +import com.google.gson.TypeAdapter; +import com.google.gson.annotations.JsonAdapter; +import com.google.gson.annotations.SerializedName; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.io.IOException; +import org.threeten.bp.OffsetDateTime; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + + +/** + * Model tests for PullRequestAllOf + */ +public class PullRequestAllOfTest { + private final PullRequestAllOf model = new PullRequestAllOf(); + + /** + * Model tests for PullRequestAllOf + */ + @Test + public void testPullRequestAllOf() { + // TODO: test PullRequestAllOf + } + + /** + * Test the property 'id' + */ + @Test + public void idTest() { + // TODO: test id + } + + /** + * Test the property 'creationDate' + */ + @Test + public void creationDateTest() { + // TODO: test creationDate + } + + /** + * Test the property 'author' + */ + @Test + public void authorTest() { + // TODO: test author + } + + /** + * Test the property 'sourceBranch' + */ + @Test + public void sourceBranchTest() { + // TODO: test sourceBranch + } + + /** + * Test the property 'destinationBranch' + */ + @Test + public void destinationBranchTest() { + // TODO: test destinationBranch + } + + /** + * Test the property 'mergedCommitId' + */ + @Test + public void mergedCommitIdTest() { + // TODO: test mergedCommitId + } + +} diff --git a/clients/java-legacy/src/test/java/io/lakefs/clients/api/model/PullRequestTest.java b/clients/java-legacy/src/test/java/io/lakefs/clients/api/model/PullRequestTest.java index ae56d899e21..cc3c8bc1a86 100644 --- a/clients/java-legacy/src/test/java/io/lakefs/clients/api/model/PullRequestTest.java +++ b/clients/java-legacy/src/test/java/io/lakefs/clients/api/model/PullRequestTest.java @@ -18,10 +18,12 @@ import com.google.gson.annotations.SerializedName; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; +import io.lakefs.clients.api.model.PullRequestAllOf; import io.lakefs.clients.api.model.PullRequestBasic; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import java.io.IOException; +import org.threeten.bp.OffsetDateTime; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; @@ -65,4 +67,52 @@ public void descriptionTest() { // TODO: test description } + /** + * Test the property 'id' + */ + @Test + public void idTest() { + // TODO: test id + } + + /** + * Test the property 'creationDate' + */ + @Test + public void creationDateTest() { + // TODO: test creationDate + } + + /** + * Test the property 'author' + */ + @Test + public void authorTest() { + // TODO: test author + } + + /** + * Test the property 'sourceBranch' + */ + @Test + public void sourceBranchTest() { + // TODO: test sourceBranch + } + + /** + * Test the property 'destinationBranch' + */ + @Test + public void destinationBranchTest() { + // TODO: test destinationBranch + } + + /** + * Test the property 'mergedCommitId' + */ + @Test + public void mergedCommitIdTest() { + // TODO: test mergedCommitId + } + } diff --git a/clients/java/api/openapi.yaml b/clients/java/api/openapi.yaml index 5b5d46cc2ae..2a55db6f9e3 100644 --- a/clients/java/api/openapi.yaml +++ b/clients/java/api/openapi.yaml @@ -9580,38 +9580,32 @@ components: PullRequest: allOf: - $ref: '#/components/schemas/PullRequestBasic' - example: - author: author - destination_branch: destination_branch - id: id - creation_date: 0 - commit_id: commit_id - source_branch: source_branch - properties: - id: - type: string - creation_date: - format: int64 - type: integer - author: - type: string - source_branch: - type: string - destination_branch: - type: string - commit_id: - description: the commit id of merged PRs - type: string - required: - - author - - creation_date - - description - - destination_branch - - id - - source_branch - - status - - title - type: object + - required: + - description + - status + - title + - properties: + id: + type: string + creation_date: + format: date-time + type: string + author: + type: string + source_branch: + type: string + destination_branch: + type: string + merged_commit_id: + description: the commit id of merged PRs + type: string + required: + - author + - creation_date + - destination_branch + - id + - source_branch + type: object PullRequestsList: example: pagination: @@ -9620,18 +9614,8 @@ components: next_offset: next_offset results: 0 results: - - author: author - destination_branch: destination_branch - id: id - creation_date: 0 - commit_id: commit_id - source_branch: source_branch - - author: author - destination_branch: destination_branch - id: id - creation_date: 0 - commit_id: commit_id - source_branch: source_branch + - null + - null properties: pagination: $ref: '#/components/schemas/Pagination' diff --git a/clients/java/docs/PullRequest.md b/clients/java/docs/PullRequest.md index 0101c7424cf..cd723d1a12f 100644 --- a/clients/java/docs/PullRequest.md +++ b/clients/java/docs/PullRequest.md @@ -7,15 +7,15 @@ | Name | Type | Description | Notes | |------------ | ------------- | ------------- | -------------| +|**status** | [**StatusEnum**](#StatusEnum) | | | +|**title** | **String** | | | +|**description** | **String** | | | |**id** | **String** | | | -|**creationDate** | **Long** | | | +|**creationDate** | **OffsetDateTime** | | | |**author** | **String** | | | |**sourceBranch** | **String** | | | |**destinationBranch** | **String** | | | -|**commitId** | **String** | the commit id of merged PRs | [optional] | -|**status** | [**StatusEnum**](#StatusEnum) | | | -|**title** | **String** | | | -|**description** | **String** | | | +|**mergedCommitId** | **String** | the commit id of merged PRs | [optional] | diff --git a/clients/java/src/main/java/io/lakefs/clients/sdk/model/PullRequest.java b/clients/java/src/main/java/io/lakefs/clients/sdk/model/PullRequest.java index 7a606a04097..2e97aa2e765 100644 --- a/clients/java/src/main/java/io/lakefs/clients/sdk/model/PullRequest.java +++ b/clients/java/src/main/java/io/lakefs/clients/sdk/model/PullRequest.java @@ -20,6 +20,7 @@ import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; import java.io.IOException; +import java.time.OffsetDateTime; import java.util.Arrays; import com.google.gson.Gson; @@ -52,30 +53,6 @@ */ @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") public class PullRequest { - public static final String SERIALIZED_NAME_ID = "id"; - @SerializedName(SERIALIZED_NAME_ID) - private String id; - - public static final String SERIALIZED_NAME_CREATION_DATE = "creation_date"; - @SerializedName(SERIALIZED_NAME_CREATION_DATE) - private Long creationDate; - - public static final String SERIALIZED_NAME_AUTHOR = "author"; - @SerializedName(SERIALIZED_NAME_AUTHOR) - private String author; - - public static final String SERIALIZED_NAME_SOURCE_BRANCH = "source_branch"; - @SerializedName(SERIALIZED_NAME_SOURCE_BRANCH) - private String sourceBranch; - - public static final String SERIALIZED_NAME_DESTINATION_BRANCH = "destination_branch"; - @SerializedName(SERIALIZED_NAME_DESTINATION_BRANCH) - private String destinationBranch; - - public static final String SERIALIZED_NAME_COMMIT_ID = "commit_id"; - @SerializedName(SERIALIZED_NAME_COMMIT_ID) - private String commitId; - /** * Gets or Sets status */ @@ -137,9 +114,96 @@ public StatusEnum read(final JsonReader jsonReader) throws IOException { @SerializedName(SERIALIZED_NAME_DESCRIPTION) private String description; + public static final String SERIALIZED_NAME_ID = "id"; + @SerializedName(SERIALIZED_NAME_ID) + private String id; + + public static final String SERIALIZED_NAME_CREATION_DATE = "creation_date"; + @SerializedName(SERIALIZED_NAME_CREATION_DATE) + private OffsetDateTime creationDate; + + public static final String SERIALIZED_NAME_AUTHOR = "author"; + @SerializedName(SERIALIZED_NAME_AUTHOR) + private String author; + + public static final String SERIALIZED_NAME_SOURCE_BRANCH = "source_branch"; + @SerializedName(SERIALIZED_NAME_SOURCE_BRANCH) + private String sourceBranch; + + public static final String SERIALIZED_NAME_DESTINATION_BRANCH = "destination_branch"; + @SerializedName(SERIALIZED_NAME_DESTINATION_BRANCH) + private String destinationBranch; + + public static final String SERIALIZED_NAME_MERGED_COMMIT_ID = "merged_commit_id"; + @SerializedName(SERIALIZED_NAME_MERGED_COMMIT_ID) + private String mergedCommitId; + public PullRequest() { } + public PullRequest status(StatusEnum status) { + + this.status = status; + return this; + } + + /** + * Get status + * @return status + **/ + @javax.annotation.Nonnull + public StatusEnum getStatus() { + return status; + } + + + public void setStatus(StatusEnum status) { + this.status = status; + } + + + public PullRequest title(String title) { + + this.title = title; + return this; + } + + /** + * Get title + * @return title + **/ + @javax.annotation.Nonnull + public String getTitle() { + return title; + } + + + public void setTitle(String title) { + this.title = title; + } + + + public PullRequest description(String description) { + + this.description = description; + return this; + } + + /** + * Get description + * @return description + **/ + @javax.annotation.Nonnull + public String getDescription() { + return description; + } + + + public void setDescription(String description) { + this.description = description; + } + + public PullRequest id(String id) { this.id = id; @@ -161,7 +225,7 @@ public void setId(String id) { } - public PullRequest creationDate(Long creationDate) { + public PullRequest creationDate(OffsetDateTime creationDate) { this.creationDate = creationDate; return this; @@ -172,12 +236,12 @@ public PullRequest creationDate(Long creationDate) { * @return creationDate **/ @javax.annotation.Nonnull - public Long getCreationDate() { + public OffsetDateTime getCreationDate() { return creationDate; } - public void setCreationDate(Long creationDate) { + public void setCreationDate(OffsetDateTime creationDate) { this.creationDate = creationDate; } @@ -245,87 +309,24 @@ public void setDestinationBranch(String destinationBranch) { } - public PullRequest commitId(String commitId) { + public PullRequest mergedCommitId(String mergedCommitId) { - this.commitId = commitId; + this.mergedCommitId = mergedCommitId; return this; } /** * the commit id of merged PRs - * @return commitId + * @return mergedCommitId **/ @javax.annotation.Nullable - public String getCommitId() { - return commitId; - } - - - public void setCommitId(String commitId) { - this.commitId = commitId; - } - - - public PullRequest status(StatusEnum status) { - - this.status = status; - return this; - } - - /** - * Get status - * @return status - **/ - @javax.annotation.Nonnull - public StatusEnum getStatus() { - return status; - } - - - public void setStatus(StatusEnum status) { - this.status = status; + public String getMergedCommitId() { + return mergedCommitId; } - public PullRequest title(String title) { - - this.title = title; - return this; - } - - /** - * Get title - * @return title - **/ - @javax.annotation.Nonnull - public String getTitle() { - return title; - } - - - public void setTitle(String title) { - this.title = title; - } - - - public PullRequest description(String description) { - - this.description = description; - return this; - } - - /** - * Get description - * @return description - **/ - @javax.annotation.Nonnull - public String getDescription() { - return description; - } - - - public void setDescription(String description) { - this.description = description; + public void setMergedCommitId(String mergedCommitId) { + this.mergedCommitId = mergedCommitId; } /** @@ -383,36 +384,36 @@ public boolean equals(Object o) { return false; } PullRequest pullRequest = (PullRequest) o; - return Objects.equals(this.id, pullRequest.id) && + return Objects.equals(this.status, pullRequest.status) && + Objects.equals(this.title, pullRequest.title) && + Objects.equals(this.description, pullRequest.description) && + Objects.equals(this.id, pullRequest.id) && Objects.equals(this.creationDate, pullRequest.creationDate) && Objects.equals(this.author, pullRequest.author) && Objects.equals(this.sourceBranch, pullRequest.sourceBranch) && Objects.equals(this.destinationBranch, pullRequest.destinationBranch) && - Objects.equals(this.commitId, pullRequest.commitId) && - Objects.equals(this.status, pullRequest.status) && - Objects.equals(this.title, pullRequest.title) && - Objects.equals(this.description, pullRequest.description)&& + Objects.equals(this.mergedCommitId, pullRequest.mergedCommitId)&& Objects.equals(this.additionalProperties, pullRequest.additionalProperties); } @Override public int hashCode() { - return Objects.hash(id, creationDate, author, sourceBranch, destinationBranch, commitId, status, title, description, additionalProperties); + return Objects.hash(status, title, description, id, creationDate, author, sourceBranch, destinationBranch, mergedCommitId, additionalProperties); } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("class PullRequest {\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append(" title: ").append(toIndentedString(title)).append("\n"); + sb.append(" description: ").append(toIndentedString(description)).append("\n"); sb.append(" id: ").append(toIndentedString(id)).append("\n"); sb.append(" creationDate: ").append(toIndentedString(creationDate)).append("\n"); sb.append(" author: ").append(toIndentedString(author)).append("\n"); sb.append(" sourceBranch: ").append(toIndentedString(sourceBranch)).append("\n"); sb.append(" destinationBranch: ").append(toIndentedString(destinationBranch)).append("\n"); - sb.append(" commitId: ").append(toIndentedString(commitId)).append("\n"); - sb.append(" status: ").append(toIndentedString(status)).append("\n"); - sb.append(" title: ").append(toIndentedString(title)).append("\n"); - sb.append(" description: ").append(toIndentedString(description)).append("\n"); + sb.append(" mergedCommitId: ").append(toIndentedString(mergedCommitId)).append("\n"); sb.append(" additionalProperties: ").append(toIndentedString(additionalProperties)).append("\n"); sb.append("}"); return sb.toString(); @@ -439,17 +440,23 @@ private String toIndentedString(Object o) { openapiFields.add("status"); openapiFields.add("title"); openapiFields.add("description"); + openapiFields.add("id"); + openapiFields.add("creation_date"); + openapiFields.add("author"); + openapiFields.add("source_branch"); + openapiFields.add("destination_branch"); + openapiFields.add("merged_commit_id"); // a set of required properties/fields (JSON key names) openapiRequiredFields = new HashSet(); + openapiRequiredFields.add("status"); + openapiRequiredFields.add("title"); + openapiRequiredFields.add("description"); openapiRequiredFields.add("id"); openapiRequiredFields.add("creation_date"); openapiRequiredFields.add("author"); openapiRequiredFields.add("source_branch"); openapiRequiredFields.add("destination_branch"); - openapiRequiredFields.add("status"); - openapiRequiredFields.add("title"); - openapiRequiredFields.add("description"); } /** @@ -472,6 +479,15 @@ public static void validateJsonElement(JsonElement jsonElement) throws IOExcepti } } JsonObject jsonObj = jsonElement.getAsJsonObject(); + if (!jsonObj.get("status").isJsonPrimitive()) { + throw new IllegalArgumentException(String.format("Expected the field `status` to be a primitive type in the JSON string but got `%s`", jsonObj.get("status").toString())); + } + if (!jsonObj.get("title").isJsonPrimitive()) { + throw new IllegalArgumentException(String.format("Expected the field `title` to be a primitive type in the JSON string but got `%s`", jsonObj.get("title").toString())); + } + if (!jsonObj.get("description").isJsonPrimitive()) { + throw new IllegalArgumentException(String.format("Expected the field `description` to be a primitive type in the JSON string but got `%s`", jsonObj.get("description").toString())); + } if (!jsonObj.get("id").isJsonPrimitive()) { throw new IllegalArgumentException(String.format("Expected the field `id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("id").toString())); } @@ -484,17 +500,8 @@ public static void validateJsonElement(JsonElement jsonElement) throws IOExcepti if (!jsonObj.get("destination_branch").isJsonPrimitive()) { throw new IllegalArgumentException(String.format("Expected the field `destination_branch` to be a primitive type in the JSON string but got `%s`", jsonObj.get("destination_branch").toString())); } - if ((jsonObj.get("commit_id") != null && !jsonObj.get("commit_id").isJsonNull()) && !jsonObj.get("commit_id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `commit_id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("commit_id").toString())); - } - if (!jsonObj.get("status").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `status` to be a primitive type in the JSON string but got `%s`", jsonObj.get("status").toString())); - } - if (!jsonObj.get("title").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `title` to be a primitive type in the JSON string but got `%s`", jsonObj.get("title").toString())); - } - if (!jsonObj.get("description").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `description` to be a primitive type in the JSON string but got `%s`", jsonObj.get("description").toString())); + if ((jsonObj.get("merged_commit_id") != null && !jsonObj.get("merged_commit_id").isJsonNull()) && !jsonObj.get("merged_commit_id").isJsonPrimitive()) { + throw new IllegalArgumentException(String.format("Expected the field `merged_commit_id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("merged_commit_id").toString())); } } diff --git a/clients/java/src/test/java/io/lakefs/clients/sdk/model/PullRequestTest.java b/clients/java/src/test/java/io/lakefs/clients/sdk/model/PullRequestTest.java index c0a6523d65f..e95ee6a2128 100644 --- a/clients/java/src/test/java/io/lakefs/clients/sdk/model/PullRequestTest.java +++ b/clients/java/src/test/java/io/lakefs/clients/sdk/model/PullRequestTest.java @@ -19,6 +19,7 @@ import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; import java.io.IOException; +import java.time.OffsetDateTime; import java.util.Arrays; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -61,4 +62,52 @@ public void descriptionTest() { // TODO: test description } + /** + * Test the property 'id' + */ + @Test + public void idTest() { + // TODO: test id + } + + /** + * Test the property 'creationDate' + */ + @Test + public void creationDateTest() { + // TODO: test creationDate + } + + /** + * Test the property 'author' + */ + @Test + public void authorTest() { + // TODO: test author + } + + /** + * Test the property 'sourceBranch' + */ + @Test + public void sourceBranchTest() { + // TODO: test sourceBranch + } + + /** + * Test the property 'destinationBranch' + */ + @Test + public void destinationBranchTest() { + // TODO: test destinationBranch + } + + /** + * Test the property 'mergedCommitId' + */ + @Test + public void mergedCommitIdTest() { + // TODO: test mergedCommitId + } + } diff --git a/clients/python-legacy/.openapi-generator/FILES b/clients/python-legacy/.openapi-generator/FILES index 30e7d6e2dc0..ad8ed0ff1fc 100644 --- a/clients/python-legacy/.openapi-generator/FILES +++ b/clients/python-legacy/.openapi-generator/FILES @@ -83,6 +83,7 @@ docs/PrepareGCUncommittedRequest.md docs/PrepareGCUncommittedResponse.md docs/PresignMultipartUpload.md docs/PullRequest.md +docs/PullRequestAllOf.md docs/PullRequestBasic.md docs/PullRequestCreation.md docs/PullRequestsList.md @@ -221,6 +222,7 @@ lakefs_client/model/prepare_gc_uncommitted_request.py lakefs_client/model/prepare_gc_uncommitted_response.py lakefs_client/model/presign_multipart_upload.py lakefs_client/model/pull_request.py +lakefs_client/model/pull_request_all_of.py lakefs_client/model/pull_request_basic.py lakefs_client/model/pull_request_creation.py lakefs_client/model/pull_requests_list.py @@ -348,6 +350,7 @@ test/test_prepare_gc_uncommitted_request.py test/test_prepare_gc_uncommitted_response.py test/test_presign_multipart_upload.py test/test_pull_request.py +test/test_pull_request_all_of.py test/test_pull_request_basic.py test/test_pull_request_creation.py test/test_pull_requests_list.py diff --git a/clients/python-legacy/README.md b/clients/python-legacy/README.md index 1fb7dc3861b..d827b40812c 100644 --- a/clients/python-legacy/README.md +++ b/clients/python-legacy/README.md @@ -332,6 +332,7 @@ Class | Method | HTTP request | Description - [PrepareGCUncommittedResponse](docs/PrepareGCUncommittedResponse.md) - [PresignMultipartUpload](docs/PresignMultipartUpload.md) - [PullRequest](docs/PullRequest.md) + - [PullRequestAllOf](docs/PullRequestAllOf.md) - [PullRequestBasic](docs/PullRequestBasic.md) - [PullRequestCreation](docs/PullRequestCreation.md) - [PullRequestsList](docs/PullRequestsList.md) diff --git a/clients/python-legacy/docs/PullRequest.md b/clients/python-legacy/docs/PullRequest.md index 7f2cb2ad5f3..ed0af57ce86 100644 --- a/clients/python-legacy/docs/PullRequest.md +++ b/clients/python-legacy/docs/PullRequest.md @@ -4,15 +4,15 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**status** | **str** | | +**title** | **str** | | +**description** | **str** | | **id** | **str** | | -**creation_date** | **int** | | +**creation_date** | **datetime** | | **author** | **str** | | **source_branch** | **str** | | **destination_branch** | **str** | | -**status** | **str** | | -**title** | **str** | | -**description** | **str** | | -**commit_id** | **str** | the commit id of merged PRs | [optional] +**merged_commit_id** | **str** | the commit id of merged PRs | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/clients/python-legacy/docs/PullRequestAllOf.md b/clients/python-legacy/docs/PullRequestAllOf.md new file mode 100644 index 00000000000..018f1086c19 --- /dev/null +++ b/clients/python-legacy/docs/PullRequestAllOf.md @@ -0,0 +1,17 @@ +# PullRequestAllOf + + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **str** | | +**creation_date** | **datetime** | | +**author** | **str** | | +**source_branch** | **str** | | +**destination_branch** | **str** | | +**merged_commit_id** | **str** | the commit id of merged PRs | [optional] +**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/clients/python-legacy/lakefs_client/model/pull_request.py b/clients/python-legacy/lakefs_client/model/pull_request.py index f931e05a274..6cf17624d85 100644 --- a/clients/python-legacy/lakefs_client/model/pull_request.py +++ b/clients/python-legacy/lakefs_client/model/pull_request.py @@ -31,7 +31,9 @@ def lazy_import(): + from lakefs_client.model.pull_request_all_of import PullRequestAllOf from lakefs_client.model.pull_request_basic import PullRequestBasic + globals()['PullRequestAllOf'] = PullRequestAllOf globals()['PullRequestBasic'] = PullRequestBasic @@ -93,15 +95,15 @@ def openapi_types(): """ lazy_import() return { + 'status': (str,), # noqa: E501 + 'title': (str,), # noqa: E501 + 'description': (str,), # noqa: E501 'id': (str,), # noqa: E501 - 'creation_date': (int,), # noqa: E501 + 'creation_date': (datetime,), # noqa: E501 'author': (str,), # noqa: E501 'source_branch': (str,), # noqa: E501 'destination_branch': (str,), # noqa: E501 - 'status': (str,), # noqa: E501 - 'title': (str,), # noqa: E501 - 'description': (str,), # noqa: E501 - 'commit_id': (str,), # noqa: E501 + 'merged_commit_id': (str,), # noqa: E501 } @cached_property @@ -110,15 +112,15 @@ def discriminator(): attribute_map = { + 'status': 'status', # noqa: E501 + 'title': 'title', # noqa: E501 + 'description': 'description', # noqa: E501 'id': 'id', # noqa: E501 'creation_date': 'creation_date', # noqa: E501 'author': 'author', # noqa: E501 'source_branch': 'source_branch', # noqa: E501 'destination_branch': 'destination_branch', # noqa: E501 - 'status': 'status', # noqa: E501 - 'title': 'title', # noqa: E501 - 'description': 'description', # noqa: E501 - 'commit_id': 'commit_id', # noqa: E501 + 'merged_commit_id': 'merged_commit_id', # noqa: E501 } read_only_vars = { @@ -130,14 +132,14 @@ def _from_openapi_data(cls, *args, **kwargs): # noqa: E501 """PullRequest - a model defined in OpenAPI Keyword Args: + status (str): + title (str): + description (str): id (str): - creation_date (int): + creation_date (datetime): author (str): source_branch (str): destination_branch (str): - status (str): - title (str): - description (str): _check_type (bool): if True, values for parameters in openapi_types will be type checked and a TypeError will be raised if the wrong type is input. @@ -168,7 +170,7 @@ def _from_openapi_data(cls, *args, **kwargs): # noqa: E501 Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) - commit_id (str): the commit id of merged PRs. [optional] # noqa: E501 + merged_commit_id (str): the commit id of merged PRs. [optional] # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) @@ -238,14 +240,14 @@ def __init__(self, *args, **kwargs): # noqa: E501 """PullRequest - a model defined in OpenAPI Keyword Args: + status (str): + title (str): + description (str): id (str): - creation_date (int): + creation_date (datetime): author (str): source_branch (str): destination_branch (str): - status (str): - title (str): - description (str): _check_type (bool): if True, values for parameters in openapi_types will be type checked and a TypeError will be raised if the wrong type is input. @@ -276,7 +278,7 @@ def __init__(self, *args, **kwargs): # noqa: E501 Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) - commit_id (str): the commit id of merged PRs. [optional] # noqa: E501 + merged_commit_id (str): the commit id of merged PRs. [optional] # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) @@ -342,6 +344,7 @@ def _composed_schemas(): 'anyOf': [ ], 'allOf': [ + PullRequestAllOf, PullRequestBasic, ], 'oneOf': [ diff --git a/clients/python-legacy/lakefs_client/model/pull_request_all_of.py b/clients/python-legacy/lakefs_client/model/pull_request_all_of.py new file mode 100644 index 00000000000..b03279de188 --- /dev/null +++ b/clients/python-legacy/lakefs_client/model/pull_request_all_of.py @@ -0,0 +1,290 @@ +""" + lakeFS API + + lakeFS HTTP API # noqa: E501 + + The version of the OpenAPI document: 1.0.0 + Contact: services@treeverse.io + Generated by: https://openapi-generator.tech +""" + + +import re # noqa: F401 +import sys # noqa: F401 + +from lakefs_client.model_utils import ( # noqa: F401 + ApiTypeError, + ModelComposed, + ModelNormal, + ModelSimple, + cached_property, + change_keys_js_to_python, + convert_js_args_to_python_args, + date, + datetime, + file_type, + none_type, + validate_get_composed_info, +) +from ..model_utils import OpenApiModel +from lakefs_client.exceptions import ApiAttributeError + + + +class PullRequestAllOf(ModelNormal): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + + Attributes: + allowed_values (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + with a capitalized key describing the allowed value and an allowed + value. These dicts store the allowed enum values. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + discriminator_value_class_map (dict): A dict to go from the discriminator + variable value to the discriminator class name. + validations (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + that stores validations for max_length, min_length, max_items, + min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum, + inclusive_minimum, and regex. + additional_properties_type (tuple): A tuple of classes accepted + as additional properties values. + """ + + allowed_values = { + } + + validations = { + } + + @cached_property + def additional_properties_type(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + """ + return (bool, date, datetime, dict, float, int, list, str, none_type,) # noqa: E501 + + _nullable = False + + @cached_property + def openapi_types(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + + Returns + openapi_types (dict): The key is attribute name + and the value is attribute type. + """ + return { + 'id': (str,), # noqa: E501 + 'creation_date': (datetime,), # noqa: E501 + 'author': (str,), # noqa: E501 + 'source_branch': (str,), # noqa: E501 + 'destination_branch': (str,), # noqa: E501 + 'merged_commit_id': (str,), # noqa: E501 + } + + @cached_property + def discriminator(): + return None + + + attribute_map = { + 'id': 'id', # noqa: E501 + 'creation_date': 'creation_date', # noqa: E501 + 'author': 'author', # noqa: E501 + 'source_branch': 'source_branch', # noqa: E501 + 'destination_branch': 'destination_branch', # noqa: E501 + 'merged_commit_id': 'merged_commit_id', # noqa: E501 + } + + read_only_vars = { + } + + _composed_schemas = {} + + @classmethod + @convert_js_args_to_python_args + def _from_openapi_data(cls, id, creation_date, author, source_branch, destination_branch, *args, **kwargs): # noqa: E501 + """PullRequestAllOf - a model defined in OpenAPI + + Args: + id (str): + creation_date (datetime): + author (str): + source_branch (str): + destination_branch (str): + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + merged_commit_id (str): the commit id of merged PRs. [optional] # noqa: E501 + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + self = super(OpenApiModel, cls).__new__(cls) + + if args: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + self.id = id + self.creation_date = creation_date + self.author = author + self.source_branch = source_branch + self.destination_branch = destination_branch + for var_name, var_value in kwargs.items(): + if var_name not in self.attribute_map and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self.additional_properties_type is None: + # discard variable. + continue + setattr(self, var_name, var_value) + return self + + required_properties = set([ + '_data_store', + '_check_type', + '_spec_property_naming', + '_path_to_item', + '_configuration', + '_visited_composed_classes', + ]) + + @convert_js_args_to_python_args + def __init__(self, id, creation_date, author, source_branch, destination_branch, *args, **kwargs): # noqa: E501 + """PullRequestAllOf - a model defined in OpenAPI + + Args: + id (str): + creation_date (datetime): + author (str): + source_branch (str): + destination_branch (str): + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + merged_commit_id (str): the commit id of merged PRs. [optional] # noqa: E501 + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + if args: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + self.id = id + self.creation_date = creation_date + self.author = author + self.source_branch = source_branch + self.destination_branch = destination_branch + for var_name, var_value in kwargs.items(): + if var_name not in self.attribute_map and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self.additional_properties_type is None: + # discard variable. + continue + setattr(self, var_name, var_value) + if var_name in self.read_only_vars: + raise ApiAttributeError(f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate " + f"class with read only attributes.") diff --git a/clients/python-legacy/lakefs_client/models/__init__.py b/clients/python-legacy/lakefs_client/models/__init__.py index 0ba85ae7ab1..66a5ba379d0 100644 --- a/clients/python-legacy/lakefs_client/models/__init__.py +++ b/clients/python-legacy/lakefs_client/models/__init__.py @@ -78,6 +78,7 @@ from lakefs_client.model.prepare_gc_uncommitted_response import PrepareGCUncommittedResponse from lakefs_client.model.presign_multipart_upload import PresignMultipartUpload from lakefs_client.model.pull_request import PullRequest +from lakefs_client.model.pull_request_all_of import PullRequestAllOf from lakefs_client.model.pull_request_basic import PullRequestBasic from lakefs_client.model.pull_request_creation import PullRequestCreation from lakefs_client.model.pull_requests_list import PullRequestsList diff --git a/clients/python-legacy/test/test_pull_request.py b/clients/python-legacy/test/test_pull_request.py index ee0eabab131..b38afd65b0b 100644 --- a/clients/python-legacy/test/test_pull_request.py +++ b/clients/python-legacy/test/test_pull_request.py @@ -13,7 +13,9 @@ import unittest import lakefs_client +from lakefs_client.model.pull_request_all_of import PullRequestAllOf from lakefs_client.model.pull_request_basic import PullRequestBasic +globals()['PullRequestAllOf'] = PullRequestAllOf globals()['PullRequestBasic'] = PullRequestBasic from lakefs_client.model.pull_request import PullRequest diff --git a/clients/python-legacy/test/test_pull_request_all_of.py b/clients/python-legacy/test/test_pull_request_all_of.py new file mode 100644 index 00000000000..305c9362589 --- /dev/null +++ b/clients/python-legacy/test/test_pull_request_all_of.py @@ -0,0 +1,36 @@ +""" + lakeFS API + + lakeFS HTTP API # noqa: E501 + + The version of the OpenAPI document: 1.0.0 + Contact: services@treeverse.io + Generated by: https://openapi-generator.tech +""" + + +import sys +import unittest + +import lakefs_client +from lakefs_client.model.pull_request_all_of import PullRequestAllOf + + +class TestPullRequestAllOf(unittest.TestCase): + """PullRequestAllOf unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def testPullRequestAllOf(self): + """Test PullRequestAllOf""" + # FIXME: construct object with mandatory attributes with example values + # model = PullRequestAllOf() # noqa: E501 + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/clients/python/docs/PullRequest.md b/clients/python/docs/PullRequest.md index 00f2c0f4f9a..1142b24a1e7 100644 --- a/clients/python/docs/PullRequest.md +++ b/clients/python/docs/PullRequest.md @@ -5,15 +5,15 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**status** | **str** | | +**title** | **str** | | +**description** | **str** | | **id** | **str** | | -**creation_date** | **int** | | +**creation_date** | **datetime** | | **author** | **str** | | **source_branch** | **str** | | **destination_branch** | **str** | | -**commit_id** | **str** | the commit id of merged PRs | [optional] -**status** | **str** | | -**title** | **str** | | -**description** | **str** | | +**merged_commit_id** | **str** | the commit id of merged PRs | [optional] ## Example diff --git a/clients/python/lakefs_sdk/models/pull_request.py b/clients/python/lakefs_sdk/models/pull_request.py index 69dd08c4ed2..49339e4cabe 100644 --- a/clients/python/lakefs_sdk/models/pull_request.py +++ b/clients/python/lakefs_sdk/models/pull_request.py @@ -18,27 +18,27 @@ import re # noqa: F401 import json - +from datetime import datetime from typing import Optional try: - from pydantic.v1 import BaseModel, Field, StrictInt, StrictStr, validator + from pydantic.v1 import BaseModel, Field, StrictStr, validator except ImportError: - from pydantic import BaseModel, Field, StrictInt, StrictStr, validator + from pydantic import BaseModel, Field, StrictStr, validator class PullRequest(BaseModel): """ PullRequest """ + status: StrictStr = Field(...) + title: StrictStr = Field(...) + description: StrictStr = Field(...) id: StrictStr = Field(...) - creation_date: StrictInt = Field(...) + creation_date: datetime = Field(...) author: StrictStr = Field(...) source_branch: StrictStr = Field(...) destination_branch: StrictStr = Field(...) - commit_id: Optional[StrictStr] = Field(None, description="the commit id of merged PRs") - status: StrictStr = Field(...) - title: StrictStr = Field(...) - description: StrictStr = Field(...) - __properties = ["status", "title", "description"] + merged_commit_id: Optional[StrictStr] = Field(None, description="the commit id of merged PRs") + __properties = ["status", "title", "description", "id", "creation_date", "author", "source_branch", "destination_branch", "merged_commit_id"] @validator('status') def status_validate_enum(cls, value): @@ -85,7 +85,13 @@ def from_dict(cls, obj: dict) -> PullRequest: _obj = PullRequest.parse_obj({ "status": obj.get("status"), "title": obj.get("title"), - "description": obj.get("description") + "description": obj.get("description"), + "id": obj.get("id"), + "creation_date": obj.get("creation_date"), + "author": obj.get("author"), + "source_branch": obj.get("source_branch"), + "destination_branch": obj.get("destination_branch"), + "merged_commit_id": obj.get("merged_commit_id") }) return _obj diff --git a/clients/python/test/test_pull_request.py b/clients/python/test/test_pull_request.py index d424b015e2d..af63d4c0498 100644 --- a/clients/python/test/test_pull_request.py +++ b/clients/python/test/test_pull_request.py @@ -39,26 +39,26 @@ def make_instance(self, include_optional): model = lakefs_sdk.models.pull_request.PullRequest() # noqa: E501 if include_optional : return PullRequest( + status = 'open', + title = '', + description = '', id = '', - creation_date = 56, + creation_date = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), author = '', source_branch = '', destination_branch = '', - commit_id = '', - status = 'open', - title = '', - description = '' + merged_commit_id = '' ) else : return PullRequest( + status = 'open', + title = '', + description = '', id = '', - creation_date = 56, + creation_date = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), author = '', source_branch = '', destination_branch = '', - status = 'open', - title = '', - description = '', ) """ diff --git a/clients/python/test/test_pull_requests_list.py b/clients/python/test/test_pull_requests_list.py index 40c39235db8..e0fd4feb5b1 100644 --- a/clients/python/test/test_pull_requests_list.py +++ b/clients/python/test/test_pull_requests_list.py @@ -45,13 +45,7 @@ def make_instance(self, include_optional): results = 0, max_per_page = 0, ), results = [ - lakefs_sdk.models.pull_request.PullRequest( - id = '', - creation_date = 56, - author = '', - source_branch = '', - destination_branch = '', - commit_id = '', ) + null ] ) else : @@ -62,13 +56,7 @@ def make_instance(self, include_optional): results = 0, max_per_page = 0, ), results = [ - lakefs_sdk.models.pull_request.PullRequest( - id = '', - creation_date = 56, - author = '', - source_branch = '', - destination_branch = '', - commit_id = '', ) + null ], ) """ diff --git a/clients/rust/docs/PullRequest.md b/clients/rust/docs/PullRequest.md index 8de195d6192..7c41e4d3795 100644 --- a/clients/rust/docs/PullRequest.md +++ b/clients/rust/docs/PullRequest.md @@ -4,15 +4,15 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**status** | **String** | | +**title** | **String** | | +**description** | **String** | | **id** | **String** | | -**creation_date** | **i64** | | +**creation_date** | **String** | | **author** | **String** | | **source_branch** | **String** | | **destination_branch** | **String** | | -**commit_id** | Option<**String**> | the commit id of merged PRs | [optional] -**status** | **String** | | -**title** | **String** | | -**description** | **String** | | +**merged_commit_id** | Option<**String**> | the commit id of merged PRs | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/clients/rust/src/models/pull_request.rs b/clients/rust/src/models/pull_request.rs index f1c703914bd..7bcb526a522 100644 --- a/clients/rust/src/models/pull_request.rs +++ b/clients/rust/src/models/pull_request.rs @@ -12,10 +12,16 @@ use crate::models; #[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] pub struct PullRequest { + #[serde(rename = "status")] + pub status: Status, + #[serde(rename = "title")] + pub title: String, + #[serde(rename = "description")] + pub description: String, #[serde(rename = "id")] pub id: String, #[serde(rename = "creation_date")] - pub creation_date: i64, + pub creation_date: String, #[serde(rename = "author")] pub author: String, #[serde(rename = "source_branch")] @@ -23,28 +29,22 @@ pub struct PullRequest { #[serde(rename = "destination_branch")] pub destination_branch: String, /// the commit id of merged PRs - #[serde(rename = "commit_id", skip_serializing_if = "Option::is_none")] - pub commit_id: Option, - #[serde(rename = "status")] - pub status: Status, - #[serde(rename = "title")] - pub title: String, - #[serde(rename = "description")] - pub description: String, + #[serde(rename = "merged_commit_id", skip_serializing_if = "Option::is_none")] + pub merged_commit_id: Option, } impl PullRequest { - pub fn new(id: String, creation_date: i64, author: String, source_branch: String, destination_branch: String, status: Status, title: String, description: String) -> PullRequest { + pub fn new(status: Status, title: String, description: String, id: String, creation_date: String, author: String, source_branch: String, destination_branch: String) -> PullRequest { PullRequest { + status, + title, + description, id, creation_date, author, source_branch, destination_branch, - commit_id: None, - status, - title, - description, + merged_commit_id: None, } } } diff --git a/docs/assets/js/swagger.yml b/docs/assets/js/swagger.yml index c941675019f..e4d1fc5f51b 100644 --- a/docs/assets/js/swagger.yml +++ b/docs/assets/js/swagger.yml @@ -1742,33 +1742,34 @@ components: type: string PullRequest: - type: object - required: - - id - - status - - creation_date - - title - - author - - description - - source_branch - - destination_branch allOf: - - $ref: '#/components/schemas/PullRequestBasic' - properties: - id: - type: string - creation_date: - type: integer - format: int64 - author: - type: string - source_branch: - type: string - destination_branch: - type: string - commit_id: - type: string - description: the commit id of merged PRs + - $ref: '#/components/schemas/PullRequestBasic' + - required: + - status + - title + - description + - type: object + required: + - id + - creation_date + - author + - source_branch + - destination_branch + properties: + id: + type: string + creation_date: + type: string + format: date-time + author: + type: string + source_branch: + type: string + destination_branch: + type: string + merged_commit_id: + type: string + description: the commit id of merged PRs PullRequestsList: type: object diff --git a/pkg/api/controller.go b/pkg/api/controller.go index b1f259d3fb0..d06711a86b1 100644 --- a/pkg/api/controller.go +++ b/pkg/api/controller.go @@ -2705,7 +2705,8 @@ func (c *Controller) handleAPIErrorCallback(ctx context.Context, w http.Response errors.Is(err, graveler.ErrInvalidMergeStrategy), errors.Is(err, block.ErrInvalidAddress), errors.Is(err, block.ErrOperationNotSupported), - errors.Is(err, authentication.ErrInvalidRequest): + errors.Is(err, authentication.ErrInvalidRequest), + errors.Is(err, graveler.ErrSameBranch): log.Debug("Bad request") cb(w, r, http.StatusBadRequest, err) @@ -5181,7 +5182,37 @@ func (c *Controller) ListPullRequests(w http.ResponseWriter, r *http.Request, re } func (c *Controller) CreatePullRequest(w http.ResponseWriter, r *http.Request, body apigen.CreatePullRequestJSONRequestBody, repository string) { - writeResponse(w, r, http.StatusNotImplemented, nil) + if !c.authorize(w, r, permissions.Node{ + Permission: permissions.Permission{ + Action: permissions.CreatePullReqeustAction, + Resource: permissions.RepoArn(repository), + }, + }) { + return + } + ctx := r.Context() + c.LogAction(ctx, "create_pull_request", r, repository, body.DestinationBranch, body.SourceBranch) + + user, err := auth.GetUser(ctx) + if c.handleAPIError(ctx, w, r, err) { + return + } + + // TODO (niro): Sanitize title and description! + + pr := &catalog.PullRequest{ + Title: body.Title, + Description: body.Description, + Author: user.Username, + SourceBranch: body.SourceBranch, + DestinationBranch: body.DestinationBranch, + } + pid, err := c.Catalog.CreatePullRequest(ctx, repository, pr) + if c.handleAPIError(ctx, w, r, err) { + return + } + w.WriteHeader(http.StatusCreated) + _, _ = io.WriteString(w, pid) } func (c *Controller) DeletePullRequest(w http.ResponseWriter, r *http.Request, repository string, pullRequestID string) { @@ -5189,7 +5220,34 @@ func (c *Controller) DeletePullRequest(w http.ResponseWriter, r *http.Request, r } func (c *Controller) GetPullRequest(w http.ResponseWriter, r *http.Request, repository string, pullRequestID string) { - writeResponse(w, r, http.StatusNotImplemented, nil) + if !c.authorize(w, r, permissions.Node{ + Permission: permissions.Permission{ + Action: permissions.GetPullReqeustAction, + Resource: permissions.RepoArn(repository), + }, + }) { + return + } + ctx := r.Context() + c.LogAction(ctx, "get_pull_request", r, repository, pullRequestID, "") + pr, err := c.Catalog.GetPullRequest(ctx, repository, pullRequestID) + if c.handleAPIError(ctx, w, r, err) { + return + } + response := apigen.PullRequest{ + PullRequestBasic: apigen.PullRequestBasic{ + Description: swag.String(pr.Description), + Status: swag.String(pr.Status.String()), + Title: swag.String(pr.Title), + }, + Author: pr.Author, + CreationDate: pr.CreationDate, + DestinationBranch: pr.Destination, + Id: pullRequestID, + MergedCommitId: swag.String(pr.MergedCommitID), + SourceBranch: pr.Source, + } + writeResponse(w, r, http.StatusOK, response) } func (c *Controller) UpdatePullRequest(w http.ResponseWriter, r *http.Request, body apigen.UpdatePullRequestJSONRequestBody, repository string, pullRequestID string) { diff --git a/pkg/api/controller_test.go b/pkg/api/controller_test.go index f6ba630cc21..5b726db9e5f 100644 --- a/pkg/api/controller_test.go +++ b/pkg/api/controller_test.go @@ -5252,6 +5252,108 @@ func TestController_CreateCommitRecord(t *testing.T) { }) } +func TestController_CreatePullRequest(t *testing.T) { + clt, deps := setupClientWithAdmin(t) + ctx := context.Background() + repo := testUniqueRepoName() + _, err := deps.catalog.CreateRepository(ctx, repo, onBlock(deps, repo), "main", false) + require.NoError(t, err) + + t.Run("invalid source", func(t *testing.T) { + resp, err := clt.CreatePullRequestWithResponse(ctx, repo, apigen.CreatePullRequestJSONRequestBody{ + Description: "My description", + DestinationBranch: "branch_a", + SourceBranch: "bad$name", + Title: "My title", + }) + require.NoError(t, err) + require.NotNil(t, resp.JSON400) + require.Contains(t, resp.JSON400.Message, "src") + }) + + t.Run("invalid dest", func(t *testing.T) { + resp, err := clt.CreatePullRequestWithResponse(ctx, repo, apigen.CreatePullRequestJSONRequestBody{ + Description: "My description", + DestinationBranch: "bad$name", + SourceBranch: "branch_a", + Title: "My title", + }) + require.NoError(t, err) + require.NotNil(t, resp.JSON400) + require.Contains(t, resp.JSON400.Message, "dest") + }) + + t.Run("no source", func(t *testing.T) { + resp, err := clt.CreatePullRequestWithResponse(ctx, repo, apigen.CreatePullRequestJSONRequestBody{ + Description: "My description", + DestinationBranch: "main", + SourceBranch: "branch_a", + Title: "My title", + }) + require.NoError(t, err) + require.NotNil(t, resp.JSON404) + require.Contains(t, resp.JSON404.Message, "branch not found") + }) + + t.Run("no dest", func(t *testing.T) { + resp, err := clt.CreatePullRequestWithResponse(ctx, repo, apigen.CreatePullRequestJSONRequestBody{ + Description: "My description", + DestinationBranch: "branch_a", + SourceBranch: "main", + Title: "My title", + }) + require.NoError(t, err) + require.NotNil(t, resp.JSON404) + require.Contains(t, resp.JSON404.Message, "branch not found") + }) + + t.Run("same branch", func(t *testing.T) { + resp, err := clt.CreatePullRequestWithResponse(ctx, repo, apigen.CreatePullRequestJSONRequestBody{ + Description: "My description", + DestinationBranch: "main", + SourceBranch: "main", + Title: "My title", + }) + require.NoError(t, err) + require.NotNil(t, resp.JSON400) + require.Contains(t, resp.JSON400.Message, "same branch") + }) + + t.Run("create sanity", func(t *testing.T) { + body := apigen.CreatePullRequestJSONRequestBody{ + Description: "My description", + DestinationBranch: "main", + SourceBranch: "branch_b", + Title: "My title", + } + _, err := clt.CreateBranchWithResponse(ctx, repo, apigen.CreateBranchJSONRequestBody{ + Name: body.SourceBranch, + Source: "main", + }) + + resp, err := clt.CreatePullRequestWithResponse(ctx, repo, body) + require.NoError(t, err) + require.Equal(t, http.StatusCreated, resp.StatusCode()) + pid := resp.Body + + // Get pull request + getResp, err := clt.GetPullRequestWithResponse(ctx, repo, string(pid)) + require.NoError(t, err) + require.NotNil(t, getResp.JSON200) + require.Equal(t, body.Title, swag.StringValue(getResp.JSON200.Title)) + require.Equal(t, body.Description, swag.StringValue(getResp.JSON200.Description)) + require.Equal(t, body.SourceBranch, getResp.JSON200.SourceBranch) + require.Equal(t, body.DestinationBranch, getResp.JSON200.DestinationBranch) + userResp, err := clt.GetCurrentUserWithResponse(ctx) + require.NoError(t, err) + require.NotNil(t, userResp.JSON200) + require.Equal(t, userResp.JSON200.User.Id, getResp.JSON200.Author) + require.Equal(t, "OPEN", swag.StringValue(getResp.JSON200.Status)) + require.Equal(t, "", swag.StringValue(getResp.JSON200.MergedCommitId)) + require.True(t, time.Now().Sub(getResp.JSON200.CreationDate) < 1*time.Minute) + }) +} + // pollRestoreStatus polls the restore status endpoint until the restore is complete or times out. // test will fail in case of error. // will return nil in case of timeout. diff --git a/pkg/auth/base.go b/pkg/auth/base.go index 2cd8428a69e..bf2c5c0a0f8 100644 --- a/pkg/auth/base.go +++ b/pkg/auth/base.go @@ -16,7 +16,7 @@ var ( // without the required ARN. var statementByName = map[string]model.Statement{ "AllAccess": { - Action: []string{"fs:*", "auth:*", "ci:*", "retention:*", "branches:*"}, + Action: []string{"fs:*", "auth:*", "ci:*", "retention:*", "branches:*", "pr:*"}, Effect: model.StatementEffectAllow, }, "FSFullAccess": { @@ -60,6 +60,8 @@ var statementByName = map[string]model.Statement{ "ci:Read*", "retention:Get*", "branches:Get*", + "pr:Get*", + "pr:Read*", permissions.ReadConfigAction, }, @@ -74,6 +76,11 @@ var statementByName = map[string]model.Statement{ }, Effect: model.StatementEffectAllow, }, + "PRReadWrite": { + Action: []string{ + "pr:*", + }, + }, } // GetActionsForPolicyType returns the actions for police type typ. diff --git a/pkg/auth/setup/setup.go b/pkg/auth/setup/setup.go index a73736e811b..9ace1369c17 100644 --- a/pkg/auth/setup/setup.go +++ b/pkg/auth/setup/setup.go @@ -67,6 +67,7 @@ func CreateRBACBasePolicies(ctx context.Context, authService auth.Service, ts ti "ci:*", "retention:*", "branches:*", + "pr:*", "fs:ReadConfig", }, Resource: permissions.All, @@ -74,6 +75,11 @@ func CreateRBACBasePolicies(ctx context.Context, authService auth.Service, ts ti }, }, }, + { + CreatedAt: ts, + DisplayName: "PRReadWriteAll", + Statement: auth.MakeStatementForPolicyTypeOrDie("PRReadWrite", all), + }, { CreatedAt: ts, DisplayName: "RepoManagementReadAll", @@ -137,7 +143,7 @@ func CreateRBACBaseGroups(ctx context.Context, authService auth.Service, ts time if err != nil { return err } - err = attachPolicies(ctx, authService, "Developers", []string{"FSReadWriteAll", "AuthManageOwnCredentials", "RepoManagementReadAll"}) + err = attachPolicies(ctx, authService, "Developers", []string{"FSReadWriteAll", "PRReadWriteAll", "AuthManageOwnCredentials", "RepoManagementReadAll"}) if err != nil { return err } diff --git a/pkg/catalog/catalog.go b/pkg/catalog/catalog.go index 1426b0f6cf9..011ea8dbedb 100644 --- a/pkg/catalog/catalog.go +++ b/pkg/catalog/catalog.go @@ -132,6 +132,7 @@ type Store interface { graveler.Dumper graveler.Loader graveler.Plumbing + graveler.Collaborator } const ( @@ -2871,6 +2872,75 @@ func (c *Catalog) checkCommitIDDuplication(ctx context.Context, repository *grav return err } +func (c *Catalog) GetPullRequest(ctx context.Context, repositoryID string, pullRequestID string) (*graveler.PullRequest, error) { + pid := graveler.PullRequestID(pullRequestID) + if err := validator.Validate([]validator.ValidateArg{ + {Name: "name", Value: repositoryID, Fn: graveler.ValidateRepositoryID}, + {Name: "pullRequestID", Value: pid, Fn: graveler.ValidatePullRequestID}, + }); err != nil { + return nil, err + } + + repository, err := c.getRepository(ctx, repositoryID) + if err != nil { + return nil, err + } + + pr, err := c.Store.GetPullRequest(ctx, repository, pid) + if err != nil { + return nil, err + } + + return pr, nil +} + +func (c *Catalog) CreatePullRequest(ctx context.Context, repositoryID string, request *PullRequest) (string, error) { + srcBranchID := graveler.BranchID(request.SourceBranch) + destBranchID := graveler.BranchID(request.DestinationBranch) + if err := validator.Validate([]validator.ValidateArg{ + {Name: "repository", Value: repositoryID, Fn: graveler.ValidateRepositoryID}, + {Name: "dest", Value: destBranchID, Fn: graveler.ValidateBranchID}, + {Name: "src", Value: srcBranchID, Fn: graveler.ValidateBranchID}, + }); err != nil { + return "", err + } + + // Verify src and dst are different + if srcBranchID == destBranchID { + return "", fmt.Errorf("source and destination branches are the same: %w", graveler.ErrSameBranch) + } + + // Check all entities exist + repository, err := c.getRepository(ctx, repositoryID) + if err != nil { + return "", err + } + if _, err = c.Store.GetBranch(ctx, repository, srcBranchID); err != nil { + return "", err + } + if _, err = c.Store.GetBranch(ctx, repository, destBranchID); err != nil { + return "", err + } + + pullID := graveler.NewRunID() + pull := &graveler.PullRequestRecord{ + ID: graveler.PullRequestID(pullID), + PullRequest: graveler.PullRequest{ + CreationDate: time.Now(), + Title: request.Title, + Author: request.Author, + Description: request.Description, + Source: request.SourceBranch, + Destination: request.DestinationBranch, + }, + } + if err = c.Store.CreatePullRequest(ctx, repository, pull); err != nil { + return "", err + } + + return pullID, nil +} + func newCatalogEntryFromEntry(commonPrefix bool, path string, ent *Entry) DBEntry { b := NewDBEntryBuilder(). CommonLevel(commonPrefix). diff --git a/pkg/catalog/fake_graveler_test.go b/pkg/catalog/fake_graveler_test.go index 3b796f1f188..d922d2e6fa3 100644 --- a/pkg/catalog/fake_graveler_test.go +++ b/pkg/catalog/fake_graveler_test.go @@ -301,6 +301,15 @@ func (g *FakeGraveler) GetStagingToken(_ context.Context, _ *graveler.Repository panic("implement me") } +func (g *FakeGraveler) GetPullRequest(context.Context, *graveler.RepositoryRecord, graveler.PullRequestID) (*graveler.PullRequest, error) { + panic("implement me") +} + +func (g *FakeGraveler) CreatePullRequest(context.Context, *graveler.RepositoryRecord, *graveler.PullRequestRecord) error { + //TODO implement me + panic("implement me") +} + type FakeValueIterator struct { Data []*graveler.ValueRecord Index int diff --git a/pkg/catalog/model.go b/pkg/catalog/model.go index 90394cf8ae5..5649998535c 100644 --- a/pkg/catalog/model.go +++ b/pkg/catalog/model.go @@ -60,6 +60,15 @@ type Tag struct { CommitID string } +type PullRequest struct { + ID string + Title string + Description string + Author string + SourceBranch string + DestinationBranch string +} + // AddressType is the type of an entry address type AddressType int32 diff --git a/pkg/graveler/errors.go b/pkg/graveler/errors.go index d750084390f..657bea3a703 100644 --- a/pkg/graveler/errors.go +++ b/pkg/graveler/errors.go @@ -37,6 +37,7 @@ var ( ErrRepositoryNotFound = fmt.Errorf("repository %w", ErrNotFound) ErrRepositoryInDeletion = errors.New("repository in deletion") ErrBranchNotFound = fmt.Errorf("branch %w", ErrNotFound) + ErrSameBranch = fmt.Errorf("same branch %w", ErrInvalid) ErrTagNotFound = fmt.Errorf("tag %w", ErrNotFound) ErrNoChanges = wrapError(ErrUserVisible, "no changes") ErrConflictFound = wrapError(ErrUserVisible, "conflict found") diff --git a/pkg/graveler/graveler.go b/pkg/graveler/graveler.go index 3096fc8f5b2..a4f86bb2e12 100644 --- a/pkg/graveler/graveler.go +++ b/pkg/graveler/graveler.go @@ -738,6 +738,15 @@ type Loader interface { LoadTags(ctx context.Context, repository *RepositoryRecord, metaRangeID MetaRangeID, opts ...SetOptionsFunc) error } +// Collaborator TODO (niro): This should eventually exist in a separate service +type Collaborator interface { + // GetPullRequest returns pull request by ID + GetPullRequest(ctx context.Context, repository *RepositoryRecord, pullRequestID PullRequestID) (*PullRequest, error) + + // CreatePullRequest creates a pull request on a repository for the given source and destination branches + CreatePullRequest(ctx context.Context, repository *RepositoryRecord, pullRequest *PullRequestRecord) error +} + // Internal structures used by Graveler // xxxIterator used as follows: // ``` @@ -3366,6 +3375,14 @@ func (g *Graveler) DeleteExpiredImports(ctx context.Context, repository *Reposit return g.RefManager.DeleteExpiredImports(ctx, repository) } +func (g *Graveler) GetPullRequest(ctx context.Context, repository *RepositoryRecord, pullRequestID PullRequestID) (*PullRequest, error) { + return g.RefManager.GetPullRequest(ctx, repository, pullRequestID) +} + +func (g *Graveler) CreatePullRequest(ctx context.Context, repository *RepositoryRecord, record *PullRequestRecord) error { + return g.RefManager.CreatePullRequest(ctx, repository, record.ID, &record.PullRequest) +} + func tagsToValueIterator(src TagIterator) ValueIterator { return &tagValueIterator{ src: src, diff --git a/pkg/graveler/mock/graveler.go b/pkg/graveler/mock/graveler.go index 8534a34b407..9f7bb2144ed 100644 --- a/pkg/graveler/mock/graveler.go +++ b/pkg/graveler/mock/graveler.go @@ -1217,6 +1217,58 @@ func (mr *MockLoaderMockRecorder) LoadTags(ctx, repository, metaRangeID interfac return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadTags", reflect.TypeOf((*MockLoader)(nil).LoadTags), varargs...) } +// MockCollaborator is a mock of Collaborator interface. +type MockCollaborator struct { + ctrl *gomock.Controller + recorder *MockCollaboratorMockRecorder +} + +// MockCollaboratorMockRecorder is the mock recorder for MockCollaborator. +type MockCollaboratorMockRecorder struct { + mock *MockCollaborator +} + +// NewMockCollaborator creates a new mock instance. +func NewMockCollaborator(ctrl *gomock.Controller) *MockCollaborator { + mock := &MockCollaborator{ctrl: ctrl} + mock.recorder = &MockCollaboratorMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockCollaborator) EXPECT() *MockCollaboratorMockRecorder { + return m.recorder +} + +// CreatePullRequest mocks base method. +func (m *MockCollaborator) CreatePullRequest(ctx context.Context, repository *graveler.RepositoryRecord, pullRequest *graveler.PullRequestRecord) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreatePullRequest", ctx, repository, pullRequest) + ret0, _ := ret[0].(error) + return ret0 +} + +// CreatePullRequest indicates an expected call of CreatePullRequest. +func (mr *MockCollaboratorMockRecorder) CreatePullRequest(ctx, repository, pullRequest interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreatePullRequest", reflect.TypeOf((*MockCollaborator)(nil).CreatePullRequest), ctx, repository, pullRequest) +} + +// GetPullRequest mocks base method. +func (m *MockCollaborator) GetPullRequest(ctx context.Context, repository *graveler.RepositoryRecord, pullRequestID graveler.PullRequestID) (*graveler.PullRequest, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPullRequest", ctx, repository, pullRequestID) + ret0, _ := ret[0].(*graveler.PullRequest) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPullRequest indicates an expected call of GetPullRequest. +func (mr *MockCollaboratorMockRecorder) GetPullRequest(ctx, repository, pullRequestID interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPullRequest", reflect.TypeOf((*MockCollaborator)(nil).GetPullRequest), ctx, repository, pullRequestID) +} + // MockRepositoryIterator is a mock of RepositoryIterator interface. type MockRepositoryIterator struct { ctrl *gomock.Controller diff --git a/pkg/graveler/validate.go b/pkg/graveler/validate.go index a1e8a44bf11..5b16bbaa264 100644 --- a/pkg/graveler/validate.go +++ b/pkg/graveler/validate.go @@ -3,6 +3,7 @@ package graveler import ( "strings" + "github.com/rs/xid" "github.com/treeverse/lakefs/pkg/validator" ) @@ -79,6 +80,17 @@ func ValidateTagID(v interface{}) error { return nil } +func ValidatePullRequestID(v interface{}) error { + s, ok := v.(PullRequestID) + if !ok { + panic(ErrInvalidType) + } + + // TODO (niro): Any other validations? + _, err := xid.FromString(s.String()) + return err +} + func isControlCodeOrSpace(r rune) bool { const space = 0x20 return r <= space diff --git a/pkg/permissions/actions.gen.go b/pkg/permissions/actions.gen.go index 34d84a96d13..293f1d54da9 100644 --- a/pkg/permissions/actions.gen.go +++ b/pkg/permissions/actions.gen.go @@ -60,4 +60,6 @@ var Actions = []string{ "retention:PrepareGarbageCollectionUncommitted", "branches:GetBranchProtectionRules", "branches:SetBranchProtectionRules", + "pr:GetPullRequest", + "pr:CreatePullRequest", } diff --git a/pkg/permissions/actions.go b/pkg/permissions/actions.go index 3fa70f13f22..51e767f8e85 100644 --- a/pkg/permissions/actions.go +++ b/pkg/permissions/actions.go @@ -71,6 +71,8 @@ const ( PrepareGarbageCollectionUncommittedAction = "retention:PrepareGarbageCollectionUncommitted" GetBranchProtectionRulesAction = "branches:GetBranchProtectionRules" SetBranchProtectionRulesAction = "branches:SetBranchProtectionRules" + GetPullReqeustAction = "pr:GetPullRequest" + CreatePullReqeustAction = "pr:CreatePullRequest" ) var serviceSet = map[string]struct{}{ @@ -79,6 +81,7 @@ var serviceSet = map[string]struct{}{ "ci": {}, "retention": {}, "branches": {}, + "pr": {}, } func IsValidAction(name string) error {