diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..d13affe --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Ensure all Java files use LF. +*.java eol=lf diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..d0878e0 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,7 @@ +# Lines starting with '#' are comments. +# Each line is a file pattern followed by one or more owners. + +# See: https://help.github.com/articles/about-codeowners/ + +# These owners will be the default owners for everything in the repo. +* @hasithaa @SasinduDilshara diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..96b073c --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,12 @@ +## Purpose + +Fixes: + +## Examples + +## Checklist +- [ ] Linked to an issue +- [ ] Updated the changelog +- [ ] Added tests +- [ ] Updated the spec +- [ ] Checked native-image compatibility diff --git a/.github/workflows/build-timestamped-master.yml b/.github/workflows/build-timestamped-master.yml new file mode 100644 index 0000000..72d594a --- /dev/null +++ b/.github/workflows/build-timestamped-master.yml @@ -0,0 +1,18 @@ +name: Build + +on: + push: + branches: + - main + paths-ignore: + - '*.md' + - 'docs/**' + - 'load-tests/**' + workflow_dispatch: + +jobs: + call_workflow: + name: Run Build Workflow + if: ${{ github.repository_owner == 'ballerina-platform' }} + uses: ballerina-platform/ballerina-library/.github/workflows/build-timestamp-master-template.yml@main + secrets: inherit diff --git a/.github/workflows/build-with-bal-test-graalvm.yml b/.github/workflows/build-with-bal-test-graalvm.yml new file mode 100644 index 0000000..291054d --- /dev/null +++ b/.github/workflows/build-with-bal-test-graalvm.yml @@ -0,0 +1,37 @@ +name: GraalVM Check + +on: + workflow_dispatch: + inputs: + lang_tag: + description: Branch/Release Tag of the Ballerina Lang + required: true + default: master + lang_version: + description: Ballerina Lang Version (If given ballerina lang build will be skipped) + required: false + default: '' + native_image_options: + description: Default native-image options + required: false + default: '' + schedule: + - cron: '30 18 * * *' + pull_request: + branches: + - main + types: [ opened, synchronize, reopened, labeled, unlabeled ] + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }} + cancel-in-progress: true + +jobs: + call_stdlib_workflow: + name: Run StdLib Workflow + if: ${{ github.event_name != 'schedule' || (github.event_name == 'schedule' && github.repository_owner == 'ballerina-platform') }} + uses: ballerina-platform/ballerina-library/.github/workflows/build-with-bal-test-graalvm-template.yml@main + with: + lang_tag: ${{ inputs.lang_tag }} + lang_version: ${{ inputs.lang_version }} + native_image_options: '-J-Xmx7G ${{ inputs.native_image_options }}' diff --git a/.github/workflows/central-publish.yml b/.github/workflows/central-publish.yml new file mode 100644 index 0000000..11922b5 --- /dev/null +++ b/.github/workflows/central-publish.yml @@ -0,0 +1,21 @@ +name: Publish to the Ballerina central + +on: + workflow_dispatch: + inputs: + environment: + type: choice + description: Select Environment + required: true + options: + - DEV CENTRAL + - STAGE CENTRAL + +jobs: + call_workflow: + name: Run Central Publish Workflow + if: ${{ github.repository_owner == 'ballerina-platform' }} + uses: ballerina-platform/ballerina-library/.github/workflows/central-publish-template.yml@main + secrets: inherit + with: + environment: ${{ github.event.inputs.environment }} diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml new file mode 100644 index 0000000..9454d4e --- /dev/null +++ b/.github/workflows/publish-release.yml @@ -0,0 +1,16 @@ +name: Publish Release + +on: + workflow_dispatch: + repository_dispatch: + types: [stdlib-release-pipeline] + +jobs: + call_workflow: + name: Run Release Workflow + if: ${{ github.repository_owner == 'ballerina-platform' }} + uses: ballerina-platform/ballerina-library/.github/workflows/release-package-template.yml@main + secrets: inherit + with: + package-name: data.jsondata + package-org: ballerina diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 0000000..06f4f56 --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,14 @@ +name: Pull Request + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }} + cancel-in-progress: true + +on: pull_request + +jobs: + call_workflow: + name: Run PR Build Workflow + if: ${{ github.repository_owner == 'ballerina-platform' }} + uses: ballerina-platform/ballerina-library/.github/workflows/pull-request-build-template.yml@main + secrets: inherit diff --git a/.github/workflows/stale-check.yml b/.github/workflows/stale-check.yml new file mode 100644 index 0000000..8763360 --- /dev/null +++ b/.github/workflows/stale-check.yml @@ -0,0 +1,19 @@ +name: 'Close stale pull requests' + +on: + schedule: + - cron: '30 19 * * *' + workflow_dispatch: + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v3 + with: + stale-pr-message: 'This PR has been open for more than 15 days with no activity. This will be closed in 3 days unless the `stale` label is removed or commented.' + close-pr-message: 'Closed PR due to inactivity for more than 18 days.' + days-before-pr-stale: 15 + days-before-pr-close: 3 + days-before-issue-stale: -1 + days-before-issue-close: -1 diff --git a/.github/workflows/trivy-scan.yml b/.github/workflows/trivy-scan.yml new file mode 100644 index 0000000..2f7999d --- /dev/null +++ b/.github/workflows/trivy-scan.yml @@ -0,0 +1,13 @@ +name: Trivy + +on: + workflow_dispatch: + schedule: + - cron: '30 20 * * *' + +jobs: + call_workflow: + name: Run Trivy Scan Workflow + if: ${{ github.repository_owner == 'ballerina-platform' }} + uses: ballerina-platform/ballerina-library/.github/workflows/trivy-scan-template.yml@main + secrets: inherit diff --git a/.gitignore b/.gitignore index 524f096..1d2a7ee 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,9 @@ # Log file *.log +# Lock file +*.lck + # BlueJ files *.ctxt @@ -12,6 +15,7 @@ # Package Files # *.jar +!gradle/wrapper/gradle-wrapper.jar *.war *.nar *.ear @@ -19,6 +23,24 @@ *.tar.gz *.rar -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.csv hs_err_pid* replay_pid* + +build +.gradle/ +target +bin/ + +# IDEA Files +.idea/ +*.iml +*.ipr +*.iws + +# MacOS +*.DS_Store + +# Ballerina +velocity.log* +*Ballerina.lock diff --git a/README.md b/README.md index 94f4ba4..ba9bc60 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,455 @@ -# module-ballerina-data.csv +# Ballerina CSV Data Library + The Ballerina CSV Data Library is a comprehensive toolkit designed to facilitate the handling and manipulation of CSV data within Ballerina applications. It streamlines the process of converting CSV data to native Ballerina data types, enabling developers to work with CSV content seamlessly and efficiently. + +This library is the refined successor of the `ballerina/csvdata` module, incorporating enhanced functionalities and improved performance. + +## Features + +- **Versatile CSV Data Input**: Accept CSV data as a csv, a string, byte array, or a stream and convert it into a Record value. +- **CSV to Record Value Conversion**: Transform CSV data into Ballerina records with ease in compliance with OpenAPI 3 standards. +- **Projection Support**: Perform selective conversion of CSV data subsets into Record values through projection. + +## Usage + +### Converting an CSV value to a Record value + +To convert an CSV value to a Record value, you can utilize the `fromCsvWithType` function provided by the library. The example below showcases the transformation of an CSV value into a Record value. + +```ballerina +import ballerina/data.csv; +import ballerina/io; + +public function main() returns error? { + csv data = csv ` + 0 + string + string + `; + + Book book = check csvdata:fromCsvWithType(data); + io:println(book); +} + +type Book record {| + int id; + string title; + string author; +|}; +``` + +### Converting an external CSV document to a Record value + +For transforming CSV content from an external source into a Record value, the `fromCsvStringWithType` function can be used. This external source can be in the form of a string or a byte array/byte stream that houses the CSV data. This is commonly extracted from files or network sockets. The example below demonstrates the conversion of an CSV value from an external source into a Record value. + +```ballerina +import ballerina/data.csv; +import ballerina/io; + +public function main() returns error? { + string csvContent = check io:fileReadString("path/to/file.csv"); + Book book = check csvdata:fromCsvStringWithType(csvContent); + io:println(book); +} + +type Book record {| + int id; + string title; + string author; +|}; +``` + +Make sure to handle possible errors that may arise during the file reading or CSV to record conversion process. The `check` keyword is utilized to handle these errors, but more sophisticated error handling can be implemented as per your requirements. + +## CSV to Record Canonical Representation + +The translation of CSV to a Record representation is a fundamental feature of the library. It facilitates a structured and type-safe approach to handling CSV data within Ballerina applications. + +Take for instance the following CSV snippet: + +```csv + + 0 + string + string + +``` + +CSV data is inherently hierarchical, forming a tree structure. In the given example, the root element is `book`, which encompasses three child elements: `id`, `title`, and `author`. The `id` element harbors a numeric value `0`, whereas both the `title` and `author` elements contain string values. + +A straightforward record representation of the above CSV data is: + +```ballerina +type Book record {| + int id; + string title; + string author; +|}; +``` + +In this representation, the CSV data is efficiently translated into a record value. The `book` element is mapped to a record of type `Book`, and the child elements `id`, `title`, and `author` are converted into record fields of types `int` and `string` correspondingly. + +This record type definition can be further refined through annotations. Moreover, utilizing open and closed records grants control over the translation process, which is elaborated in subsequent sections. + +### CSV Element Names + +The name of the CSV element serves as the name of the record field, altered to fit a valid Ballerina identifier. Notably, the record field name corresponds to the local name of the CSV element, with any namespace prefixes being disregarded. + +Consider the CSV snippet: + +```csv + + 0 + string + string + +``` + +The canonical representation of the above CSV as a Ballerina record is: + +```ballerina +type Book record {| + int id; + string 'title\-name'; + string 'author\-name'; +|}; +``` + +Observe how the CSV element names `title-name` and `author-name` are represented using delimited identifiers in Ballerina; the `-` characters in the CSV element names are escaped using the `\` character. + +Moreover, the `@Name` annotation can be utilized to explicitly specify the name of the record field, providing control over the translation process: + +```ballerina +import ballerina/data.csv; + +type Book record {| + int id; + @csvdata:Name { value: "title-name" } + string title; + @csvdata:Name { value: "author-name" } + string author; +|}; +``` + +### CSV Attributes + +Similarly to CSV elements, CSV attributes are also represented into record fields within the corresponding parent Record type. The name of the CSV attribute is converted into the name of the record field, ensuring it is a valid Ballerina identifier. It is crucial to emphasize that the record field name aligns with the local name of the CSV attribute, and any namespace prefixes are ignored. + +Consider the following CSV snippet: + +```csv + + 0 + string + string + +``` + +The canonical representation of the above CSV as a Ballerina record is: + +```ballerina +type Book record {| + string lang; + decimal price; + int id; + string title; + string author; +|}; +``` + +Additionally the `@Attribute` annotation can be utilized to explicitly specify the name of the record field, providing control over the translation process. + +### Child Elements + +Child elements are mapped to record fields, with the type reflecting that of the corresponding child element. + +Examine the CSV snippet below: + +```csv + + 0 + string + + string + string + + +``` + +The canonical representation of the above CSV as a Ballerina record is: + +```ballerina +type Book record {| + int id; + string title; + Author author; +|}; + +type Author record {| + string name; + string country; +|}; +``` + +In this transformation, child elements, like the `author` element containing its own sub-elements, are converted into nested records. This maintains the hierarchical structure of the CSV data within the Ballerina type system, enabling intuitive and type-safe data manipulation. + +Alternatively, inline type definitions offer a compact method for representing child elements as records within their parent record. This approach is particularly beneficial when the child record does not require reuse elsewhere and is unique to its parent record. + +Consider the subsequent Ballerina record definition, which employs inline type definition for the `author` field: + +```ballerina +type Book record {| + int id; + string title; + record {| + string name; + string country; + |} author; +|}; +``` + +### CSV Text Content + +The transformation of CSV text content into record fields typically involves types like `string`, `boolean`, `int`, `float`, or `decimal`, depending on the textual content. For numeric values where type information is not explicitly defined, the default conversion type is `decimal`. Conversely, for non-numeric content, the default type is `string`. + +Consider the CSV snippet below: + +```csv + + 0 + string + string + true + 10.5 + +``` + +The translation into a Ballerina record would be as follows: + +```ballerina +type Book record {| + int id; + string title; + string author; + boolean available; + decimal price; +|}; +``` + +In scenarios where the parent CSV element of text content also includes attributes, the CSV text content can be represented by a `string` type field named `#content` within a record type, with the attributes being mapped to their respective fields. + +For instance, examine this CSV: + +```csv + + 0 + string + 10.5 + +``` + +The canonical translation of CSV to a Ballerina record is as such: + +```ballerina +type Book record {| + int id; + Title title; + decimal price; +|}; + +type Title record {| + string \#content; + string lang; +|}; +``` + +Modifications to the default behavior for converting numerical values can be achieved by providing `Options` mappings to the respective functions. This enables developers to choose specific data types and exert finer control over the conversion process. + +### CSV Namespaces + +CSV namespaces are accommodated by the library, supporting the translation of CSV data that contains namespace prefixes. However, the presence of CSV namespaces is not mandatory, and the library is capable of processing CSV data without namespaces. Should namespaces be present, they will be utilized to resolve the names of CSV elements and attributes. + +It's important to note that, unlike in the `csvdata` module, the namespace prefixes do not reflect in the record field names, as the record field names align with the local names of the CSV elements. + +Examine the CSV snippet below with default namespaces: + +```csv + + 0 + string + string + +``` + +The translation into a Ballerina record would be: + +```ballerina +type Book record {| + int id; + string title; + string author; +|}; +``` + +Incorporating namespace validation yields: + +```ballerina +import ballerina/data.csv; + +@csvdata:Namespace { + uri: "http://example.com/book" +} +type Book record {| + int id; + string title; + string author; +|}; +``` + +Here is the same CSV snippet with a namespace prefix: + +```csv + + 0 + string + string + +``` + +The translation into a Ballerina record would be: + +```ballerina +import ballerina/data.csv; + +@csvdata:Namespace { + uri: "http://example.com/book", + prefix: "bk" +} +type Book record {| + int id; + string title; + string author; +|}; +``` + +In these examples, the CSV namespaces are appropriately acknowledged, ensuring the integrity of the CSV structure within the Ballerina records. + +### Working with Arrays + +The library is equipped to handle the transformation of CSV data containing arrays into Ballerina records. + +Take the following CSV snippet as an example: + +```csv + + 0 + string + string + string + string + +``` + +The canonical representation of this CSV as a Ballerina record is: + +```ballerina +type Book record {| + int id; + string title; + string[] author; +|}; +``` + +### Controlling Which Elements to Convert + +The library allows for selective conversion of CSV elements into records through the use of rest fields. This is beneficial when the CSV data contains elements that are not necessary to be transformed into record fields. + +Take this CSV snippet as an example: + +```csv + + 0 + string + string + 10.5 + +``` + +Suppose that only the book `id`, and `title` elements are needed for conversion into record fields. This can be achieved by defining only the required fields in the record type and omitting the rest field: + +```ballerina +type Book record {| + int id; + string title; +|}; +``` + +However, if the rest field is utilized (or if the record type is defined as an open record), all elements in the CSV data will be transformed into record fields: + +```ballerina +type Book record {| + int id; + string title; +|}; +``` + +In this instance, all other elements in the CSV data, such as `author` and `price` along with their attributes, will be transformed into `string` type fields with the corresponding element name as the key. + +This behavior extends to arrays as well. + +The process of projecting CSV data into a record supports various use cases, including the filtering out of unnecessary elements. This functionality is anticipated to be enhanced in the future to accommodate more complex scenarios, such as filtering values based on regular expressions, among others. + +## Issues and projects + +Issues and Projects tabs are disabled for this repository as this is part of the Ballerina standard library. To report bugs, request new features, start new discussions, view project boards, etc. please visit Ballerina standard library [parent repository](https://github.com/ballerina-platform/ballerina-standard-library). + +This repository only contains the source code for the package. + +## Building from the source + +### Set up the prerequisites + +1. Download and install Java SE Development Kit (JDK) version 17 (from one of the following locations). + * [Oracle](https://www.oracle.com/java/technologies/downloads/) + * [OpenJDK](https://adoptium.net/) + +2. Export your GitHub personal access token with the read package permissions as follows. + + export packageUser= + export packagePAT= + +### Building the source + +Execute the commands below to build from source. + +1. To build the library: + + ./gradlew clean build + +2. Publish ZIP artifact to the local `.m2` repository: + + ./gradlew clean build publishToMavenLocal + +3. Publish the generated artifacts to the local Ballerina central repository: + + ./gradlew clean build -PpublishToLocalCentral=true + +4. Publish the generated artifacts to the Ballerina central repository: + + ./gradlew clean build -PpublishToCentral=true + +## Contributing to Ballerina + +As an open source project, Ballerina welcomes contributions from the community. + +For more information, go to the [contribution guidelines](https://github.com/ballerina-platform/ballerina-lang/blob/master/CONTRIBUTING.md). + +## Code of conduct + +All contributors are encouraged to read the [Ballerina code of conduct](https://ballerina.io/code-of-conduct). + +## Useful links + +[//]: # (* For more information go to the [`csvdata` library](https://lib.ballerina.io/ballerina/data.csv/latest).) +* Chat live with us via our [Discord server](https://discord.gg/ballerinalang). +* Post all technical questions on Stack Overflow with the [#ballerina](https://stackoverflow.com/questions/tagged/ballerina) tag. \ No newline at end of file diff --git a/ballerina/Ballerina.toml b/ballerina/Ballerina.toml new file mode 100644 index 0000000..ecae9dc --- /dev/null +++ b/ballerina/Ballerina.toml @@ -0,0 +1,19 @@ +[package] +org = "ballerina" +name = "data.csv" +version = "0.1.0" +authors = ["Ballerina"] +keywords = ["csv"] +repository = "https://github.com/ballerina-platform/module-ballerina-data.csv" +license = ["Apache-2.0"] +distribution = "2201.9.0" +export = ["data.csv"] + +[platform.java17] +graalvmCompatible = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "data.csv-native" +version = "0.1.0" +path = "../native/build/libs/data.csv-native-0.1.0-SNAPSHOT.jar" diff --git a/ballerina/CompilerPlugin.toml b/ballerina/CompilerPlugin.toml new file mode 100644 index 0000000..e503c45 --- /dev/null +++ b/ballerina/CompilerPlugin.toml @@ -0,0 +1,6 @@ +[plugin] +id = "constraint-compiler-plugin" +class = "io.ballerina.stdlib.data.csvdata.compiler.CsvDataCompilerPlugin" + +[[dependency]] +path = "../compiler-plugin/build/libs/data.csv-compiler-plugin-0.1.0-SNAPSHOT.jar" diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml new file mode 100644 index 0000000..c07b540 --- /dev/null +++ b/ballerina/Dependencies.toml @@ -0,0 +1,28 @@ +# AUTO-GENERATED FILE. DO NOT MODIFY. + +# This file is auto-generated by Ballerina for managing dependency versions. +# It should not be modified by hand. + +[ballerina] +dependencies-toml-version = "2" +distribution-version = "2201.9.0" + +[[package]] +org = "ballerina" +name = "data.csv" +version = "0.1.0" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] +modules = [ + {org = "ballerina", packageName = "data.csv", moduleName = "data.csv"} +] + +[[package]] +org = "ballerina" +name = "jballerina.java" +version = "0.0.0" +modules = [ + {org = "ballerina", packageName = "jballerina.java", moduleName = "jballerina.java"} +] + diff --git a/ballerina/Package.md b/ballerina/Package.md new file mode 100644 index 0000000..7da4a1a --- /dev/null +++ b/ballerina/Package.md @@ -0,0 +1 @@ +# Ballerina CSV Data module \ No newline at end of file diff --git a/ballerina/build.gradle b/ballerina/build.gradle new file mode 100644 index 0000000..4c5f9c3 --- /dev/null +++ b/ballerina/build.gradle @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import org.apache.tools.ant.taskdefs.condition.Os + +buildscript { + repositories { + maven { + url = 'https://maven.pkg.github.com/ballerina-platform/plugin-gradle' + credentials { + username System.getenv("packageUser") + password System.getenv("packagePAT") + } + } + } + dependencies { + classpath "io.ballerina:plugin-gradle:${project.ballerinaGradlePluginVersion}" + } +} + +description = 'Ballerina - Data CSV Module' + +def packageName = "data.csv" +def packageOrg = "ballerina" + +def tomlVersion = stripBallerinaExtensionVersion("${project.version}") +def ballerinaTomlFilePlaceHolder = new File("${project.rootDir}/build-config/resources/Ballerina.toml") +def ballerinaTomlFile = new File("$project.projectDir/Ballerina.toml") +def compilerPluginTomlFilePlaceHolder = new File("${project.rootDir}/build-config/resources/CompilerPlugin.toml") +def compilerPluginTomlFile = new File("$project.projectDir/CompilerPlugin.toml") + +def stripBallerinaExtensionVersion(String extVersion) { + if (extVersion.matches(project.ext.timestampedVersionRegex)) { + def splitVersion = extVersion.split('-'); + if (splitVersion.length > 3) { + def strippedValues = splitVersion[0..-4] + return strippedValues.join('-') + } else { + return extVersion + } + } else { + return extVersion.replace("${project.ext.snapshotVersion}", "") + } +} + +apply plugin: 'io.ballerina.plugin' + +ballerina { + testCoverageParam = "--code-coverage --coverage-format=xml --includes=io.ballerina.stdlib.data.*:ballerina.*" + packageOrganization = packageOrg + module = packageName + langVersion = ballerinaLangVersion +} + +configurations { + externalJars +} + +dependencies { + externalJars(group: 'io.ballerina.stdlib', name: 'constraint-native', version: "${stdlibConstraintVersion}") { + transitive = false + } +} + +task updateTomlFiles { + doLast { + def stdlibDependentConstraintNativeVersion = stdlibConstraintVersion + def stdlibDependentConstraintVersion = stripBallerinaExtensionVersion("${stdlibDependentConstraintNativeVersion}") + def newConfig = ballerinaTomlFilePlaceHolder.text.replace("@project.version@", project.version) + newConfig = newConfig.replace("@toml.version@", tomlVersion) + ballerinaTomlFile.text = newConfig + + def newCompilerPluginToml = compilerPluginTomlFilePlaceHolder.text.replace("@project.version@", project.version) + compilerPluginTomlFile.text = newCompilerPluginToml + } +} + +task commitTomlFiles { + doLast { + project.exec { + ignoreExitValue true + if (Os.isFamily(Os.FAMILY_WINDOWS)) { + commandLine 'cmd', '/c', "git commit Ballerina.toml Dependencies.toml CompilerPlugin.toml -m '[Automated] Update the native jar versions'" + } else { + commandLine 'sh', '-c', "git commit Ballerina.toml Dependencies.toml CompilerPlugin.toml -m '[Automated] Update the native jar versions'" + } + } + } +} + +publishing { + publications { + maven(MavenPublication) { + artifact source: createArtifactZip, extension: 'zip' + } + } + + repositories { + maven { + name = "GitHubPackages" + url = uri("https://maven.pkg.github.com/ballerina-platform/module-${packageOrg}-${packageName}") + credentials { + username = System.getenv("publishUser") + password = System.getenv("publishPAT") + } + } + } +} + +task deleteDependencyTomlFiles { + if (project.hasProperty("deleteDependencies")) { + delete "${project.projectDir}/Dependencies.toml" + } +} + + +updateTomlFiles.dependsOn copyStdlibs + +build.dependsOn "generatePomFileForMavenPublication" +build.dependsOn ":${packageName}-native:build" +build.dependsOn deleteDependencyTomlFiles +build.dependsOn ":${packageName}-compiler-plugin:build" +build.dependsOn deleteDependencyTomlFiles + +test.dependsOn ":${packageName}-native:build" +test.dependsOn ":${packageName}-native:build" +test.dependsOn ":${packageName}-compiler-plugin:build" + +publish.dependsOn build +publishToMavenLocal.dependsOn build diff --git a/ballerina/csv_api.bal b/ballerina/csv_api.bal new file mode 100644 index 0000000..7355b09 --- /dev/null +++ b/ballerina/csv_api.bal @@ -0,0 +1,114 @@ +// Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ballerina/jballerina.java; + +# Converts CSV string to subtype of record array. +# +# + s - Source CSV string value +# + options - Options to be used for filtering in the projection +# + t - Target type +# + return - On success, value belonging to the given target type, else returns an `csv:Error` value. +public isolated function parseStringToRecord(string s, parseToRecordOption options = {}, typedesc t = <>) + returns t|Error = @java:Method {'class: "io.ballerina.stdlib.data.csvdata.csv.Native"} external; + +# Converts byte[] to subtype of record array. +# +# + s - Source CSV byte array +# + options - Options to be used for filtering in the projection +# + t - Target type +# + return - On success, value belonging to the given target type, else returns an `csv:Error` value. +public isolated function parseBytesToRecord(byte[] s, parseToRecordOption options = {}, typedesc t = <>) + returns t|Error = @java:Method {'class: "io.ballerina.stdlib.data.csvdata.csv.Native"} external; + +# Converts CSV byte-block-stream to subtype of record array. +# +# + s - Source CSV byte-block-stream +# + options - Options to be used for filtering in the projection +# + t - Target type +# + return - On success, value belonging to the given target type, else returns an `csv:Error` value. +public isolated function parseStreamToRecord(stream s, + parseToRecordOption options = {}, typedesc t = <>) + returns t|Error = @java:Method {'class: "io.ballerina.stdlib.data.csvdata.csv.Native"} external; + +# Converts CSV string to subtype of anydata[][]. +# +# + s - Source CSV string value +# + options - Options to be used for filtering in the projection +# + t - Target type +# + return - On success, value belonging to the given target type, else returns an `csv:Error` value. +public isolated function parseStringToList(string s, ParseOption options = {}, typedesc t = <>) + returns t|Error = @java:Method {'class: "io.ballerina.stdlib.data.csvdata.csv.Native"} external; + +# Converts byte[] to subtype of anydata[][]. +# +# + s - Source CSV byte array +# + options - Options to be used for filtering in the projection +# + t - Target type +# + return - On success, value belonging to the given target type, else returns an `csv:Error` value. +public isolated function parseBytesToList(byte[] s, ParseOption options = {}, typedesc t = <>) + returns t|Error = @java:Method {'class: "io.ballerina.stdlib.data.csvdata.csv.Native"} external; + +# Converts CSV byte-block-stream to subtype of anydata[][]. +# +# + s - Source CSV byte-block-stream +# + options - Options to be used for filtering in the projection +# + t - Target type +# + return - On success, value belonging to the given target type, else returns an `csv:Error` value. +public isolated function parseStreamToList(stream s, + ParseOption options = {}, typedesc t = <>) + returns t|Error = @java:Method {'class: "io.ballerina.stdlib.data.csvdata.csv.Native"} external; + +# Convert value of type record{}[] to subtype of record{}[]. +# +# + s - Source Ballerina record array value +# + options - Options to be used for filtering in the projection +# + t - Target type +# + return - On success, returns value belonging to the given target type, else returns an `csv:Error` value. +public isolated function parseRecordAsRecordType(record{}[] s, + RecordAsRecordOption options = {}, typedesc t = <>) + returns t|Error = @java:Method {'class: "io.ballerina.stdlib.data.csvdata.csv.Native"} external; + +# Convert value of type record{}[] to subtype of anydata[][]. +# +# + s - Source Ballerina record array value +# + headerNames - The order of the header names in the source +# + options - Options to be used for filtering in the projection +# + t - Target type +# + return - On success, returns value belonging to the given target type, else returns an `csv:Error` value. +public isolated function parseRecordAsListType(record{}[] s, string[] headerNames, + Options options = {}, typedesc t = <>) + returns t|Error = @java:Method {'class: "io.ballerina.stdlib.data.csvdata.csv.Native"} external; + +# Convert value of type string[][] to subtype of record{}[]. +# +# + s - Source Ballerina string array of array value +# + customHeaders - The order of the header names in the source +# + options - Options to be used for filtering in the projection +# + t - Target type +# + return - On success, returns value belonging to the given target type, else returns an `csv:Error` value. +public isolated function parseListAsRecordType(string[][] s, string[]? customHeaders = (), + ListAsRecordOption options = {}, typedesc t = <>) + returns t|Error = @java:Method {'class: "io.ballerina.stdlib.data.csvdata.csv.Native"} external; + +# Convert value of type string[][] to subtype of anydata[][]. +# +# + s - Source Ballerina string array of array value +# + options - Options to be used for filtering in the projection +# + t - Target type +# + return - On success, returns value belonging to the given target type, else returns an `csv:Error` value. +public isolated function parseListAsListType(string[][] s, ListAsListOption options = {}, typedesc t = <>) + returns t|Error = @java:Method {'class: "io.ballerina.stdlib.data.csvdata.csv.Native"} external; diff --git a/ballerina/init.bal b/ballerina/init.bal new file mode 100644 index 0000000..a0a98cb --- /dev/null +++ b/ballerina/init.bal @@ -0,0 +1,25 @@ +// Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ballerina/jballerina.java; + +isolated function init() { + setModule(); +} + +isolated function setModule() = @java:Method { + 'class: "io.ballerina.stdlib.data.csvdata.utils.ModuleUtils" +} external; diff --git a/ballerina/types.bal b/ballerina/types.bal new file mode 100644 index 0000000..11b0c38 --- /dev/null +++ b/ballerina/types.bal @@ -0,0 +1,73 @@ +public type Error error; + +# Defines the name of the JSON Object key. +# +# + value - The name of the JSON Object key +public type NameConfig record {| + string value; +|}; + +# The annotation is used to overwrite the existing record field name. +public const annotation NameConfig Name on record field; + +public type Options record { + record { + # If `true`, nil values will be considered as optional fields in the projection. + boolean nilAsOptionalField = false; // () assign to op + # If `true`, absent fields will be considered as nilable types in the projection. + boolean absentAsNilableType = false; // source haven't () && expected type contains op => () + }|false allowDataProjection = {}; + int[]|string skipLines = []; +}; + +public type ParseOption record {| + *Options; + string:Char delimiter = ","; + string encoding = "UTF-8"; + string locale = "en_US"; +// TODO: Add " for Strings" + string:Char textEnclosure = "\""; + string:Char escapeChar = "\\"; + LineTerminator|LineTerminator[] lineTerminator = [CR, LF, CRLF]; + NilValue? nilValue = (); + // string commentStartingSequence = "#"; + string:Char comment = "#"; + false|int:Unsigned32 header = 0; +|}; + +public type parseToRecordOption record {| + *ParseOption; + + // if header = false and this value is null, Then compiler time error. + string[]? customHeaders = (); + boolean enableConstraintValidation = true; +|}; + +public type ListAsListOption record {| + *Options; + boolean stringConversion = true; +|}; + +public type RecordAsRecordOption record {| + *Options; + boolean enableConstraintValidation = true; +|}; + +public type ListAsRecordOption record {| + *Options; + boolean enableConstraintValidation = true; + boolean stringConversion = true; +|}; + +public enum LineTerminator { + CR = "\r", + LF = "\n", + CRLF = "\r\n" +}; + +public enum NilValue { + NULL = "null", + EMPTY_STRING = "", + NOT_APPLICABLE = "N/A", + BAL_NULL = "()" +}; diff --git a/build-config/checkstyle/build.gradle b/build-config/checkstyle/build.gradle new file mode 100644 index 0000000..857ad1e --- /dev/null +++ b/build-config/checkstyle/build.gradle @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +plugins { + id "de.undercouch.download" +} + +apply plugin: 'java' + +task downloadCheckstyleRuleFiles(type: Download) { + src([ + 'https://raw.githubusercontent.com/wso2/code-quality-tools/v1.4/checkstyle/jdk-17/checkstyle.xml', + 'https://raw.githubusercontent.com/wso2/code-quality-tools/v1.4/checkstyle/jdk-17/suppressions.xml' + ]) + overwrite false + onlyIfNewer true + dest buildDir +} + +jar { + enabled = false +} + +clean { + enabled = false +} + +artifacts.add('default', file("$project.buildDir/checkstyle.csv")) { + builtBy('downloadCheckstyleRuleFiles') +} + +artifacts.add('default', file("$project.buildDir/suppressions.csv")) { + builtBy('downloadCheckstyleRuleFiles') +} diff --git a/build-config/resources/Ballerina.toml b/build-config/resources/Ballerina.toml new file mode 100644 index 0000000..3db6b47 --- /dev/null +++ b/build-config/resources/Ballerina.toml @@ -0,0 +1,19 @@ +[package] +org = "ballerina" +name = "data.csv" +version = "@toml.version@" +authors = ["Ballerina"] +keywords = ["csv"] +repository = "https://github.com/ballerina-platform/module-ballerina-data.csv" +license = ["Apache-2.0"] +distribution = "2201.9.0" +export = ["data.csv"] + +[platform.java17] +graalvmCompatible = true + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "data.csv-native" +version = "@toml.version@" +path = "../native/build/libs/data.csv-native-@project.version@.jar" diff --git a/build-config/resources/CompilerPlugin.toml b/build-config/resources/CompilerPlugin.toml new file mode 100644 index 0000000..10f4b4a --- /dev/null +++ b/build-config/resources/CompilerPlugin.toml @@ -0,0 +1,6 @@ +[plugin] +id = "constraint-compiler-plugin" +class = "io.ballerina.stdlib.data.csvdata.compiler.CsvDataCompilerPlugin" + +[[dependency]] +path = "../compiler-plugin/build/libs/data.csv-compiler-plugin-@project.version@.jar" diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..dc3d177 --- /dev/null +++ b/build.gradle @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +plugins { + id "com.github.spotbugs" + id "com.github.johnrengelman.shadow" + id "de.undercouch.download" + id "net.researchgate.release" +} + +allprojects { + group = project.group + version = project.version + + apply plugin: 'jacoco' + apply plugin: 'maven-publish' + + repositories { + mavenLocal() + maven { + url = 'https://maven.wso2.org/nexus/content/repositories/releases/' + } + + maven { + url = 'https://maven.wso2.org/nexus/content/groups/wso2-public/' + } + + maven { + url = 'https://repo.maven.apache.org/maven2' + } + + maven { + url = 'https://maven.pkg.github.com/ballerina-platform/ballerina-lang' + credentials { + username System.getenv("packageUser") + password System.getenv("packagePAT") + } + } + } + + ext { + snapshotVersion= '-SNAPSHOT' + timestampedVersionRegex = '.*-\\d{8}-\\d{6}-\\w.*\$' + } +} + +subprojects { + + configurations { + ballerinaStdLibs + } + + dependencies { + /* Standard libraries */ + ballerinaStdLibs "io.ballerina.stdlib:file-ballerina:${stdlibFileVersion}" + ballerinaStdLibs "io.ballerina.stdlib:io-ballerina:${stdlibIoVersion}" + ballerinaStdLibs "io.ballerina.stdlib:os-ballerina:${stdlibOsVersion}" + ballerinaStdLibs "io.ballerina.stdlib:time-ballerina:${stdlibTimeVersion}" + ballerinaStdLibs "io.ballerina.stdlib:constraint-ballerina:${stdlibConstraintVersion}" + } +} + +def moduleVersion = project.version.replace("-SNAPSHOT", "") + +release { + failOnPublishNeeded = false + + buildTasks = ["build"] + failOnSnapshotDependencies = true + versionPropertyFile = 'gradle.properties' + tagTemplate = 'v$version' + + git { + requireBranch = "release-${moduleVersion}" + pushToRemote = 'origin' + } +} + +task build { + dependsOn('data.csv-ballerina:build') +} diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..f60b970 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,8 @@ +coverage: + precision: 2 + round: down + range: "60...80" + status: + project: + default: + target: 80 diff --git a/compiler-plugin-test/build.gradle b/compiler-plugin-test/build.gradle new file mode 100644 index 0000000..6d5c7f2 --- /dev/null +++ b/compiler-plugin-test/build.gradle @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +plugins { + id 'java' + id 'checkstyle' + id 'com.github.spotbugs' +} + +description = 'Ballerina - Csv Compiler Plugin Tests' + +dependencies { + checkstyle project(':checkstyle') + checkstyle "com.puppycrawl.tools:checkstyle:${puppycrawlCheckstyleVersion}" + + implementation project(':data.csv-compiler-plugin') + + testImplementation group: 'org.ballerinalang', name: 'ballerina-lang', version: "${ballerinaLangVersion}" + testImplementation group: 'org.ballerinalang', name: 'ballerina-tools-api', version: "${ballerinaLangVersion}" + testImplementation group: 'org.ballerinalang', name: 'ballerina-parser', version: "${ballerinaLangVersion}" + testImplementation group: 'org.testng', name: 'testng', version: "${testngVersion}" +} + +tasks.withType(Checkstyle) { + exclude '**/module-info.java' +} + +checkstyle { + toolVersion "${project.puppycrawlCheckstyleVersion}" + configFile rootProject.file("build-config/checkstyle/build/checkstyle.xml") + configProperties = ["suppressionFile" : file("${rootDir}/build-config/checkstyle/build/suppressions.xml")] +} + +checkstyleTest.dependsOn(":checkstyle:downloadCheckstyleRuleFiles") + +spotbugsTest { + effort "max" + reportLevel "low" + reportsDir = file("$project.buildDir/reports/spotbugs") + reports { + html.enabled true + text.enabled = true + } + def excludeFile = file("${project.projectDir}/spotbugs-exclude.xml") + if(excludeFile.exists()) { + excludeFilter = excludeFile + } +} + +spotbugsMain { + enabled false +} + +checkstyleMain { + enabled false +} + +compileJava { + doFirst { + options.compilerArgs = [ + '--module-path', classpath.asPath, + ] + classpath = files() + } +} + +test { + systemProperty "ballerina.offline.flag", "true" + useTestNG() + finalizedBy jacocoTestReport + + testLogging { + exceptionFormat = "full" + afterSuite { desc, result -> + if (!desc.parent) { // will match the outermost suite + def output = "Compiler Plugin Tests: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)" + def startItem = '| ', endItem = ' |' + def repeatLength = startItem.length() + output.length() + endItem.length() + println('\n' + ('-' * repeatLength) + '\n' + startItem + output + endItem + '\n' + ('-' * repeatLength)) + } + } + } +} + +jacocoTestReport { + dependsOn test + reports { + xml.required = true + } + sourceSets project(':data.csv-compiler-plugin').sourceSets.main +} + +test.dependsOn ":data.csv-ballerina:build" diff --git a/compiler-plugin-test/src/test/java/io/ballerina/lib/data/csvdata/compiler/CompilerPluginTest.java b/compiler-plugin-test/src/test/java/io/ballerina/lib/data/csvdata/compiler/CompilerPluginTest.java new file mode 100644 index 0000000..69c212b --- /dev/null +++ b/compiler-plugin-test/src/test/java/io/ballerina/lib/data/csvdata/compiler/CompilerPluginTest.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.ballerina.lib.data.csvdata.compiler; + +/** + * This class includes tests for Ballerina Csv Data compiler plugin. + */ +public class CompilerPluginTest { + +} diff --git a/compiler-plugin-test/src/test/resources/testng.xml b/compiler-plugin-test/src/test/resources/testng.xml new file mode 100644 index 0000000..02c1d8e --- /dev/null +++ b/compiler-plugin-test/src/test/resources/testng.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + diff --git a/compiler-plugin/build.gradle b/compiler-plugin/build.gradle new file mode 100644 index 0000000..f30d515 --- /dev/null +++ b/compiler-plugin/build.gradle @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +plugins { + id 'java' + id 'checkstyle' + id 'com.github.spotbugs' +} + +description = 'Ballerina - Csv Data Compiler Plugin' + +dependencies { + checkstyle project(':checkstyle') + checkstyle "com.puppycrawl.tools:checkstyle:${puppycrawlCheckstyleVersion}" + + implementation group: 'org.ballerinalang', name: 'ballerina-lang', version: "${ballerinaLangVersion}" + implementation group: 'org.ballerinalang', name: 'ballerina-tools-api', version: "${ballerinaLangVersion}" + implementation group: 'org.ballerinalang', name: 'ballerina-parser', version: "${ballerinaLangVersion}" +} + +def excludePattern = '**/module-info.java' +tasks.withType(Checkstyle) { + exclude excludePattern +} + +checkstyle { + toolVersion "${project.puppycrawlCheckstyleVersion}" + configFile rootProject.file("build-config/checkstyle/build/checkstyle.xml") + configProperties = ["suppressionFile" : file("${rootDir}/build-config/checkstyle/build/suppressions.xml")] +} + +checkstyleMain.dependsOn(":checkstyle:downloadCheckstyleRuleFiles") + +spotbugsMain { + effort "max" + reportLevel "low" + reportsDir = file("$project.buildDir/reports/spotbugs") + reports { + html.enabled true + text.enabled = true + } + def excludeFile = file("${rootDir}/spotbugs-exclude.xml") + if(excludeFile.exists()) { + excludeFilter = excludeFile + } +} + +spotbugsMain { + enabled false +} + +compileJava { + doFirst { + options.compilerArgs = [ + '--module-path', classpath.asPath, + ] + classpath = files() + } +} diff --git a/compiler-plugin/src/main/java/io/ballerina/stdlib/data/csvdata/compiler/CsvDataCompilerPlugin.java b/compiler-plugin/src/main/java/io/ballerina/stdlib/data/csvdata/compiler/CsvDataCompilerPlugin.java new file mode 100644 index 0000000..80f28de --- /dev/null +++ b/compiler-plugin/src/main/java/io/ballerina/stdlib/data/csvdata/compiler/CsvDataCompilerPlugin.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.ballerina.stdlib.data.csvdata.compiler; + +import io.ballerina.projects.plugins.CompilerPlugin; +import io.ballerina.projects.plugins.CompilerPluginContext; + +/** + * Compiler plugin for Csvdata's utils functions. + * + * @since 0.1.0 + */ +public class CsvDataCompilerPlugin extends CompilerPlugin { + + @Override + public void init(CompilerPluginContext compilerPluginContext) { + + } +} diff --git a/compiler-plugin/src/main/java/module-info.java b/compiler-plugin/src/main/java/module-info.java new file mode 100644 index 0000000..60ac711 --- /dev/null +++ b/compiler-plugin/src/main/java/module-info.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +module io.ballerina.stdlib.csvdata.compiler { + requires io.ballerina.lang; + requires io.ballerina.tools.api; + requires io.ballerina.parser; +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..ee77c50 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,23 @@ +org.gradle.caching=true +group=io.ballerina.stdlib +version=0.1.0-SNAPSHOT +ballerinaLangVersion=2201.9.0 + +checkstyleToolVersion=10.12.0 +puppycrawlCheckstyleVersion=10.12.0 +testngVersion=7.6.1 +slf4jVersion=2.0.7 +spotbugsVersion=5.0.14 +shadowJarPluginVersion=8.1.1 +downloadPluginVersion=4.0.4 +releasePluginVersion=2.8.0 +ballerinaGradlePluginVersion=2.0.1 +javaJsonPathVersion=2.9.0 +javaJsonSmartVersion=2.4.11 +javaAccessorsSmartVersion=2.4.7 + +stdlibFileVersion=1.9.0 +stdlibIoVersion=1.6.0 +stdlibOsVersion=1.8.0 +stdlibTimeVersion=2.4.0 +stdlibConstraintVersion=1.5.0 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..7454180 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..9f4197d --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..fcb6fca --- /dev/null +++ b/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..6689b85 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/native/build.gradle b/native/build.gradle new file mode 100644 index 0000000..54266fa --- /dev/null +++ b/native/build.gradle @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +plugins { + id 'java' + id 'checkstyle' + id 'com.github.spotbugs' +} + +description = 'Ballerina - Data.CSV Java Utils' + +dependencies { + implementation 'junit:junit:4.13.1' +// checkstyle project(':checkstyle') + checkstyle "com.puppycrawl.tools:checkstyle:${puppycrawlCheckstyleVersion}" + implementation 'org.apache.commons:commons-lang3:3.6' + + implementation group: 'org.ballerinalang', name: 'ballerina-lang', version: "${ballerinaLangVersion}" + implementation group: 'org.ballerinalang', name: 'ballerina-runtime', version: "${ballerinaLangVersion}" + implementation group: 'org.ballerinalang', name: 'value', version: "${ballerinaLangVersion}" + implementation group: 'org.ballerinalang', name: 'value', version: "${ballerinaLangVersion}" + implementation group: 'io.ballerina.stdlib', name: 'constraint-native', version: "${stdlibConstraintVersion}" + // ballerinaStdLibs "io.ballerina.stdlib:constraint-ballerina:${stdlibConstraintVersion}" +} + +checkstyle { + toolVersion "${checkstyleToolVersion}" + configFile rootProject.file("build-config/checkstyle/build/checkstyle.xml") + configProperties = ["suppressionFile" : file("${rootDir}/build-config/checkstyle/build/suppressions.xml")] +} + +checkstyleMain.dependsOn(":checkstyle:downloadCheckstyleRuleFiles") + +def excludePattern = '**/module-info.java' +tasks.withType(Checkstyle) { + exclude excludePattern +} + +spotbugsMain { + enabled=false + effort "max" + reportLevel "low" + reportsDir = file("$project.buildDir/reports/spotbugs") + reports { + html.enabled true + text.enabled = true + } + def excludeFile = file("${rootDir}/spotbugs-exclude.csv") + if(excludeFile.exists()) { + excludeFilter = excludeFile + } +} + +spotbugsTest { + enabled = false +} + +compileJava { + doFirst { + options.compilerArgs = [ + '--module-path', classpath.asPath, + ] + classpath = files() + } +} diff --git a/native/src/main/java/io/ballerina/stdlib/data/csvdata/csv/Native.java b/native/src/main/java/io/ballerina/stdlib/data/csvdata/csv/Native.java new file mode 100644 index 0000000..1f5d3d6 --- /dev/null +++ b/native/src/main/java/io/ballerina/stdlib/data/csvdata/csv/Native.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.ballerina.stdlib.data.csvdata.csv; + +import io.ballerina.runtime.api.Environment; +import io.ballerina.runtime.api.values.BArray; +import io.ballerina.runtime.api.values.BMap; +import io.ballerina.runtime.api.values.BStream; +import io.ballerina.runtime.api.values.BString; +import io.ballerina.runtime.api.values.BTypedesc; + +/** + * Csv conversion. + * + * @since 0.1.0 + */ +public class Native { + + public static Object parseStringToRecord(BString csv, BMap options, BTypedesc type) { + return null; + } + + public static Object parseBytesToRecord(BArray csv, BMap options, BTypedesc type) { + return null; + } + + public static Object parseStreamToRecord(Environment env, BStream csv, + BMap options, BTypedesc type) { + return null; + } + + public static Object parseStringToList(BString csv, BMap options, BTypedesc type) { + return null; + } + + public static Object parseBytesToList(BArray csv, BMap options, BTypedesc type) { + return null; + } + + public static Object parseStreamToList(Environment env, BStream csv, + BMap options, BTypedesc type) { + return null; + } + + public static Object parseRecordAsRecordType(BArray csv, BMap options, BTypedesc type) { + return null; + } + + public static Object parseRecordAsListType(BArray csv, BArray headers, + BMap options, BTypedesc type) { + return null; + } + + public static Object parseListAsRecordType(BArray csv, Object customHeaders, + BMap options, BTypedesc type) { + return null; + } + + public static Object parseListAsListType(BArray csv, BMap options, BTypedesc type) { + return null; + } +} diff --git a/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/ModuleUtils.java b/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/ModuleUtils.java new file mode 100644 index 0000000..d9de709 --- /dev/null +++ b/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/ModuleUtils.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.ballerina.stdlib.data.csvdata.utils; + +import io.ballerina.runtime.api.Environment; +import io.ballerina.runtime.api.Module; + +/** + * This class will hold module related utility functions. + * + * @since 0.1.0 + */ +public class ModuleUtils { + + /** + * Time standard library package ID. + */ + private static Module module = null; + + private ModuleUtils() { + } + + public static void setModule(Environment env) { + module = env.getCurrentModule(); + } + + public static Module getModule() { + return module; + } +} diff --git a/native/src/main/java/module-info.java b/native/src/main/java/module-info.java new file mode 100644 index 0000000..1f625c2 --- /dev/null +++ b/native/src/main/java/module-info.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +module io.ballerina.stdlib.data { + requires io.ballerina.runtime; +} diff --git a/native/src/main/resources/error.properties b/native/src/main/resources/error.properties new file mode 100644 index 0000000..84e78d6 --- /dev/null +++ b/native/src/main/resources/error.properties @@ -0,0 +1,21 @@ +# +# Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). +# +# WSO2 LLC. licenses this file to you under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# ------------------------- +# Data module error messages +# ------------------------- diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..72b6bfd --- /dev/null +++ b/settings.gradle @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +pluginManagement { + plugins { + id "com.github.spotbugs" version "${spotbugsVersion}" + id "com.github.johnrengelman.shadow" version "${shadowJarPluginVersion}" + id "de.undercouch.download" version "${downloadPluginVersion}" + id "net.researchgate.release" version "${releasePluginVersion}" + id "io.ballerina.plugin" version "${ballerinaGradlePluginVersion}" + } + repositories { + gradlePluginPortal() + maven { + url = 'https://maven.pkg.github.com/ballerina-platform/*' + credentials { + username System.getenv("packageUser") + password System.getenv("packagePAT") + } + } + } +} + +plugins { + id "com.gradle.enterprise" version "3.2" +} + +rootProject.name = 'data.csv' +include(':checkstyle') +include(':data.csv-native') +include(':data.csv-ballerina') +include(':data.csv-compiler-plugin') +include(':data.csv-compiler-plugin-tests') + +project(':checkstyle').projectDir = file("build-config${File.separator}checkstyle") +project(':data.csv-native').projectDir = file('native') +project(':data.csv-ballerina').projectDir = file('ballerina') +project(':data.csv-compiler-plugin').projectDir = file('compiler-plugin') +project(':data.csv-compiler-plugin-tests').projectDir = file('compiler-plugin-test') + +gradleEnterprise { + buildScan { + termsOfServiceUrl = 'https://gradle.com/terms-of-service' + termsOfServiceAgree = 'yes' + } +}