diff --git a/README.md b/README.md
index 4e6173d..431908e 100644
--- a/README.md
+++ b/README.md
@@ -58,7 +58,7 @@ stage ("stage-name") {
writeFileToFile destFile: "u/USER/myfile", sourceFile: "myfile.txt", binary: "true"
deleteDataset dsn:"EXAMPLE.DATASET", failOnNotExist:"False"
- deleteDataset dsn:"EXAMPLE.DATASET", member:"MEMBER", failOnNotExist:"True"
+ deleteDataset dsn:"EXAMPLE.DATASET(MEMBER)", failOnNotExist:"True"
deleteDatasetsByMask mask:"EXAMPLE.DATASET.*", failOnNotExist:"False"
}
// ...
@@ -121,19 +121,19 @@ zosmf ("z/os-connection-name") {
### deleteDataset - Represents an action for deleting datasets and members in a declarative style
```groovy
zosmf ("z/os-connection-name") {
- deleteDataset dsn: "EXAMPLE.DATASET", member:"MEMBER", failOnNotExist:"False"
+ deleteDataset dsn: "EXAMPLE.DATASET(MEMBER)", failOnNotExist: false
}
```
**Mandatory Parameters:**
- * ```dsn:"EXAMPLE.DATASET"``` - Sequential or library dataset name for deletion
- * ```member:"MEMBER"``` - Dataset member name for deletion
- * ```failOnNotExist:"False"``` - If the dataset has been deleted and the option is enabled, execution will halt. (Boolean parameter, is set to 'False' by default)
+ * ```dsn:"EXAMPLE.DATASET"``` - Sequential or library dataset name in the form `HLQ.DSNAME` or `HLQ.DSNAME(MEMNAME)`
+**Optional Parameters:**
+ * `failOnNotExist: false` - Fail the execution if the entity does not exist. Boolean parameter, is set to 'false' by default.
**Expected behavior under various deletion scenarios:**
-* To delete a member from the library, the dsn and member parameters must be specified:
+* To delete a member from the library, provide dataset member name in the form `HLQ.DSNAME(MEMNAME)`:
```
- deleteDataset dsn:"EXAMPLE.DATASET", member:"MEMBER", failOnNotExist:"False"
+ deleteDataset dsn:"EXAMPLE.DATASET(MEMBER1)", failOnNotExist: false
```
* You cannot delete a VSAM dataset this way. Otherwise, you will get output similar to:
diff --git a/src/main/kotlin/org/zowe/zdevops/classic/steps/DeleteDatasetStep.kt b/src/main/kotlin/org/zowe/zdevops/classic/steps/DeleteDatasetStep.kt
index 6974e54..239ad72 100644
--- a/src/main/kotlin/org/zowe/zdevops/classic/steps/DeleteDatasetStep.kt
+++ b/src/main/kotlin/org/zowe/zdevops/classic/steps/DeleteDatasetStep.kt
@@ -1,11 +1,15 @@
/*
+ * Copyright (c) 2022-2024 IBA Group.
+ *
* This program and the accompanying materials are made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
- * Copyright IBA Group 2022
+ * Contributors:
+ * IBA Group
+ * Zowe Community
*/
package org.zowe.zdevops.classic.steps
@@ -21,22 +25,19 @@ import org.zowe.kotlinsdk.zowe.client.sdk.core.ZOSConnection
import org.zowe.zdevops.Messages
import org.zowe.zdevops.classic.AbstractBuildStep
import org.zowe.zdevops.logic.deleteDatasetOrMember
-import org.zowe.zdevops.utils.validateDatasetName
-import org.zowe.zdevops.utils.validateMemberName
+import org.zowe.zdevops.utils.validateDsnOrDsnMemberName
class DeleteDatasetStep
/**
* Constructs a new instance of the DeleteDatasetStep.
*
* @param connectionName The name of the z/OS connection to use for deleting the dataset.
- * @param dsn The name of the dataset to delete.
- * @param member The name of the member to delete.
+ * @param dsn The name of the dataset to delete in the form ZOSMFAD.TEST(MEMNAME).
*/
@DataBoundConstructor
constructor(
connectionName: String,
val dsn: String,
- val member: String?,
val failOnNotExist: Boolean = false ,
) : AbstractBuildStep(connectionName) {
@@ -46,7 +47,7 @@ constructor(
listener: BuildListener,
zosConnection: ZOSConnection
) {
- deleteDatasetOrMember(dsn, member, zosConnection, listener, failOnNotExist)
+ deleteDatasetOrMember(dsn, zosConnection, listener, failOnNotExist)
}
@Extension
@@ -54,27 +55,14 @@ constructor(
Companion.DefaultBuildDescriptor(Messages.zdevops_classic_deleteDatasetStep_display_name()) {
/**
- * Checks if the dataset name is valid
+ * Checks if the dataset name or dataset member name is valid
*
- * @param dsn The dataset name
+ * @param dsn The dataset name or dataset member name
* @return FormValidation.ok() if the dataset name is valid, or an error message otherwise
*/
fun doCheckDsn(@QueryParameter dsn: String): FormValidation? {
- return validateDatasetName(dsn)
+ return validateDsnOrDsnMemberName(dsn)
}
- /**
- * Checks if the member name is valid
- *
- * @param member The dataset member name
- * @return FormValidation.ok() if either the member name is valid or is not provided, or an error message otherwise
- */
- fun doCheckMember(@QueryParameter member: String): FormValidation? {
- return if (member.isNotBlank()) {
- validateMemberName(member)
- } else {
- FormValidation.ok()
- }
- }
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/org/zowe/zdevops/declarative/jobs/DeleteDatasetDeclarative.kt b/src/main/kotlin/org/zowe/zdevops/declarative/jobs/DeleteDatasetDeclarative.kt
index fc72a4e..2f15342 100644
--- a/src/main/kotlin/org/zowe/zdevops/declarative/jobs/DeleteDatasetDeclarative.kt
+++ b/src/main/kotlin/org/zowe/zdevops/declarative/jobs/DeleteDatasetDeclarative.kt
@@ -1,11 +1,15 @@
/*
+ * Copyright (c) 2022-2024 IBA Group.
+ *
* This program and the accompanying materials are made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
- * Copyright IBA Group 2022
+ * Contributors:
+ * IBA Group
+ * Zowe Community
*/
package org.zowe.zdevops.declarative.jobs
@@ -38,9 +42,9 @@ import org.zowe.zdevops.logic.deleteDatasetOrMember
* Deleting dataset USER1A.TEST.KSDS with connection 172.20.2.2:10443
* ISRZ002 Deallocation failed - Deallocation failed for data set 'USER1A.TEST.KSDS'
* ```
- * To delete a member from the library, the dsn and member parameters must be specified:
+ * To delete a member from the library, provide dataset member name in the form `HLQ.DSNAME(MEMNAME)`:
* ```
- * deleteDataset dsn:"USER1A.TEST.LIB", member:"MEMBER1"
+ * deleteDataset dsn:"USER1A.TEST.LIB(MEMBER1)"
* ```
* And out will be:
* ```
@@ -57,23 +61,19 @@ import org.zowe.zdevops.logic.deleteDatasetOrMember
* Deleting dataset USER1A.DS.ISUSED.BY.USER with connection 172.20.2.2:10443
* ISRZ002 Data set in use - Data set 'USER1A.DS.ISUSED.BY.USER' in use by another user, try later or enter HELP for a list of jobs and users allocated to 'USER1A.DS.ISUSED.BY.USER'.
* ```
- * It can take 2 params:
- * @param dsn dataset name - sequential or library
- * @param member dataset member name
+ * It takes:
+ * @param dsn dataset name - sequential or library - in the form HLQ.DSNAME or HLQ.DSNAME(MEMNAME) for member
+ * @param failOnNotExist Fail the execution if the entity does not exist
*/
class DeleteDatasetDeclarative @DataBoundConstructor constructor(
) : AbstractZosmfAction() {
private var dsn: String = ""
- private var member: String = ""
private var failOnNotExist: Boolean = false
@DataBoundSetter
fun setDsn(dsn: String) { this.dsn = dsn }
- @DataBoundSetter
- fun setMember(member: String) { this.member = member }
-
@DataBoundSetter
fun setFailOnNotExist(failOnNotExist: Boolean) { this.failOnNotExist = failOnNotExist }
@@ -87,7 +87,7 @@ class DeleteDatasetDeclarative @DataBoundConstructor constructor(
listener: TaskListener,
zosConnection: ZOSConnection
) {
- deleteDatasetOrMember(dsn, member, zosConnection, listener, failOnNotExist)
+ deleteDatasetOrMember(dsn, zosConnection, listener, failOnNotExist)
}
@Symbol("deleteDataset")
diff --git a/src/main/kotlin/org/zowe/zdevops/logic/DeleteOperation.kt b/src/main/kotlin/org/zowe/zdevops/logic/DeleteOperation.kt
index 6048c5f..d3af445 100644
--- a/src/main/kotlin/org/zowe/zdevops/logic/DeleteOperation.kt
+++ b/src/main/kotlin/org/zowe/zdevops/logic/DeleteOperation.kt
@@ -1,11 +1,15 @@
/*
+ * Copyright (c) 2022-2024 IBA Group.
+ *
* This program and the accompanying materials are made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
- * Copyright IBA Group 2022
+ * Contributors:
+ * IBA Group
+ * Zowe Community
*/
package org.zowe.zdevops.logic
@@ -18,6 +22,7 @@ import org.zowe.kotlinsdk.zowe.client.sdk.zosfiles.ZosDsnList
import org.zowe.kotlinsdk.zowe.client.sdk.zosfiles.input.ListParams
import org.zowe.zdevops.declarative.jobs.zMessages
import org.zowe.zdevops.utils.runMFTryCatchWrappedQuery
+import javax.naming.InvalidNameException
private val successMessage: String = zMessages.zdevops_deleting_ds_success()
@@ -59,27 +64,33 @@ fun deleteDatasetsByMask(mask: String, zosConnection: ZOSConnection, listener: T
/**
* Deletes a dataset or member
*
- * @param dsn The dataset name.
- * @param member The member name (optional).
+ * @param dsnWithMemName The dataset name in the form ZOSMFAD.TEST(MEMNAME).
* @param zosConnection The z/OS connection to be used for dataset deletion.
* @param listener The task listener to log information and handle exceptions.
* @throws AbortException If the dataset name is empty or the member name is invalid.
*/
-fun deleteDatasetOrMember(dsn: String, member: String?, zosConnection: ZOSConnection, listener: TaskListener, failOnNotExist: Boolean) {
- if (dsn.isEmpty()) {
+fun deleteDatasetOrMember(dsnWithMemName: String, zosConnection: ZOSConnection, listener: TaskListener, failOnNotExist: Boolean) {
+ if (dsnWithMemName.isEmpty()) {
throw AbortException(zMessages.zdevops_deleting_ds_fail_dsn_param_empty())
}
- val logMessage = if (!member.isNullOrEmpty()) zMessages.zdevops_deleting_ds_member(member, dsn, zosConnection.host, zosConnection.zosmfPort)
- else zMessages.zdevops_deleting_ds(dsn, zosConnection.host, zosConnection.zosmfPort)
+ val dsnMemberPattern = Regex("[\\w#\$@.-]{1,}\\([\\w#\$@]+\\)") //means it's a PDS member
+ var member: String? = null
+ if (dsnWithMemName.contains(dsnMemberPattern)) {
+ member = dsnWithMemName.substringAfter('(').substringBefore(')')
+ }
+ val logMessage = if (!member.isNullOrEmpty()) zMessages.zdevops_deleting_ds_member(dsnWithMemName, zosConnection.host, zosConnection.zosmfPort)
+ else zMessages.zdevops_deleting_ds(dsnWithMemName, zosConnection.host, zosConnection.zosmfPort)
listener.logger.println(logMessage)
try {
if (!member.isNullOrEmpty()) {
isMemberNameValid(member)
- ZosDsn(zosConnection).deleteDsn(dsn, member)
+ ZosDsn(zosConnection).deleteDsn(dsnWithMemName, member)
} else {
- ZosDsn(zosConnection).deleteDsn(dsn)
+ ZosDsn(zosConnection).deleteDsn(dsnWithMemName)
}
listener.logger.println(successMessage)
+ } catch (e: InvalidNameException) {
+ throw e
} catch (doesNotExistEx: Exception) {
if(failOnNotExist) {
throw doesNotExistEx
@@ -97,6 +108,6 @@ fun deleteDatasetOrMember(dsn: String, member: String?, zosConnection: ZOSConnec
*/
private fun isMemberNameValid(member: String) {
if (member.length > 8 || member.isEmpty())
- throw Exception(zMessages.zdevops_member_name_invalid())
+ throw InvalidNameException(zMessages.zdevops_member_name_invalid())
}
diff --git a/src/main/resources/org/zowe/zdevops/Messages.properties b/src/main/resources/org/zowe/zdevops/Messages.properties
index 1f6d285..4350a54 100644
--- a/src/main/resources/org/zowe/zdevops/Messages.properties
+++ b/src/main/resources/org/zowe/zdevops/Messages.properties
@@ -78,7 +78,7 @@ zdevops_declarative_writing_file_fail=Cannot write to Unix file {0}
zdevops_deleting_ds_fail=Cannot perform deletion
zdevops_deleting_ds_fail_dsn_param_empty=Unable to delete: no dsn keyword present
-zdevops_deleting_ds_member=Deleting member {0} from dataset "{1}" with connection {2}:{3}
+zdevops_deleting_ds_member=Deleting member {0} with connection {1}:{2}
zdevops_deleting_ds=Deleting dataset {0} with connection {1}:{2}
zdevops_deleting_ds_by_mask=Deleting datasets that match the mask "{0}"
zdevops_deleting_ds_fail_no_matching_mask=No data sets matching the mask were found
diff --git a/src/main/resources/org/zowe/zdevops/classic/steps/DeleteDatasetStep/config.jelly b/src/main/resources/org/zowe/zdevops/classic/steps/DeleteDatasetStep/config.jelly
index aa711c2..44d0497 100644
--- a/src/main/resources/org/zowe/zdevops/classic/steps/DeleteDatasetStep/config.jelly
+++ b/src/main/resources/org/zowe/zdevops/classic/steps/DeleteDatasetStep/config.jelly
@@ -6,13 +6,10 @@
-
+
-
-
-
-
+
\ No newline at end of file
diff --git a/src/main/resources/org/zowe/zdevops/classic/steps/DeleteDatasetStep/config.properties b/src/main/resources/org/zowe/zdevops/classic/steps/DeleteDatasetStep/config.properties
index ada18a6..b2110cb 100644
--- a/src/main/resources/org/zowe/zdevops/classic/steps/DeleteDatasetStep/config.properties
+++ b/src/main/resources/org/zowe/zdevops/classic/steps/DeleteDatasetStep/config.properties
@@ -1,3 +1,4 @@
zdevops.classic.connection.title=z/OS connection
zdevops.classic.dsn.title=Dataset
-zdevops.classic.member.title=Member (optional)
+zdevops.classic.dsn.desc=Specify a dataset as HLQ.DSNAME or a member name as HLQ.DSNAME(MEMNAME)
+zdevops.classic.failOnNotExist.title=Fail the step if the entity does not exist
diff --git a/src/test/kotlin/org/zowe/zdevops/classic/steps/DeleteDatasetStepSpec.kt b/src/test/kotlin/org/zowe/zdevops/classic/steps/DeleteDatasetStepSpec.kt
index f110b9d..fa8b3f4 100644
--- a/src/test/kotlin/org/zowe/zdevops/classic/steps/DeleteDatasetStepSpec.kt
+++ b/src/test/kotlin/org/zowe/zdevops/classic/steps/DeleteDatasetStepSpec.kt
@@ -87,7 +87,7 @@ class DeleteDatasetStepSpec : ShouldSpec({
)
val deleteDatasetStep = spyk(
- DeleteDatasetStep("test", "TEST.IJMP.DATASET1", member = null)
+ DeleteDatasetStep("test", "TEST.IJMP.DATASET1")
)
deleteDatasetStep.perform(
build,
@@ -130,7 +130,7 @@ class DeleteDatasetStepSpec : ShouldSpec({
)
val deleteDatasetStep = spyk(
- DeleteDatasetStep("test", "TEST.IJMP.DATASET1", member = null, failOnNotExist = false)
+ DeleteDatasetStep("test", "TEST.IJMP.DATASET1", failOnNotExist = false)
)
deleteDatasetStep.perform(
build,
@@ -152,11 +152,5 @@ class DeleteDatasetStepSpec : ShouldSpec({
descriptor.doCheckDsn("") shouldBe FormValidation.error(Messages.zdevops_value_must_not_be_empty_validation())
descriptor.doCheckDsn("MY_DATASET") shouldBe FormValidation.error(Messages.zdevops_dataset_name_is_invalid_validation())
}
-
- should("validate member name") {
- descriptor.doCheckMember("") shouldBe FormValidation.ok()
- descriptor.doCheckMember("@MY_DS") shouldBe FormValidation.warning(Messages.zdevops_member_name_is_invalid_validation())
- descriptor.doCheckMember("DSNAME") shouldBe FormValidation.ok()
- }
}
})
\ No newline at end of file
diff --git a/src/test/kotlin/org/zowe/zdevops/declarative/jobs/DeleteDatasetDeclarativeSpec.kt b/src/test/kotlin/org/zowe/zdevops/declarative/jobs/DeleteDatasetDeclarativeSpec.kt
index e3dab24..a544b80 100644
--- a/src/test/kotlin/org/zowe/zdevops/declarative/jobs/DeleteDatasetDeclarativeSpec.kt
+++ b/src/test/kotlin/org/zowe/zdevops/declarative/jobs/DeleteDatasetDeclarativeSpec.kt
@@ -174,8 +174,7 @@ class DeleteDatasetDeclarativeSpec : ShouldSpec({
val deleteDatasetDecl = spyk(
DeleteDatasetDeclarative()
)
- deleteDatasetDecl.setDsn("test")
- deleteDatasetDecl.setMember("test")
+ deleteDatasetDecl.setDsn("test(test)")
deleteDatasetDecl.perform(
run,
workspace,
@@ -210,8 +209,7 @@ class DeleteDatasetDeclarativeSpec : ShouldSpec({
val deleteDatasetDecl = spyk(
DeleteDatasetDeclarative()
)
- deleteDatasetDecl.setDsn("test")
- deleteDatasetDecl.setMember("testlongmembername")
+ deleteDatasetDecl.setDsn("test(testlongmembername)")
runCatching {
deleteDatasetDecl.perform(
run,