2024-09-17
有些梦想虽然遥不可及,但不是不可能实现。只要我足够的强。 --- 《秦时明月》 · 小学生
English
once again
: 再次
It's again possible
: 再次可行
PowerShell: Export Directory Permission List
To export the user permission list for the first-level subdirectories in D:\Sharing_Data
, you can use PowerShell or the Command Prompt with the icacls
tool. Below are the detailed steps for both methods:
Method 1: Using PowerShell
-
Open PowerShell
- Press
Win + X
, and select Windows PowerShell (Admin) or Windows Terminal (Admin).
- Press
-
Run the following script
# Set the shared directory path
$sharedPath = "D:\Sharing_Data"
# Get first-level subdirectories
$subDirectories = Get-ChildItem -Path $sharedPath -Directory
# Create an empty array to store permission info
$permissionsList = @()
foreach ($dir in $subDirectories) {
# Get the current subdirectory's ACL (Access Control List)
$acl = Get-Acl -Path $dir.FullName
foreach ($access in $acl.Access) {
# Create a custom object to store info
$permission = [PSCustomObject]@{
Directory = $dir.Name
Identity = $access.IdentityReference
FileSystemRights = $access.FileSystemRights
AccessControlType = $access.AccessControlType
}
# Add to the array
$permissionsList += $permission
}
}
# Export to CSV file
$permissionsList | Export-Csv -Path "D:\Sharing_Data_Permissions.csv" -NoTypeInformation -Encoding UTF8
Write-Output "Permission list has been successfully exported to D:\Sharing_Data_Permissions.csv" -
Script Explanation
- Retrieve Subdirectories:
Get-ChildItem -Path $sharedPath -Directory
retrieves all first-level subdirectories underD:\Sharing_Data
. - Retrieve Permissions:
Get-Acl
retrieves the permission info for each subdirectory. - Organize Data: Directory names, users, and permission types are organized into a table format.
- Export to CSV: The organized permission information is exported to
D:\Sharing_Data_Permissions.csv
.
- Retrieve Subdirectories:
-
View the Exported Permission File
You can open the
D:\Sharing_Data_Permissions.csv
file using Excel or any CSV-compatible application for easy viewing and analysis.
Method 2: Using icacls
in Command Prompt
-
Open Command Prompt
- Press
Win + R
, typecmd
, and pressEnter
.
- Press
-
Run the following command
cd /d D:\Sharing_Data
for /D %G in (*) do icacls "%G" >> D:\Sharing_Data_Permissions.txtNote:
- If you are writing this command in a batch file (.bat), replace
%G
with%%G
:for /D %%G in (*) do icacls "%%G" >> D:\Sharing_Data_Permissions.txt
- If you are writing this command in a batch file (.bat), replace
-
Command Explanation
for /D %G in (*)
: Loops through all first-level subdirectories underD:\Sharing_Data
.icacls "%G"
: Retrieves the permission information for each subdirectory.>> D:\Sharing_Data_Permissions.txt
: Appends the permission info toD:\Sharing_Data_Permissions.txt
.
-
View the Exported Permission File
Open the
D:\Sharing_Data_Permissions.txt
file to view the permission list for each subdirectory.
Which Method to Choose?
- The PowerShell method is more flexible and powerful, suitable for scenarios where further processing or analysis of permission data is required.
- The
icacls
method is quick and simple, ideal for rapidly exporting permission information to a text file.
Choose the method that best fits your needs. If you need detailed or formatted permission data, the PowerShell method is recommended.
Additional Tips
- Administrator Privileges: Ensure you run PowerShell or Command Prompt as an administrator to avoid permission issues when reading certain directories.
- Encoding Issues: Use UTF-8 encoding when exporting to a CSV file to prevent Chinese characters from displaying as garbled text.
- Permission Description:
IdentityReference
: Represents the user or user group.FileSystemRights
: Specifies the type of permission, such as read, write, modify, etc.AccessControlType
: Specifies whether the permission is allowed (Allow) or denied (Deny).
Developing a Gradle Plugin
To create a custom Gradle plugin called codegen-jooq-gradle-plugin
with plugin ID org.moonlit.jooq
, which adds default configurations to the gradle-jooq-plugin
, you can follow the steps below. The process includes setting up the plugin project, defining the plugin logic, adding default configurations, and packaging and publishing the plugin.
Below are the detailed steps with code examples:
1. Create the Plugin Project
Start by creating a new Gradle project to develop your plugin.
mkdir codegen-jooq-gradle-plugin
cd codegen-jooq-gradle-plugin
gradle init --type java-gradle-plugin
This will generate a basic structure for your Gradle plugin project.
2. Configure build.gradle
Next, edit the build.gradle
file to add the necessary dependencies and plugin information.
plugins {
id 'java-gradle-plugin'
id 'maven-publish'
id 'java'
}
group = 'org.moonlit'
version = '1.0.0'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.jooq:jooq:3.18.4' // Adjust version as needed
implementation 'nu.studer:gradle-jooq-plugin:5.2.1' // Use the appropriate version of gradle-jooq-plugin
}
gradlePlugin {
plugins {
codegenJooq {
id = 'org.moonlit.jooq'
implementationClass = 'org.moonlit.jooq.CodegenJooqPlugin'
displayName = 'Codegen JOOQ Gradle Plugin'
description = 'A custom Gradle plugin that extends gradle-jooq-plugin with default configurations.'
}
}
}
publishing {
publications {
pluginMaven(MavenPublication) {
from components.java
groupId = 'org.moonlit'
artifactId = 'codegen-jooq-gradle-plugin'
version = '1.0.0'
}
}
repositories {
mavenLocal()
// Add remote repository configuration if needed
// maven {
// url = uri("https://your.repository.url")
// credentials {
// username = project.findProperty("repoUser") ?: ""
// password = project.findProperty("repoPassword") ?: ""
// }
// }
}
}
Explanation:
- The
gradlePlugin
block defines the plugin ID and implementation class. - The
publishing
block configures Maven publishing to allow distribution of the plugin locally or to a remote repository.
3. Implement the Plugin Logic
Now, create the plugin implementation file. In the directory src/main/java/org/moonlit/jooq/
, create CodegenJooqPlugin.java
.
package org.moonlit.jooq;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.jooq.gradle.JooqGenerate;
import nu.studer.gradle.jooq.JooqPluginExtension;
public class CodegenJooqPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
// Apply the original gradle-jooq-plugin
project.getPluginManager().apply("nu.studer.jooq");
// Get the Jooq plugin extension
JooqPluginExtension jooqExtension = project.getExtensions().getByType(JooqPluginExtension.class);
// Set default configurations
jooqExtension.getVersion().convention("3.18.4"); // Default JOOQ version
jooqExtension.generateAll(generate -> {
generate.getInputSchema().convention("public");
generate.getOutputDirectory().convention(new File(project.getBuildDir(), "generated-jooq"));
generate.getGenerator().getName().convention("org.jooq.codegen.DefaultGenerator");
generate.getGenerator().getStrategy().getName().convention("org.jooq.codegen.DefaultGeneratorStrategy");
});
// More default configurations can be added, such as database connection settings
}
}
Explanation:
- This code applies the
gradle-jooq-plugin
and adds default configurations for schema, output directory, and generator strategy.
4. Configure Plugin Metadata
Ensure that the plugin metadata file exists at resources/META-INF/gradle-plugins/org.moonlit.jooq.properties
with the following content:
implementation-class=org.moonlit.jooq.CodegenJooqPlugin
This informs Gradle about the plugin’s implementation class.
5. Package and Publish the Plugin
Local Publishing
To publish the plugin to your local Maven repository for testing:
./gradlew publishToMavenLocal
Remote Publishing
If you want to publish the plugin to Maven Central or another remote repository, ensure that the publishing
block in build.gradle
is correctly configured with credentials and repository URLs.
6. Use the Plugin
To use the plugin in another project, follow these steps:
1. Add Plugin Repository to settings.gradle
If the plugin has been published to Maven Central or another repository, add the repository in settings.gradle
:
pluginManagement {
repositories {
gradlePluginPortal()
mavenLocal()
mavenCentral()
}
}
2. Apply the Plugin in build.gradle
plugins {
id 'org.moonlit.jooq' version '1.0.0'
}
// Minimal configuration needed as default values are pre-configured
jooq {
version = '3.18.4' // Optional, only if you want to override the default version
configurations {
main {
jdbc {
driver = 'org.postgresql.Driver'
url = 'jdbc:postgresql://localhost:5432/mydb'
user = 'username'
password = 'password'
}
generator {
database {
inputSchema = 'public'
}
target {
packageName = 'com.example.jooq'
directory = "${project.buildDir}/generated-jooq"
}
}
}
}
}
3. Generate JOOQ Classes
Run the following command to generate the JOOQ classes:
./gradlew generateJooq
7. Increase Flexibility with Custom Extension
If you want the plugin to be more flexible and allow users to override default configurations, you can modify the plugin as follows:
package org.moonlit.jooq;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import nu.studer.gradle.jooq.JooqPluginExtension;
public class CodegenJooqPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getPluginManager().apply("nu.studer.jooq");
JooqPluginExtension jooqExtension = project.getExtensions().getByType(JooqPluginExtension.class);
jooqExtension.getVersion().convention("3.18.4");
jooqExtension.configurations().all(configuration -> {
configuration.generate(generate -> {
generate.getInputSchema().convention("public");
generate.getOutputDirectory().convention(new File(project.getBuildDir(), "generated-jooq"));
generate.getGenerator().getName().convention("org.jooq.codegen.DefaultGenerator");
});
});
}
}
Explanation:
- Users can override the default configurations as needed in their
build.gradle
file.
8. Version Control and Continuous Integration
To ensure plugin versioning and CI/CD processes:
- Use Git for version control.
- Set up a CI/CD pipeline (e.g., GitHub Actions, GitLab CI) to automate testing and publishing.
- Follow Semantic Versioning (SemVer) to manage plugin versions.
9. Example Project
To help users understand how to use the plugin, create an example project with instructions in the README.md
.
Example Project Structure
example-project/
├── build.gradle
├── settings.gradle
└── src/
└── main/
└── java/
Example build.gradle
plugins {
id 'org.moonlit.jooq' version '1.0.0'
}
repositories {
mavenLocal()
mavenCentral()
}
jooq {
configurations {
main {
jdbc {
driver = 'org.postgresql.Driver'
url = 'jdbc:postgresql://localhost:5432/mydb'
user = 'username'
password = 'password'
}
generator {
database {
inputSchema = 'public'
}
target {
packageName = 'com.example.jooq'
}
}
}
}
}
Summary
By following these steps, you can develop a custom Gradle plugin codegen-jooq-gradle-plugin
that extends gradle-jooq-plugin
with default configurations. Make sure to thoroughly test the plugin during development and provide clear documentation for users to enhance the usability of your plugin.
For more information, you can refer to:
- Gradle Plugin Development Documentation
- gradle-jooq-plugin Documentation
- JOOQ Official Documentation
Testing a Gradle Plugin Project
When developing the codegen-jooq-gradle-plugin
, it's important to test the plugin to ensure it works as expected in different configurations. This guide covers how to configure a testing environment, create test classes, and execute them using Gradle TestKit.
1. Configure the Testing Environment
Start by ensuring that your build.gradle
file contains the necessary dependencies and configuration for testing.
Modify build.gradle
plugins {
id 'java-gradle-plugin'
id 'maven-publish'
id 'java'
}
group = 'org.moonlit'
version = '1.0.0'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.jooq:jooq:3.18.4'
implementation 'nu.studer:gradle-jooq-plugin:5.2.1'
// Testing dependencies
testImplementation gradleTestKit() // For testing the Gradle plugin
testImplementation 'junit:junit:4.13.2' // Using JUnit 4 for testing
// If you want to use JUnit 5:
// testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'
}
gradlePlugin {
plugins {
codegenJooq {
id = 'org.moonlit.jooq'
implementationClass = 'org.moonlit.jooq.CodegenJooqPlugin'
displayName = 'Codegen JOOQ Gradle Plugin'
description = 'A custom Gradle plugin that extends gradle-jooq-plugin with default configurations.'
}
}
}
publishing {
publications {
pluginMaven(MavenPublication) {
from components.java
groupId = 'org.moonlit'
artifactId = 'codegen-jooq-gradle-plugin'
version = '1.0.0'
}
}
repositories {
mavenLocal()
}
}
// Use JUnit 4 for testing
test {
useJUnit()
// If using JUnit 5:
// useJUnitPlatform()
}
Explanation:
- The
testImplementation gradleTestKit()
dependency enables you to use Gradle TestKit for plugin testing. - You can choose between JUnit 4 or JUnit 5 for writing your tests by configuring the corresponding dependencies and
test {}
block.
2. Create a Test Class
Next, you will create a test class that uses Gradle TestKit to validate your plugin's behavior.
Directory Structure
Ensure your project structure looks like this:
codegen-jooq-gradle-plugin/
├── build.gradle
├── settings.gradle
├── src/
│ ├── main/
│ │ └── java/
│ │ └── org/
│ │ └── moonlit/
│ │ └── jooq/
│ │ └── CodegenJooqPlugin.java
│ └── test/
│ └── java/
│ └── org/
│ └── moonlit/
│ └── jooq/
│ └── CodegenJooqPluginTest.java
Writing the Test Class
Create CodegenJooqPluginTest.java
under src/test/java/org/moonlit/jooq/
.
package org.moonlit.jooq;
import org.gradle.testkit.runner.GradleRunner;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import static org.junit.Assert.*;
public class CodegenJooqPluginTest {
@Rule
public final TemporaryFolder testProjectDir = new TemporaryFolder(); // To isolate test environments
private File buildFile;
@Test
public void testPluginAppliesSuccessfully() throws IOException {
// Create a temporary project directory
File projectDir = testProjectDir.getRoot();
// Create a build.gradle file
buildFile = testProjectDir.newFile("build.gradle");
String buildFileContent = "plugins {\n" +
" id 'org.moonlit.jooq'\n" +
"}\n" +
"\n" +
"repositories {\n" +
" mavenCentral()\n" +
"}\n" +
"\n" +
"jooq {\n" +
" configurations {\n" +
" main {\n" +
" jdbc {\n" +
" driver = 'org.h2.Driver'\n" +
" url = 'jdbc:h2:mem:testdb'\n" +
" user = 'sa'\n" +
" password = ''\n" +
" }\n" +
" generator {\n" +
" name = 'org.jooq.codegen.DefaultGenerator'\n" +
" strategy {\n" +
" name = 'org.jooq.codegen.DefaultGeneratorStrategy'\n" +
" }\n" +
" database {\n" +
" name = 'org.jooq.meta.h2.H2Database'\n" +
" inputSchema = 'PUBLIC'\n" +
" }\n" +
" generate {\n" +
" daos = true\n" +
" records = true\n" +
" immutablePojos = true\n" +
" }\n" +
" target {\n" +
" packageName = 'com.example.jooq'\n" +
" directory = '${project.buildDir}/generated-jooq'\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
"}\n";
Files.write(buildFile.toPath(), buildFileContent.getBytes());
// Run the Gradle task
BuildResult result = GradleRunner.create()
.withProjectDir(projectDir)
.withPluginClasspath()
.withArguments("generateJooq")
.build();
// Assert the task succeeded
assertEquals(TaskOutcome.SUCCESS, result.task(":generateJooq").getOutcome());
}
@Test
public void testPluginConfiguration() throws IOException {
// Create another temporary project directory
File projectDir = testProjectDir.getRoot();
// Create a build.gradle file with custom configurations
buildFile = testProjectDir.newFile("build.gradle");
String buildFileContent = "plugins {\n" +
" id 'org.moonlit.jooq'\n" +
"}\n" +
"\n" +
"repositories {\n" +
" mavenCentral()\n" +
"}\n" +
"\n" +
"jooq {\n" +
" configurations {\n" +
" main {\n" +
" jdbc {\n" +
" driver = 'org.h2.Driver'\n" +
" url = 'jdbc:h2:mem:testdb'\n" +
" user = 'sa'\n" +
" password = ''\n" +
" }\n" +
" generator {\n" +
" target {\n" +
" packageName = 'com.custom.jooq'\n" +
" directory = '${project.buildDir}/custom-generated-jooq'\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
"}\n";
Files.write(buildFile.toPath(), buildFileContent.getBytes());
// Run the Gradle task
BuildResult result = GradleRunner.create()
.withProjectDir(projectDir)
.withPluginClasspath()
.withArguments("generateJooq")
.build();
// Assert the task succeeded
assertEquals(TaskOutcome.SUCCESS, result.task(":generateJooq").getOutcome());
// Verify the output directory exists
File generatedDir = new File(projectDir, "build/custom-generated-jooq");
assertTrue(generatedDir.exists());
}
}
Explanation:
TemporaryFolder
ensures that each test has its own isolated directory for creating temporary projects.- testPluginAppliesSuccessfully(): This test verifies that the plugin can be applied successfully and runs the
generateJooq
task. - testPluginConfiguration(): This test checks if the plugin works with custom configurations and verifies the output.
3. Run the Tests
To execute the tests, run the following command from your project root:
./gradlew test
Gradle will run the tests and generate a report in build/reports/tests/test/index.html
.
4. Use JUnit 5 (Optional)
If you prefer JUnit 5 over JUnit 4, you can update your configuration as follows:
Modify build.gradle
dependencies {
implementation 'org.jooq:jooq:3.18.4'
implementation 'nu.studer:gradle-jooq-plugin:5.2.1'
// JUnit 5 dependency
testImplementation gradleTestKit()
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'
}
test {
useJUnitPlatform() // Enable JUnit 5 platform
}
Example JUnit 5 Test Class
package org.moonlit.jooq;
import org.gradle
.testkit.runner.GradleRunner;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import static org.junit.jupiter.api.Assertions.*;
public class CodegenJooqPluginJUnit5Test {
@TempDir
File testProjectDir;
private File buildFile;
@Test
public void testPluginAppliesSuccessfully() throws IOException {
buildFile = new File(testProjectDir, "build.gradle");
String buildFileContent = "plugins {\n" +
" id 'org.moonlit.jooq'\n" +
"}\n" +
"\n" +
"repositories {\n" +
" mavenCentral()\n" +
"}\n" +
"\n" +
"jooq {\n" +
" configurations {\n" +
" main {\n" +
" jdbc {\n" +
" driver = 'org.h2.Driver'\n" +
" url = 'jdbc:h2:mem:testdb'\n" +
" user = 'sa'\n" +
" password = ''\n" +
" }\n" +
" generator {\n" +
" name = 'org.jooq.codegen.DefaultGenerator'\n" +
" strategy {\n" +
" name = 'org.jooq.codegen.DefaultGeneratorStrategy'\n" +
" }\n" +
" database {\n" +
" name = 'org.jooq.meta.h2.H2Database'\n" +
" inputSchema = 'PUBLIC'\n" +
" }\n" +
" generate {\n" +
" daos = true\n" +
" records = true\n" +
" immutablePojos = true\n" +
" }\n" +
" target {\n" +
" packageName = 'com.example.jooq'\n" +
" directory = '${project.buildDir}/generated-jooq'\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
"}\n";
Files.write(buildFile.toPath(), buildFileContent.getBytes());
// Run the Gradle task
BuildResult result = GradleRunner.create()
.withProjectDir(testProjectDir)
.withPluginClasspath()
.withArguments("generateJooq")
.build();
assertEquals(TaskOutcome.SUCCESS, result.task(":generateJooq").getOutcome());
}
}
5. Expand Tests
You can add additional tests to cover more scenarios, such as:
- Default Configuration Tests: Verify that default values are applied correctly when no custom configurations are provided.
- Custom Configuration Tests: Validate that the plugin correctly applies user-provided configurations.
- Error Handling Tests: Ensure the plugin provides helpful error messages when misconfigured.
Example Test for Default Configuration
@Test
public void testDefaultConfiguration() throws IOException {
buildFile = testProjectDir.newFile("build.gradle");
String buildFileContent = "plugins {\n" +
" id 'org.moonlit.jooq'\n" +
"}\n" +
"\n" +
"repositories {\n" +
" mavenCentral()\n" +
"}\n";
Files.write(buildFile.toPath(), buildFileContent.getBytes());
BuildResult result = GradleRunner.create()
.withProjectDir(testProjectDir.getRoot())
.withPluginClasspath()
.withArguments("generateJooq")
.build();
assertEquals(TaskOutcome.SUCCESS, result.task(":generateJooq").getOutcome());
File generatedDir = new File(testProjectDir.getRoot(), "build/generated-jooq");
assertTrue(generatedDir.exists());
}
6. Continuous Integration (CI)
To ensure your plugin works across different environments and code changes, set up a CI pipeline using tools like GitHub Actions. Here's an example GitHub Actions configuration:
GitHub Actions Workflow
Create a .github/workflows/gradle.yml
file:
name: Gradle CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew build
Summary
By following these steps, you can effectively test your Gradle plugin and ensure it works correctly in various scenarios. Key points include:
- Testing Environment: Set up dependencies using Gradle TestKit and JUnit.
- Test Classes: Create isolated tests for validating plugin behavior.
- Test Execution: Use
./gradlew test
to run tests and verify results. - CI Integration: Automate testing using GitHub Actions or another CI tool.
This setup will help you maintain a high-quality Gradle plugin.