├── .art ├── banner.webp ├── kmmify.ai ├── kmmify.svg └── kmmify.webp ├── .editorconfig ├── .github ├── pull_request_template.md └── workflows │ ├── deploy.yml │ └── pipeline.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE.txt ├── README.md ├── SECURITY.md ├── build.gradle.kts ├── buildSrc ├── build.gradle.kts ├── settings.gradle.kts └── src │ └── main │ ├── kotlin │ ├── BuildConfig.kt │ ├── build │ │ ├── Arch.kt │ │ ├── CIPlatform.kt │ │ ├── Os.kt │ │ └── Version.kt │ ├── extensions.kt │ ├── external │ │ └── CommandLine.kt │ └── publication │ │ ├── SigningConfig.kt │ │ └── gh-packages.gradle.kts │ └── resources │ └── license-regex.template ├── core ├── build.gradle.kts └── src │ ├── androidMain │ ├── AndroidManifest.xml │ └── kotlin │ │ ├── .keep │ │ └── io │ │ └── goatbytes │ │ └── kmmify │ │ └── Platform.kt │ ├── androidUnitTest │ └── kotlin │ │ ├── .keep │ │ └── io │ │ └── goatbytes │ │ └── kmmify │ │ └── PlatformTest.kt │ ├── appleMain │ └── kotlin │ │ └── .keep │ ├── commonMain │ └── kotlin │ │ ├── .keep │ │ └── io │ │ └── goatbytes │ │ └── kmmify │ │ ├── Platform.kt │ │ └── PlatformType.kt │ ├── commonTest │ └── kotlin │ │ └── .keep │ ├── iosMain │ └── kotlin │ │ ├── .keep │ │ └── io │ │ └── goatbytes │ │ └── kmmify │ │ └── Platform.kt │ ├── jsMain │ └── kotlin │ │ ├── .keep │ │ └── io │ │ └── goatbytes │ │ └── kmmify │ │ └── Platform.kt │ ├── jsTest │ └── kotlin │ │ ├── .keep │ │ └── io │ │ └── goatbytes │ │ └── kmmify │ │ └── PlatformTest.kt │ ├── jvmMain │ └── kotlin │ │ ├── .keep │ │ └── io │ │ └── goatbytes │ │ └── kmmify │ │ └── Platform.kt │ ├── jvmTest │ └── kotlin │ │ ├── .keep │ │ └── io │ │ └── goatbytes │ │ └── kmmify │ │ └── PlatformTest.kt │ ├── linuxMain │ └── kotlin │ │ ├── .keep │ │ └── io │ │ └── goatbytes │ │ └── kmmify │ │ └── Platform.kt │ ├── macosMain │ └── kotlin │ │ ├── .keep │ │ └── io │ │ └── goatbytes │ │ └── kmmify │ │ └── Platform.kt │ ├── tvosMain │ └── kotlin │ │ ├── .keep │ │ └── io │ │ └── goatbytes │ │ └── kmmify │ │ └── Platform.kt │ └── watchosMain │ └── kotlin │ ├── .keep │ └── io │ └── goatbytes │ └── kmmify │ └── Platform.kt ├── detekt.yml ├── docs ├── assets │ ├── css │ │ └── app.css │ ├── img │ │ ├── banner.png │ │ ├── favicon.png │ │ └── logo.png │ └── js │ │ └── app.js ├── index.md └── overrides │ └── partials │ └── copyright.html ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── kotlin-js-store └── yarn.lock ├── mkdocs.yml ├── renovate.json └── settings.gradle.kts /.art/banner.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/.art/banner.webp -------------------------------------------------------------------------------- /.art/kmmify.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/.art/kmmify.ai -------------------------------------------------------------------------------- /.art/kmmify.svg: -------------------------------------------------------------------------------- 1 | by -------------------------------------------------------------------------------- /.art/kmmify.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/.art/kmmify.webp -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | charset = utf-8 3 | end_of_line = lf 4 | indent_size = 2 5 | indent_style = space 6 | insert_final_newline = false 7 | max_line_length = 100 8 | tab_width = 2 9 | ij_continuation_indent_size = 4 10 | 11 | [{*.kt,*.kts}] 12 | indent_size = 2 13 | tab_width = 2 14 | ij_continuation_indent_size = 2 15 | ij_kotlin_align_in_columns_case_branch = false 16 | ij_kotlin_align_multiline_binary_operation = false 17 | ij_kotlin_align_multiline_extends_list = false 18 | ij_kotlin_align_multiline_method_parentheses = false 19 | ij_kotlin_align_multiline_parameters = true 20 | ij_kotlin_align_multiline_parameters_in_calls = false 21 | ij_kotlin_allow_trailing_comma = false 22 | ij_kotlin_allow_trailing_comma_on_call_site = false 23 | ij_kotlin_assignment_wrap = normal 24 | ij_kotlin_blank_lines_after_class_header = 0 25 | ij_kotlin_blank_lines_around_block_when_branches = 0 26 | ij_kotlin_blank_lines_before_declaration_with_comment_or_annotation_on_separate_line = 1 27 | ij_kotlin_block_comment_add_space = false 28 | ij_kotlin_block_comment_at_first_column = true 29 | ij_kotlin_call_parameters_new_line_after_left_paren = true 30 | ij_kotlin_call_parameters_right_paren_on_new_line = true 31 | ij_kotlin_call_parameters_wrap = on_every_item 32 | ij_kotlin_catch_on_new_line = false 33 | ij_kotlin_class_annotation_wrap = split_into_lines 34 | ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL 35 | ij_kotlin_continuation_indent_for_chained_calls = false 36 | ij_kotlin_continuation_indent_for_expression_bodies = false 37 | ij_kotlin_continuation_indent_in_argument_lists = false 38 | ij_kotlin_continuation_indent_in_elvis = false 39 | ij_kotlin_continuation_indent_in_if_conditions = false 40 | ij_kotlin_continuation_indent_in_parameter_lists = false 41 | ij_kotlin_continuation_indent_in_supertype_lists = false 42 | ij_kotlin_else_on_new_line = false 43 | ij_kotlin_enum_constants_wrap = off 44 | ij_kotlin_extends_list_wrap = normal 45 | ij_kotlin_field_annotation_wrap = split_into_lines 46 | ij_kotlin_finally_on_new_line = false 47 | ij_kotlin_if_rparen_on_new_line = true 48 | ij_kotlin_import_nested_classes = false 49 | ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^ 50 | ij_kotlin_insert_whitespaces_in_simple_one_line_method = true 51 | ij_kotlin_keep_blank_lines_before_right_brace = 2 52 | ij_kotlin_keep_blank_lines_in_code = 2 53 | ij_kotlin_keep_blank_lines_in_declarations = 2 54 | ij_kotlin_keep_first_column_comment = true 55 | ij_kotlin_keep_indents_on_empty_lines = false 56 | ij_kotlin_keep_line_breaks = true 57 | ij_kotlin_lbrace_on_next_line = false 58 | ij_kotlin_line_break_after_multiline_when_entry = true 59 | ij_kotlin_line_comment_add_space = false 60 | ij_kotlin_line_comment_add_space_on_reformat = false 61 | ij_kotlin_line_comment_at_first_column = true 62 | ij_kotlin_method_annotation_wrap = split_into_lines 63 | ij_kotlin_method_call_chain_wrap = normal 64 | ij_kotlin_method_parameters_new_line_after_left_paren = true 65 | ij_kotlin_method_parameters_right_paren_on_new_line = true 66 | ij_kotlin_method_parameters_wrap = on_every_item 67 | ij_kotlin_name_count_to_use_star_import = 2147483647 68 | ij_kotlin_name_count_to_use_star_import_for_members = 2147483647 69 | ij_kotlin_packages_to_use_import_on_demand = java.util.*,kotlinx.html.**,kotlinx.android.synthetic.**,io.ktor.** 70 | ij_kotlin_parameter_annotation_wrap = off 71 | ij_kotlin_space_after_comma = true 72 | ij_kotlin_space_after_extend_colon = true 73 | ij_kotlin_space_after_type_colon = true 74 | ij_kotlin_space_before_catch_parentheses = true 75 | ij_kotlin_space_before_comma = false 76 | ij_kotlin_space_before_extend_colon = true 77 | ij_kotlin_space_before_for_parentheses = true 78 | ij_kotlin_space_before_if_parentheses = true 79 | ij_kotlin_space_before_lambda_arrow = true 80 | ij_kotlin_space_before_type_colon = false 81 | ij_kotlin_space_before_when_parentheses = true 82 | ij_kotlin_space_before_while_parentheses = true 83 | ij_kotlin_spaces_around_additive_operators = true 84 | ij_kotlin_spaces_around_assignment_operators = true 85 | ij_kotlin_spaces_around_equality_operators = true 86 | ij_kotlin_spaces_around_function_type_arrow = true 87 | ij_kotlin_spaces_around_logical_operators = true 88 | ij_kotlin_spaces_around_multiplicative_operators = true 89 | ij_kotlin_spaces_around_range = false 90 | ij_kotlin_spaces_around_relational_operators = true 91 | ij_kotlin_spaces_around_unary_operator = false 92 | ij_kotlin_spaces_around_when_arrow = true 93 | ij_kotlin_use_custom_formatting_for_modifiers = true 94 | ij_kotlin_variable_annotation_wrap = off 95 | ij_kotlin_while_on_new_line = false 96 | ij_kotlin_wrap_elvis_expressions = 1 97 | ij_kotlin_wrap_expression_body_functions = 1 98 | ij_kotlin_wrap_first_method_in_call_chain = false 99 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## JIRA Ticket Link: 2 | - Please include a link to the JIRA ticket associated with this PR. 3 | 4 | ## Description: 5 | - Briefly describe the purpose of this PR and the problem it solves. 6 | 7 | ## How To Test: 8 | - Describe steps for testing these changes. 9 | - Include any specific environments, configurations, or data needed. 10 | 11 | ## Known Issues: 12 | - List any known issues or incomplete parts of this PR that need to be addressed in future work. 13 | 14 | --- 15 | 16 | ### PR Naming Convention: 17 | Please ensure the PR title follows the naming convention: `[JIRA Ticket Number] - Short Description` 18 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Artifacts to GitHub Packages 2 | 3 | on: workflow_dispatch 4 | 5 | jobs: 6 | setup-and-publish: 7 | runs-on: ${{ matrix.os }} 8 | strategy: 9 | fail-fast: false 10 | matrix: 11 | include: 12 | - os: ubuntu-latest 13 | tasks: publishAndroidReleasePublicationToGitHubPackagesRepository publishJvmPublicationToGitHubPackagesRepository publishJsPublicationToGitHubPackagesRepository publishKotlinMultiplatformPublicationToGitHubPackagesRepository 14 | - os: macos-latest 15 | tasks: publishIosArm64PublicationToGitHubPackagesRepository publishIosX64PublicationToGitHubPackagesRepository publishMacosArm64PublicationToGitHubPackagesRepository publishMacosX64PublicationToGitHubPackagesRepository publishTvosArm64PublicationToGitHubPackagesRepository publishTvosX64PublicationToGitHubPackagesRepository publishWatchosArm32PublicationToGitHubPackagesRepository publishWatchosArm64PublicationToGitHubPackagesRepository publishWatchosX64PublicationToGitHubPackagesRepository 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | with: 20 | fetch-depth: 0 21 | 22 | - name: Set up JDK 17 23 | uses: actions/setup-java@v4 24 | with: 25 | distribution: 'temurin' 26 | java-version: '17' 27 | 28 | - name: Install Linux-specific Dependencies 29 | if: matrix.os == 'ubuntu-latest' 30 | run: sudo apt-get update && sudo apt-get install -y wget unzip 31 | 32 | - name: Setup Android SDK 33 | uses: android-actions/setup-android@v3 34 | with: 35 | cmdline-tools-version: 11076708 36 | log-accepted-android-sdk-licenses: false 37 | packages: "platform-tools platforms;android-34 build-tools;34.0.0" 38 | 39 | - name: Setup Xcode 40 | if: matrix.os == 'macos-latest' 41 | uses: maxim-lobanov/setup-xcode@v1 42 | with: 43 | xcode-version: latest-stable 44 | 45 | - name: Clear npm and Yarn cache 46 | run: | 47 | npm cache clean --force 48 | yarn cache clean 49 | 50 | - name: Cache dependencies 51 | uses: actions/cache@v4 52 | with: 53 | path: | 54 | ~/.gradle/caches 55 | ~/.gradle/wrapper 56 | /usr/local/android-sdk/build-tools 57 | /usr/local/android-sdk/platforms 58 | /usr/local/android-sdk/licenses 59 | ~/.konan/cache 60 | key: ${{ runner.os }}-dependencies-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} 61 | restore-keys: | 62 | ${{ runner.os }}-dependencies- 63 | 64 | - name: Grant Execute Permission for Gradle Wrapper 65 | run: chmod +x ./gradlew 66 | 67 | - name: Build Project 68 | run: ./gradlew build 69 | 70 | - name: Publish Artifacts 71 | run: ./gradlew ${{ matrix.tasks }} --no-configuration-cache 72 | env: 73 | GH_TOKEN: ${{ secrets.GH_TOKEN }} 74 | GH_USERNAME: ${{ secrets.GH_USERNAME }} 75 | SIGNING_KEYRING: ${{ secrets.SIGNING_KEYRING }} 76 | SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} 77 | SIGNING_KEY_ID: ${{ secrets.SIGNING_KEY_ID }} 78 | -------------------------------------------------------------------------------- /.github/workflows/pipeline.yml: -------------------------------------------------------------------------------- 1 | name: CI/CD Pipeline 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - develop 7 | - main 8 | push: 9 | branches: 10 | - develop 11 | - main 12 | workflow_dispatch: 13 | permissions: 14 | contents: write 15 | 16 | jobs: 17 | prepare-matrix: 18 | runs-on: ubuntu-latest 19 | outputs: 20 | matrix: ${{ steps.set-matrix.outputs.matrix }} 21 | steps: 22 | - uses: actions/checkout@v4 23 | with: 24 | fetch-depth: 0 25 | - id: set-matrix 26 | run: | 27 | # Fetch specific commits to ensure they are available for the diff operation 28 | git fetch --depth=1 origin ${{ github.event.before }}:${{ github.event.before }} 29 | git fetch --depth=1 origin ${{ github.event.after }}:${{ github.event.after }} 30 | # Determine which directories have changed 31 | CHANGED_FILES=$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }}) 32 | MATRIX="{\"include\": [" 33 | if echo "$CHANGED_FILES" | grep -q 'appleMain/'; then 34 | MATRIX+="{\"os\":\"macos-latest\", \"files\":\"appleMain/\"}," 35 | fi 36 | if echo "$CHANGED_FILES" | grep -q 'nativeMain/'; then 37 | MATRIX+="{\"os\":\"windows-latest\", \"files\":\"nativeMain/\"}," 38 | fi 39 | MATRIX+="{\"os\":\"ubuntu-latest\", \"files\":\"always\"}" 40 | MATRIX+="]}" 41 | echo "matrix=$MATRIX" >> $GITHUB_OUTPUT 42 | 43 | build-and-test: 44 | needs: prepare-matrix 45 | runs-on: ${{ matrix.os }} 46 | strategy: 47 | fail-fast: false 48 | matrix: ${{fromJson(needs.prepare-matrix.outputs.matrix)}} 49 | steps: 50 | - uses: actions/checkout@v4 51 | with: 52 | fetch-depth: 0 53 | - name: Set up JDK 17 54 | uses: actions/setup-java@v4 55 | with: 56 | distribution: 'temurin' 57 | java-version: '17' 58 | - name: Install Linux-specific Dependencies 59 | if: matrix.os == 'ubuntu-latest' 60 | continue-on-error: true 61 | run: sudo apt-get update && sudo apt-get install -y wget unzip 62 | - name: Setup Android SDK 63 | uses: android-actions/setup-android@v3 64 | with: 65 | cmdline-tools-version: 11076708 66 | log-accepted-android-sdk-licenses: false 67 | packages: "platform-tools platforms;android-34 build-tools;34.0.0" 68 | - name: Setup Xcode 69 | if: matrix.os == 'macos-latest' 70 | uses: maxim-lobanov/setup-xcode@v1 71 | with: 72 | xcode-version: '13.1.0' 73 | - name: Clear npm and Yarn cache 74 | run: | 75 | npm cache clean --force 76 | yarn cache clean 77 | - name: Cache dependencies 78 | uses: actions/cache@v4 79 | with: 80 | path: | 81 | ~/.gradle/caches 82 | ~/.gradle/wrapper 83 | /usr/local/android-sdk/build-tools 84 | /usr/local/android-sdk/platforms 85 | /usr/local/android-sdk/licenses 86 | ~/.konan/cache 87 | key: ${{ runner.os }}-dependencies-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}-20240320 88 | restore-keys: | 89 | ${{ runner.os }}-dependencies- 90 | - name: Grant Execute Permission for Scripts 91 | run: chmod +x ./gradlew 92 | - name: Run Detekt for Code Quality Checks 93 | run: ./gradlew detektAll 94 | - name: Build Project 95 | run: ./gradlew build 96 | - name: Test Project 97 | run: ./gradlew test 98 | - name: Generate Documentation 99 | if: matrix.os == 'ubuntu-latest' && github.ref == 'refs/heads/main' 100 | run: ./gradlew dokkaHtml 101 | - name: Upload Documentation as Artifact 102 | if: matrix.os == 'ubuntu-latest' && github.ref == 'refs/heads/main' 103 | uses: actions/upload-artifact@v4 104 | with: 105 | name: documentation 106 | path: docs/docs 107 | 108 | publish-documentation: 109 | needs: build-and-test 110 | runs-on: ubuntu-latest 111 | if: github.event_name == 'push' && github.ref == 'refs/heads/main' 112 | steps: 113 | - name: Checkout 114 | uses: actions/checkout@v4 115 | with: 116 | fetch-depth: 0 117 | - name: Set up Python 118 | uses: actions/setup-python@v5 119 | with: 120 | python-version: 3.8 121 | - name: Install dependencies 122 | run: | 123 | pip install mkdocs 124 | pip install mkdocs-material 125 | pip install pymdown-extensions 126 | pip install mkdocs-minify-plugin 127 | pip install mkdocs-git-revision-date-localized-plugin 128 | - name: Download Documentation Artifact 129 | uses: actions/download-artifact@v4 130 | with: 131 | name: documentation 132 | path: docs/docs 133 | - name: Build Website 134 | run: | 135 | pip install mkdocs-material mkdocs-macros-plugin 136 | mkdocs build 137 | - name: Deploy Documentation 138 | uses: JamesIves/github-pages-deploy-action@releases/v3 139 | with: 140 | BRANCH: gh-pages 141 | FOLDER: site 142 | SINGLE_COMMIT: true -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled source # 2 | *.class 3 | *.jar 4 | *.war 5 | *.ear 6 | *.out 7 | 8 | # Build artifacts # 9 | build/ 10 | out/ 11 | **/build/ 12 | local-build-outputs/ 13 | .kotlin 14 | 15 | # Gradle # 16 | .gradle/ 17 | !gradle/wrapper/gradle-wrapper.jar 18 | local.properties 19 | 20 | # IntelliJ IDEA & Android Studio # 21 | .idea/ 22 | *.iml 23 | *.ipr 24 | *.iws 25 | *.idea_modules/ 26 | captures/ 27 | navigation/ 28 | 29 | # VS Code # 30 | .vscode/ 31 | 32 | # macOS # 33 | .DS_Store 34 | 35 | # Logs # 36 | *.log 37 | *.log.* 38 | logs/ 39 | 40 | # Node # 41 | node_modules/ 42 | 43 | # Special Mkdocs files # 44 | /site 45 | docs/[0-9]* 46 | docs/docs 47 | 48 | # Misc # 49 | *.nar 50 | *.tar.gz 51 | *.sql 52 | *.sqlite 53 | *.swp 54 | *.swo 55 | *.tmp 56 | *.bak 57 | *.swbackup 58 | *.sav 59 | *.tgz 60 | *.gzip 61 | *.bzip2 62 | *.zip 63 | *.rar 64 | *.7z 65 | *.gz 66 | *.xz 67 | *.exe 68 | *.dll 69 | *.so 70 | *.dylib 71 | *.test 72 | *.hprof 73 | 74 | # Specific directory inclusion # 75 | !buildSrc/src/main/kotlin/build/ 76 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Our Project 2 | 3 | Thank you for your interest in contributing! We're excited to have you join our community. Everyone 4 | is welcome to contribute, whether you're fixing bugs, adding features, or improving documentation. 5 | Here's how you can get started: 6 | 7 | ### Start with a Fork 8 | 9 | Feel free to fork this repository if you want to make substantial changes. This lets you tweak the 10 | project as much as you like in your own version while still allowing you to contribute back to the 11 | main project. 12 | 13 | ### Making Contributions 14 | 15 | 1. **Agree to Our Contributor License Agreement (CLA):** Before your contributions can be accepted, 16 | please sign our [CLA][CLA]. This ensures there are no legal hitches with your submissions. 17 | 18 | 2. **Make Your Changes:** Work on your forked version of the repository and make your changes. Try 19 | to keep your updates clear and stick to the project's existing style as much as you can. 20 | 21 | 3. **Submit a Pull Request:** Once you're ready, send us a pull request. Describe what you've done 22 | and how it affects the project. We're eager to see your ideas! 23 | 24 | ### What Happens Next? 25 | 26 | We'll review your pull request as soon as we can. We appreciate every contribution, but sometimes 27 | changes might not align perfectly with our project's direction. We'll discuss potential adjustments 28 | with you, so your hard work can still be part of the project. 29 | 30 | ## Keep Your Fork Updated 31 | 32 | Even if your changes don't make it into the project, keep your fork active! Your unique tweaks could 33 | inspire others, and you might find ways to integrate your changes over time. 34 | 35 | ## Got Questions or Suggestions? 36 | 37 | If you have questions or suggestions, please open an issue in the repository. We're always looking 38 | to improve and love hearing from the community. 39 | 40 | Thank you for helping us make this project better. We can't wait to see what you bring to the table! 41 | 42 | [CLA]: https://forms.gle/J5iqyH4hrHQQDfUCA 43 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # kmmify - Kotlin Multiplatform Library Template 2 | 3 | Welcome to kmmify, a comprehensive template designed to jumpstart your Kotlin Multiplatform library 4 | projects. This template simplifies the creation and maintenance of cross-platform libraries, 5 | enabling shared business logic across multiple platforms including iOS, Android, Web, and various 6 | native platforms like Linux, watchOS, and tvOS. Kmmify is the perfect starting point for developers 7 | looking to build robust, multiplatform solutions efficiently. 8 | 9 | ![kmmify](.art/kmmify.webp) 10 | 11 | [![Style Guide-Kotlin](https://img.shields.io/badge/Style%20Guide-Kotlin-7F52FF.svg?style=flat&labelColor=black&color=7F52FF&logo=kotlin)](https://styles.goatbytes.io/lang/kotlin) 12 | ![License](https://img.shields.io/badge/License-Apache%20V2.0-blue) 13 | ![Platform](https://img.shields.io/badge/Platform-Android%20|%20iOS%20|%20Desktop%20|%20Web-green) 14 | 15 | ## Key Features 16 | 17 | - **Extensive Multiplatform Support:** Configured for Android, iOS, Web, and Native platforms 18 | (including Linux, watchOS, and tvOS), ensuring broad compatibility and versatility. 19 | - **Pre-configured Build System:** Includes ready-to-use Gradle scripts for building and testing 20 | your libraries. 21 | - **Code Quality Assurance:** Set up with Detekt for static code analysis to maintain high code 22 | standards. 23 | - **Documentation Ready:** Integrated with MkDocs and Dokka for generating comprehensive project 24 | documentation. 25 | - **Release Signing:** Sign your artifacts before publishing for enhanced security and integrity. 26 | - **GitHub Packages Publishing:** Easily publish your library to GitHub Packages with a single 27 | command. 28 | - **CI/CD Ready:** Integrated with GitHub Actions for automated testing and deployment. 29 | 30 | ## Quick Start Guide 31 | 32 | ### Prerequisites 33 | 34 | - Kotlin Multiplatform compatible IDE (IntelliJ IDEA recommended) 35 | 36 | ### Repository Setup 37 | 38 | 1. Click on the **Use this template** button to create a new repository from this template. 39 | 2. Clone the repository to your local machine using the following command: 40 | ```shell 41 | git clone https://github.com/goatbytes/kmmify.git 42 | ``` 43 | 3. Modify the [`BuildConfig.kt`](buildSrc/src/main/kotlin/BuildConfig.kt) file with your project 44 | details. 45 | 46 | ### Static Code Analysis with Detekt 47 | 48 | Run Detekt to ensure code quality: 49 | 50 | ```shell 51 | ./gradlew detektAll 52 | ``` 53 | 54 | ### Generate Documentation 55 | 56 | Generate project documentation using Dokka: 57 | 58 | ```shell 59 | ./gradlew dokkaHtml 60 | ``` 61 | 62 | ### Publish Documentation to GitHub Pages 63 | 64 | 1. Install `mkdocs`: 65 | ```shell 66 | pip install mkdocs mkdocs-material pymdown-extensions mkdocs-minify-plugin mkdocs-git-revision-date-localized-plugin 67 | ``` 68 | 2. Serve the documentation locally: 69 | ```shell 70 | mkdocs serve 71 | ``` 72 | 3. Access the documentation at `http://localhost:8000`. 73 | 4. Publish the documentation to GitHub Pages: 74 | ```shell 75 | mkdocs gh-deploy 76 | ``` 77 | 78 | ### Secure Publishing with Release Signing 79 | 80 | Ensure your library is securely published by signing your artifacts before release: 81 | 82 | #### Setup for Release Signing 83 | 84 | To sign your releases, you need to generate signing keys. You can use tools like GPG or OpenSSL. 85 | Then ensure the following properties are set in your `~/.gradle/gradle.properties` or passed via 86 | environment variables: 87 | 88 | - SIGNING_KEY_ID 89 | - SIGNING_KEYRING 90 | - SIGNING_PASSWORD 91 | 92 | ## Contributing 93 | 94 | Contributions are welcome! Please read our [contributing guide](CONTRIBUTING.md) and submit pull 95 | requests to our repository. 96 | 97 | ## License 98 | 99 | Distributed under the Apache v2.0 License. See `LICENSE.txt` for more information. 100 | 101 | ## About GoatBytes.IO 102 | 103 | ![GoatBytesLogo](.art/banner.webp) 104 | 105 | At **GoatBytes.IO**, our mission is to develop secure software solutions that empower businesses to 106 | transform the world. With a focus on innovation and excellence, we strive to deliver cutting-edge 107 | products that meet the evolving needs of businesses across various industries. 108 | 109 | [![GitHub](https://img.shields.io/badge/GitHub-GoatBytes-181717?logo=github)](https://github.com/goatbytes) 110 | [![Twitter](https://img.shields.io/badge/Twitter-GoatBytes-1DA1F2?logo=twitter)](https://twitter.com/goatbytes) 111 | [![LinkedIn](https://img.shields.io/badge/LinkedIn-GoatBytes-0077B5?logo=linkedin)](https://www.linkedin.com/company/goatbytes) 112 | [![Instagram](https://img.shields.io/badge/Instagram-GoatBytes.io-E4405F?logo=instagram)](https://www.instagram.com/goatbytes.io/) 113 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Use this section to let people know which versions of your project are currently being supported 6 | with security updates. 7 | 8 | | Version | Supported | 9 | |---------|--------------------| 10 | | 1.2.x | :white_check_mark: | 11 | | 1.1.x | :white_check_mark: | 12 | | 1.0.x | :x: | 13 | | < 1.0 | :x: | 14 | 15 | ## Reporting a Vulnerability 16 | 17 | Your contributions to the security of our project are greatly appreciated. If you've discovered a 18 | security vulnerability within the project, we encourage you to report it as soon as possible. Please 19 | follow these guidelines to communicate the issue responsibly. 20 | 21 | ### How to Report a Security Vulnerability? 22 | 23 | If you believe you have found a security vulnerability, please send us an email 24 | at [security@goatbytes.io](mailto:security@goatbytes.io). Provide a clear description of the issue, 25 | including how it can be reproduced, and, if possible, a code snippet or an executable test case 26 | demonstrating the vulnerability. 27 | 28 | ### What to Expect 29 | 30 | After submitting a vulnerability report, you should receive an acknowledgment of your report within 31 | 48 hours. Following this, the team will: 32 | 33 | - Review your report and determine whether the vulnerability can be confirmed. 34 | - Assign a severity level to the vulnerability according to its impact and urgency. 35 | - Notify you of the progress towards a fix and full announcement. 36 | - Work to remediate the issue through mutual agreement, ensuring that a fix is confirmed and an 37 | update is prepared and deployed. 38 | 39 | ### Public Disclosure Timing 40 | 41 | Please keep your vulnerability report confidential until we have completed the fix and rollout 42 | process. The timeline for public disclosure depends on the severity of the issue and may involve 43 | coordinating with stakeholders and industry partners. 44 | 45 | We strive to resolve all security issues in a timely and transparent manner. Collaboration and 46 | communication during the vulnerability disclosure process are vital. We appreciate your help in 47 | keeping our project safe and secure for everyone. 48 | 49 | ## More Information 50 | 51 | For more information on how to contribute or other ways to get involved with the project, check out 52 | our [CONTRIBUTING.md](./CONTRIBUTING.md). 53 | 54 | Thank you for supporting our project and helping us ensure the security and reliability of our code! 55 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | import io.gitlab.arturbosch.detekt.Detekt 19 | import io.gitlab.arturbosch.detekt.DetektCreateBaselineTask 20 | 21 | BuildConfig.initialize(project) 22 | 23 | plugins { 24 | alias(libs.plugins.android.library).apply(false) 25 | alias(libs.plugins.kotlin.multiplatform).apply(false) 26 | alias(libs.plugins.detekt) 27 | } 28 | 29 | allprojects { 30 | group = BuildConfig.GROUP 31 | version = BuildConfig.VERSION 32 | } 33 | 34 | dependencies { 35 | detektPlugins(libs.detekt.formatting) 36 | } 37 | 38 | detekt { 39 | buildUponDefaultConfig = true 40 | config.setFrom(BuildConfig.Detekt.CONFIG) 41 | } 42 | 43 | tasks.withType().configureEach { 44 | jvmTarget = BuildConfig.Detekt.jvmTarget 45 | } 46 | 47 | tasks.withType().configureEach { 48 | jvmTarget = BuildConfig.Detekt.jvmTarget 49 | reports { 50 | html.required.set(true) 51 | md.required.set(true) 52 | sarif.required.set(false) 53 | txt.required.set(false) 54 | xml.required.set(false) 55 | } 56 | } 57 | 58 | val detektAll by tasks.registering(Detekt::class) { 59 | description = "Run detekt analysis on entire project" 60 | parallel = true 61 | buildUponDefaultConfig = true 62 | config.setFrom(BuildConfig.Detekt.CONFIG) 63 | setSource(files(projectDir)) 64 | include("**/*.kt", "**/*.kts") 65 | exclude("resources/", "*/build/*") 66 | } 67 | -------------------------------------------------------------------------------- /buildSrc/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | plugins { 19 | `kotlin-dsl` 20 | } 21 | 22 | repositories { 23 | mavenCentral() 24 | gradlePluginPortal() 25 | } 26 | 27 | dependencies { 28 | compileOnly(kotlin("gradle-plugin")) 29 | compileOnly(kotlin("gradle-plugin-api")) 30 | implementation(libs.nexus.publish) 31 | } 32 | -------------------------------------------------------------------------------- /buildSrc/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | pluginManagement { 19 | repositories { 20 | google() 21 | gradlePluginPortal() 22 | mavenCentral() 23 | } 24 | } 25 | 26 | dependencyResolutionManagement { 27 | @Suppress("UnstableApiUsage") 28 | repositories { 29 | google() 30 | gradlePluginPortal() 31 | mavenCentral() 32 | } 33 | 34 | versionCatalogs { 35 | create("libs") { 36 | from(files("../gradle/libs.versions.toml")) 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/BuildConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | import org.gradle.api.JavaVersion 19 | import org.gradle.api.Project 20 | import java.io.File 21 | import java.time.LocalDateTime 22 | import java.time.format.DateTimeFormatter 23 | 24 | /** 25 | * Contains build configuration properties for the project. 26 | */ 27 | object BuildConfig { 28 | 29 | const val NAME = "kmmify" 30 | const val URL = "https://${SCM.ORG}.github.io/${SCM.NAME}" 31 | const val DESCRIPTION = "A Kotlin Multiplatform Template" 32 | 33 | const val GROUP = "io.goatbytes.kmmify" 34 | val VERSION by lazy { Version.get(project) } 35 | 36 | /** 37 | * Version Update Instructions: 38 | * 39 | * - IDENTIFIER: Indicate the current stage of release (Alpha, Beta, RC, or Release) 40 | * based on the software's readiness for deployment. 41 | * - MAJOR: Increment for incompatible API changes. Resets minor and patch levels to 0. 42 | * - MINOR: Increment for adding functionality in a backwards-compatible manner. 43 | * Resets the patch level to 0. 44 | * - PATCH: Increment for making backwards-compatible bug fixes. 45 | * - BUILD_NUMBER: Increment with each build to uniquely identify it. 46 | * 47 | * Refer to the Semantic Versioning specification at https://semver.org/ for detailed guidelines. 48 | */ 49 | object Version { 50 | private const val MAJOR = 0 51 | private const val MINOR = 0 52 | private const val PATCH = 1 53 | private const val BUILD_NUMBER = 0 54 | private val IDENTIFIER = build.Version.Identifier.SNAPSHOT 55 | 56 | private val BUILD_TIME_PATTERN: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHH") 57 | 58 | /** 59 | * Generates the project version using semantic versioning. 60 | * 61 | * @param project The project 62 | * @return The project version 63 | */ 64 | fun get(project: Project) = build.Version.Semantic( 65 | major = MAJOR, 66 | minor = MINOR, 67 | patch = PATCH, 68 | identifier = IDENTIFIER, 69 | metadata = build.Version.Metadata( 70 | buildNumber = BUILD_NUMBER, 71 | gitSha = project.gitCommitSha, 72 | gitBranch = project.gitBranchName, 73 | buildTime = LocalDateTime.now().format(BUILD_TIME_PATTERN) 74 | ) 75 | ) 76 | } 77 | 78 | /** 79 | * Contains the License name and URL for the project 80 | */ 81 | object License { 82 | const val NAME = "Apache v2.0" 83 | const val URL = "https://${SCM.PATH}/blob/main/LICENSE.txt" 84 | } 85 | 86 | private lateinit var project: Project 87 | 88 | /** 89 | * Android Build Configuration 90 | */ 91 | object Android { 92 | const val NAMESPACE = "$GROUP.android" 93 | const val COMPILE_SDK = 34 94 | const val MIN_SDK = 24 95 | val javaVersion = JavaVersion.VERSION_1_8 96 | } 97 | 98 | /** 99 | * Apple Target Build Configuration 100 | */ 101 | object Apple { 102 | const val FRAMEWORK_NAME = NAME 103 | } 104 | 105 | /** 106 | * Contains configuration for Detekt static analysis plugin. 107 | */ 108 | object Detekt { 109 | val CONFIG by lazy { "${project.rootDir}/detekt.yml" } 110 | val jvmTarget = JavaVersion.VERSION_1_8.toString() 111 | } 112 | 113 | /** 114 | * Contains constants for Dokka 115 | */ 116 | object Dokka { 117 | const val DOC_LINK = "https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/" 118 | const val PKG_LIST = "https://kotlin.github.io/kotlinx.coroutines/package-list" 119 | val outputDirectory: File get() = project.file("${project.rootDir}/docs/docs") 120 | } 121 | 122 | /** 123 | * Defines constants for SCM (Software Configuration Management) related to the project. 124 | */ 125 | object SCM { 126 | /** Host of the SCM. */ 127 | const val HOST = "github.com" 128 | 129 | /** Organization name within the SCM. */ 130 | const val ORG = "goatbytes" 131 | 132 | /** Project name within the SCM. */ 133 | const val NAME = "kmmify" 134 | 135 | /** Full SCM path constructed from host, organization, and project name. */ 136 | const val PATH = "$HOST/$ORG/$NAME" 137 | } 138 | 139 | /** 140 | * Contains the developer metadata for the POM. 141 | */ 142 | object Developer { 143 | const val ID = "goatbytes" 144 | const val NAME = "GoatBytes.IO" 145 | const val EMAIL = "engineering@goatbytes.io" 146 | const val URL = "https://goatbytes.io" 147 | const val TIMEZONE = "America/Los_Angeles" 148 | } 149 | 150 | /** 151 | * Initialize the [BuildConfig] to reference the root project 152 | * 153 | * @param rootProject The root project 154 | * @return The [BuildConfig] for chaining any method calls. 155 | */ 156 | fun initialize(rootProject: Project) = apply { 157 | project = rootProject 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/build/Arch.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package build 19 | 20 | /** 21 | * Represents the architecture types that can be identified. 22 | */ 23 | enum class Arch { 24 | X64, Arm32, Arm64; 25 | companion object { 26 | /** The current architecture. */ 27 | val current: Arch by lazy { 28 | val arch = System.getProperty("os.arch").lowercase() 29 | when { 30 | "amd64" in arch || "x86_64" in arch -> X64 31 | "arm" in arch || "arm32" in arch -> Arm32 32 | "aarch64" in arch -> Arm64 33 | else -> error("Unsupported build environment: $arch") 34 | } 35 | } 36 | val isX64 get() = current == X64 37 | val isArm32 get() = current == Arm32 38 | val isArm64 get() = current == Arm64 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/build/CIPlatform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package build 19 | 20 | /** 21 | * Enum class representing supported CI/CD platforms. It provides utility methods to detect the 22 | * current CI/CD platform and to fetch the branch name and commit SHA based on platform-specific 23 | * environment variables. 24 | * 25 | * @param detectionVar The environment variable used to detect if running on the specific CI/CD platform. 26 | * @param branchNameVar The environment variable that stores the git branch name on this platform. 27 | * @param commitShaVar The environment variable that stores the git commit SHA on this platform. 28 | */ 29 | enum class CIPlatform( 30 | private val detectionVar: String, 31 | private val branchNameVar: String, 32 | private val commitShaVar: String 33 | ) { 34 | /** 35 | * GitHub Actions is GitHub's automation and CI/CD platform, allowing users to automate workflows 36 | * directly from their GitHub repositories. 37 | * More info: https://github.com/features/actions 38 | */ 39 | GITHUB_ACTIONS("GITHUB_ACTIONS", "GITHUB_REF_NAME", "GITHUB_SHA"), 40 | 41 | /** 42 | * GitLab CI/CD is integrated into GitLab and provides a well-supported platform for automating 43 | * the build, test, and deployment of your applications. 44 | * More info: https://docs.gitlab.com/ee/ci/ 45 | */ 46 | GITLAB_CI("GITLAB_CI", "CI_COMMIT_REF_NAME", "CI_COMMIT_SHA"), 47 | 48 | /** 49 | * Jenkins is an open-source automation server that provides hundreds of plugins to support 50 | * building, deploying, and automating any project. 51 | * More info: https://www.jenkins.io/ 52 | */ 53 | JENKINS("JENKINS_URL", "GIT_BRANCH", "GIT_COMMIT"), 54 | 55 | /** 56 | * CircleCI offers cloud-based CI/CD services to automate the software development process. 57 | * It is known for its flexibility and scalability. 58 | * More info: https://circleci.com/ 59 | */ 60 | CIRCLE_CI("CIRCLECI", "CIRCLE_BRANCH", "CIRCLE_SHA1"), 61 | 62 | /** 63 | * Bitbucket Pipelines is Bitbucket's integrated tool for CI/CD, directly configured through a 64 | * YAML file in the Bitbucket repository. 65 | * More info: https://bitbucket.org/product/features/pipelines 66 | */ 67 | BITBUCKET_PIPELINES("BITBUCKET_COMMIT", "BITBUCKET_BRANCH", "BITBUCKET_COMMIT"), 68 | 69 | /** 70 | * Travis CI is a cloud-based CI service that automatically builds and tests code changes, 71 | * offering seamless integration with GitHub. 72 | * More info: https://travis-ci.com/ 73 | */ 74 | TRAVIS_CI("TRAVIS", "TRAVIS_BRANCH", "TRAVIS_COMMIT"), 75 | 76 | /** 77 | * Azure Pipelines is a part of Azure DevOps Services, providing CI/CD that works with any 78 | * language, platform, and cloud. 79 | * More info: https://azure.microsoft.com/en-us/services/devops/pipelines/ 80 | */ 81 | AZURE_PIPELINES("TF_BUILD", "BUILD_SOURCEBRANCHNAME", "BUILD_SOURCEVERSION"), 82 | 83 | /** 84 | * Bamboo by Atlassian is a CI/CD server that integrates with other Atlassian products. It is 85 | * known for its build and deployment projects management. 86 | * More info: https://www.atlassian.com/software/bamboo 87 | */ 88 | BAMBOO("bamboo_planKey", "bamboo_repository_branch_name", "bamboo_planRepository_revision"), 89 | 90 | /** 91 | * TeamCity by JetBrains is a powerful CI/CD server known for its ease of setup, comprehensive 92 | * build, test, and deployment features. 93 | * More info: https://www.jetbrains.com/teamcity/ 94 | */ 95 | TEAMCITY("TEAMCITY_VERSION", "env.BRANCH_NAME", "build.vcs.number"), 96 | 97 | /** 98 | * Bitrise is a Mobile Continuous Integration and Delivery CI/CD for mobile app development, known 99 | * for its excellent support for iOS, Android, Flutter, and React Native projects. 100 | * More info: https://www.bitrise.io/ 101 | */ 102 | BITRISE("BITRISE_IO", "BITRISE_GIT_BRANCH", "BITRISE_GIT_COMMIT"); 103 | 104 | companion object { 105 | /** 106 | * Detects the current CI/CD platform based on the presence of a platform-specific environment variable. 107 | * 108 | * @return The detected [CIPlatform] or `null` if the platform is not recognized. 109 | */ 110 | fun detect(): CIPlatform? = values().firstOrNull { System.getenv(it.detectionVar) != null } 111 | } 112 | 113 | /** 114 | * Gets the git branch name for the current CI/CD platform. 115 | * 116 | * @return The branch name if available and applicable for the detected platform, otherwise `null`. 117 | */ 118 | fun getBranchName(): String? = System.getenv(branchNameVar) 119 | 120 | /** 121 | * Gets the git commit SHA for the current CI/CD platform. 122 | * 123 | * @return The commit SHA if available and applicable for the detected platform, otherwise `null`. 124 | */ 125 | fun getCommitSha(): String? = System.getenv(commitShaVar) 126 | } 127 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/build/Os.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package build 19 | 20 | /** 21 | * Represents the operating system types that can be identified. 22 | */ 23 | enum class Os { 24 | Mac, Windows, Linux; 25 | companion object { 26 | /** The current operating system. */ 27 | val current: Os by lazy { 28 | val osName = System.getProperty("os.name").lowercase() 29 | when { 30 | "mac" in osName -> Mac 31 | "linux" in osName -> Linux 32 | "windows" in osName -> Windows 33 | else -> error("Unsupported build environment: $osName") 34 | } 35 | } 36 | val isLinux get() = current == Linux 37 | val isWindows get() = current == Windows 38 | val isMacOS get() = current == Mac 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/build/Version.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024 GoatBytes.IO. All rights reserved. 3 | * 4 | * This file is part of peopledatalabs-kotlin project by GoatBytes.IO and is released under the 5 | * GoatBytes.IO PDL Software License Agreement. 6 | * 7 | * For details, see the LICENSE.md file in the root of the project or contact legal@goatbytes.io 8 | * for a full copy. 9 | * 10 | * RESTRICTIONS: This software is provided for internal use only. Unauthorized use, copying, 11 | * modification, or distribution of this software is strictly prohibited. This software is offered 12 | * "AS IS", without warranties of any kind, and subject to the limitations stated in the license 13 | * agreement. 14 | * 15 | */ 16 | 17 | package build 18 | 19 | import build.Version.Identifier.Alpha 20 | import build.Version.Identifier.Beta 21 | import build.Version.Identifier.RC 22 | import build.Version.Identifier.SNAPSHOT 23 | 24 | /** 25 | * Represents a base class for different versioning strategies. 26 | */ 27 | sealed class Version { 28 | 29 | /** Represents the version as a human-readable string. */ 30 | abstract val name: String 31 | 32 | /** Represents the version as a unique, sortable numeric code. */ 33 | abstract val code: Long 34 | 35 | /** Enumerates common pre-release identifiers for software versions. */ 36 | enum class Identifier { 37 | Alpha, Beta, RC, Release, SNAPSHOT 38 | } 39 | 40 | /** 41 | * Contains metadata related to the build or version, including Git information and build timing. 42 | * 43 | * @property buildNumber An incremental number representing the sequence of the build. 44 | * @property gitSha The Git SHA hash of the commit from which the build was created. 45 | * @property gitBranch The name of the Git branch from which the build was created. 46 | * @property buildTime The timestamp representing when the build was created. 47 | */ 48 | data class Metadata( 49 | val buildNumber: Int?, 50 | val gitSha: String?, 51 | val gitBranch: String?, 52 | val buildTime: String?, 53 | ) 54 | 55 | /** 56 | * Represents a semantic version, including major, minor, and patch levels, along with optional 57 | * pre-release identifiers and metadata. 58 | * 59 | * @property major The major version number, indicating incompatible API changes. 60 | * @property minor The minor version number, indicating added functionality in a backwards-compatible manner. 61 | * @property patch The patch version number, indicating backwards-compatible bug fixes. 62 | * @property identifier An optional pre-release identifier to denote version stability. 63 | * @property metadata Optional additional metadata providing context about the build or version. 64 | */ 65 | data class Semantic( 66 | val major: Int, 67 | val minor: Int, 68 | val patch: Int, 69 | val identifier: Identifier? = null, 70 | val metadata: Metadata? = null 71 | ) : Version() { 72 | 73 | override val name by lazy { 74 | "$major.$minor.$patch${preRelease()}${buildMetadata()}" 75 | } 76 | 77 | override val code: Long 78 | get() { 79 | val majorPart = major * MAJOR_MULTIPLIER 80 | val minorPart = minor * MINOR_MULTIPLIER 81 | val patchPart = patch * PATCH_MULTIPLIER 82 | val identifierPart = (identifier?.ordinal ?: 0) * IDENTIFIER_MULTIPLIER 83 | val buildNumberPart = metadata?.buildNumber?.toLong() ?: 0L 84 | return majorPart + minorPart + patchPart + identifierPart + buildNumberPart 85 | } 86 | 87 | override fun toString() = name 88 | 89 | private fun preRelease(): String = when (identifier) { 90 | Identifier.Release, null -> "" 91 | SNAPSHOT -> "-SNAPSHOT" 92 | else -> "-${identifier.name.lowercase()}" 93 | } 94 | 95 | private fun buildMetadata() = buildString { 96 | when (identifier) { 97 | Alpha, Beta, RC, SNAPSHOT -> metadata?.run { 98 | var separator = "+" 99 | listOf( 100 | buildNumber?.takeIf { it > 0 }, 101 | buildTime, 102 | gitBranch?.takeIf { it !in listOf("main") && !it.contains("/") }, 103 | gitSha 104 | ).mapNotNull { it }.forEach { data -> 105 | append(separator).append(data).also { separator = "." } 106 | } 107 | } 108 | else -> { 109 | // no-op 110 | } 111 | } 112 | } 113 | 114 | private companion object { 115 | private const val MAJOR_MULTIPLIER = 1_000_000_000_000L 116 | private const val MINOR_MULTIPLIER = 1_000_000_000L 117 | private const val PATCH_MULTIPLIER = 1_000_000L 118 | private const val IDENTIFIER_MULTIPLIER = 100_000L 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/extensions.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | @file:Suppress("Filename") 19 | 20 | import build.CIPlatform 21 | import org.gradle.api.NamedDomainObjectContainer 22 | import org.gradle.api.Project 23 | import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension 24 | import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet 25 | import java.util.* 26 | 27 | val Project.gitBranchName: String 28 | get() = CIPlatform.detect()?.getBranchName() ?: exec( 29 | "git branch --show-current || git symbolic-ref --short HEAD || echo 'unknown'" 30 | ) 31 | 32 | val Project.gitCommitSha: String 33 | get() = CIPlatform.detect()?.getCommitSha() ?: exec( 34 | "git --no-pager log -1 --format=%h || git rev-parse --short HEAD || echo 'unknown'" 35 | ) 36 | 37 | /** 38 | * Executes a single command line specified as a string. 39 | * 40 | * @param command string representing the command to execute and its arguments, separated by spaces. 41 | * @return The command's output as a string. 42 | */ 43 | fun Project.exec(command: String) = external.CommandLine(this).execute(command).stdout 44 | 45 | /** 46 | * Sets up all Apple targets for a multiplatform module. 47 | * 48 | * @param baseName The name of the framework 49 | */ 50 | @Suppress("NOTHING_TO_INLINE") 51 | inline fun KotlinMultiplatformExtension.appleTargetsWithFramework(baseName: String) { 52 | val iosTargets = listOf(iosX64(), iosArm64()) 53 | val macosTargets = listOf(macosX64(), macosArm64()) 54 | val tvosTargets = listOf(tvosX64(), tvosArm64()) 55 | val watchosTargets = listOf(watchosX64(), watchosArm64(), watchosArm32()) 56 | val targets = iosTargets + macosTargets + tvosTargets + watchosTargets 57 | targets.forEach { target -> 58 | target.binaries.framework { 59 | this.baseName = baseName 60 | this.freeCompilerArgs += "-Xbinary=bundleId=${BuildConfig.GROUP}.kotlin" 61 | } 62 | } 63 | } 64 | 65 | /** 66 | * Returns a copy of this string having its first letter title-cased using the rules of the default 67 | * locale, or the original string if it's empty or already starts with a title case letter. 68 | */ 69 | fun String.capitalize() = 70 | replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } 71 | 72 | inline val NamedDomainObjectContainer.androidUnitTest 73 | get(): KotlinSourceSet = getByName("androidUnitTest") 74 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/external/CommandLine.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package external 19 | 20 | import org.gradle.api.Project 21 | import org.gradle.api.provider.ListProperty 22 | import org.gradle.api.provider.ValueSource 23 | import org.gradle.api.provider.ValueSourceParameters 24 | import org.gradle.process.ExecOperations 25 | import java.io.ByteArrayOutputStream 26 | import javax.inject.Inject 27 | 28 | /** 29 | * A class for executing commands in Gradle and capturing their output. 30 | * 31 | * This class provides a convenient way to run commands within Gradle builds 32 | * and access the standard output, standard error, and exit code of the executed command. 33 | */ 34 | class CommandLine(private val project: Project) { 35 | 36 | /** 37 | * Executes a command in the shell and returns the result. 38 | * 39 | * This function takes a variable number of strings as arguments, representing 40 | * the command and its arguments. It constructs a [Source] object with these arguments 41 | * and retrieves the execution result using Gradle's provider mechanism. 42 | * 43 | * @param command The command and its arguments as a list of strings. 44 | * @return A [Result] object containing the standard output, standard error, 45 | * and exit code of the executed command. 46 | */ 47 | fun execute(vararg command: String): Result = project.providers.of(Source::class.java) { 48 | parameters.commands.set(listOf("sh", "-c") + command.toList()) 49 | }.get() 50 | 51 | /** 52 | * An interface extending ValueSourceParameters, meant to specify parameters for 53 | * [CommandLineValueSource]. It includes a commands parameter, representing the executable and 54 | * its arguments as a list of strings. 55 | * 56 | * Example: 57 | * To execute a git status command: 58 | * 59 | * ```kotlin 60 | * spec.parameters.commands.set(listOf("git", "status")) 61 | * ``` 62 | */ 63 | interface Params : ValueSourceParameters { 64 | /** A list property containing the command and its arguments as strings. */ 65 | val commands: ListProperty 66 | } 67 | 68 | /** 69 | * The result of executing a command in a shell. 70 | * 71 | * @property stdout The standard output 72 | * @property stderr The standard error 73 | * @property exitCode The exit status of the command 74 | */ 75 | data class Result( 76 | val stdout: String, 77 | val stderr: String, 78 | val exitCode: Int 79 | ) { 80 | /** If the command returned a success status code */ 81 | val isSuccess = exitCode == 0 82 | } 83 | 84 | /** 85 | * This ValueSource implementation allows for the execution of command-line operations within 86 | * Gradle's configuration phase and captures their output. Utilizing Gradle's ExecOperations, it 87 | * executes a specified command line and returns the output as a string. 88 | * 89 | * Usage: 90 | * 91 | * ```kotlin 92 | * val commandOutput: String = project.providers.of(CommandLine.Source::class.java) { 93 | * parameters.commands.set(listOf("echo", "Hello, World!")) 94 | * }.get() 95 | * println("Command Output: $commandOutput") 96 | * ``` 97 | */ 98 | abstract class Source : ValueSource { 99 | 100 | @get:Inject 101 | abstract val execOperations: ExecOperations 102 | 103 | override fun obtain(): Result { 104 | val stdout = ByteArrayOutputStream() 105 | val stderr = ByteArrayOutputStream() 106 | try { 107 | val result = execOperations.exec { 108 | commandLine(parameters.commands.get()) 109 | environment(System.getenv()) 110 | standardOutput = stdout 111 | errorOutput = stderr 112 | } 113 | return Result( 114 | stdout = stdout.toString(Charsets.UTF_8).trim(), 115 | stderr = stderr.toString(Charsets.UTF_8).trim(), 116 | exitCode = result.exitValue 117 | ) 118 | } finally { 119 | stdout.close() 120 | stderr.close() 121 | } 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/publication/SigningConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package publication 19 | 20 | import org.gradle.api.Project 21 | 22 | /** 23 | * Represents the configuration for signing artifacts, encapsulating necessary details. 24 | * 25 | * @property keyId The ID of the signing key. 26 | * @property keyRing The location of the keyring containing the signing key. 27 | * @property password The password for accessing the signing key. 28 | */ 29 | sealed class SigningConfig( 30 | val keyId: String, 31 | val keyRing: String, 32 | val password: String 33 | ) { 34 | 35 | /** 36 | * Specific signing configuration for the release publication. 37 | * 38 | * @param project The Gradle project context to derive properties from. 39 | */ 40 | class Release(project: Project) : SigningConfig( 41 | keyId = project prop KEY_ID, 42 | keyRing = project prop KEYRING, 43 | password = project prop PASSWORD 44 | ) { 45 | companion object { 46 | 47 | /** 48 | * Checks if the necessary signing credentials are present in the project's properties 49 | * or environment variables. 50 | * 51 | * @param project The Gradle project to check for properties. 52 | * @return True if all required credentials are available; false otherwise. 53 | */ 54 | fun hasCredentials(project: Project): Boolean { 55 | return listOf(KEY_ID, KEYRING, PASSWORD).all { name -> project hasPropOrEnv name } 56 | } 57 | 58 | private const val KEY_ID = "SIGNING_KEY_ID" 59 | private const val KEYRING = "SIGNING_KEYRING" 60 | private const val PASSWORD = "SIGNING_PASSWORD" 61 | } 62 | } 63 | 64 | private companion object { 65 | /** 66 | * Retrieves a project property or environment variable value by name. 67 | * 68 | * @param name The name of the property or environment variable to retrieve. 69 | * @return The value of the property or environment variable. 70 | */ 71 | private infix fun Project.prop(name: String): String { 72 | return (System.getenv(name) ?: findProperty(name)) as String 73 | } 74 | 75 | /** 76 | * Checks if a property or environment variable is present. 77 | * 78 | * @param name The name of the property or environment variable to check. 79 | * @return True if the property or environment variable is present; false otherwise. 80 | */ 81 | private infix fun Project.hasPropOrEnv(name: String): Boolean { 82 | return hasProperty(name) || System.getenv(name) != null 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/publication/gh-packages.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | @file:Suppress("FunctionName") 19 | 20 | package publication 21 | 22 | import BuildConfig 23 | import BuildConfig.Developer 24 | import BuildConfig.SCM 25 | import java.net.URI 26 | 27 | plugins { 28 | `maven-publish` 29 | signing 30 | } 31 | 32 | publishing { 33 | repositories { 34 | maven { 35 | name = "GitHubPackages" 36 | url = URI("https://maven.pkg.github.com/${SCM.ORG}/${SCM.NAME}/") 37 | credentials { 38 | username = System.getenv("GH_USERNAME") 39 | password = System.getenv("GH_TOKEN") 40 | } 41 | } 42 | } 43 | publications.withType { 44 | artifact( 45 | tasks.register("${name}JavadocJar", Jar::class) { 46 | archiveClassifier.set("javadoc") 47 | archiveAppendix.set(this@withType.name) 48 | } 49 | ) 50 | pom.run { 51 | name.set(BuildConfig.NAME) 52 | description.set(BuildConfig.DESCRIPTION) 53 | url.set(BuildConfig.URL) 54 | licenses { 55 | license { 56 | name.set(BuildConfig.License.NAME) 57 | url.set(BuildConfig.License.URL) 58 | distribution.set("repo") 59 | } 60 | } 61 | developers { 62 | developer { 63 | id.set(Developer.ID) 64 | name.set(Developer.NAME) 65 | email.set(Developer.EMAIL) 66 | url.set(Developer.URL) 67 | timezone.set(Developer.TIMEZONE) 68 | } 69 | } 70 | scm { 71 | url.set("https://${SCM.PATH}/") 72 | connection.set("scm:git:git://${SCM.PATH}.git") 73 | developerConnection.set("scm:git:ssh://git@${SCM.PATH}.git") 74 | } 75 | } 76 | } 77 | } 78 | 79 | signing { 80 | if (SigningConfig.Release.hasCredentials(project)) { 81 | val config = SigningConfig.Release(project) 82 | useInMemoryPgpKeys(config.keyId, config.keyRing, config.password) 83 | sign(publishing.publications) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /buildSrc/src/main/resources/license-regex.template: -------------------------------------------------------------------------------- 1 | ^\/[*\s]+Copyright.*20\d{2}\sGoatBytes.IO -------------------------------------------------------------------------------- /core/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | import build.Os 19 | import org.jetbrains.kotlin.gradle.dsl.JsModuleKind 20 | import java.net.URL 21 | 22 | plugins { 23 | alias(libs.plugins.kotlin.multiplatform) 24 | alias(libs.plugins.android.library) 25 | alias(libs.plugins.dokka) 26 | id("publication.gh-packages") 27 | } 28 | 29 | kotlin { 30 | applyDefaultHierarchyTemplate() 31 | 32 | targets.all { 33 | compilations.all { 34 | kotlinOptions { 35 | freeCompilerArgs += listOf( 36 | "-Xexpect-actual-classes", 37 | ) 38 | } 39 | } 40 | } 41 | 42 | js(IR) { 43 | compilations.all { 44 | kotlinOptions { 45 | moduleKind = JsModuleKind.MODULE_UMD.kind 46 | sourceMap = true 47 | metaInfo = true 48 | } 49 | } 50 | nodejs { 51 | testTask { 52 | useMocha { 53 | timeout = "30s" 54 | } 55 | } 56 | } 57 | browser { 58 | webpackTask { 59 | outputDirectory.set(layout.buildDirectory.get().file("dist/js").asFile) 60 | } 61 | } 62 | binaries.executable() 63 | } 64 | 65 | jvm() 66 | 67 | androidTarget { 68 | publishLibraryVariants("release") 69 | compilations.all { 70 | kotlinOptions { 71 | jvmTarget = BuildConfig.Android.javaVersion.toString() 72 | } 73 | } 74 | } 75 | 76 | if (Os.isMacOS) { 77 | appleTargetsWithFramework(BuildConfig.Apple.FRAMEWORK_NAME) 78 | } 79 | 80 | if (Os.isLinux) { 81 | linuxX64("linux") { 82 | compilations.getByName("main") { 83 | kotlinOptions { 84 | // Required for CPointer etc. since Kotlin 1.9. 85 | freeCompilerArgs += "-opt-in=kotlinx.cinterop.ExperimentalForeignApi" 86 | } 87 | } 88 | } 89 | } 90 | 91 | sourceSets { 92 | commonMain.dependencies { 93 | implementation(libs.kotlinx.coroutines.core) 94 | } 95 | commonTest.dependencies { 96 | implementation(libs.kotlin.test) 97 | implementation(libs.kotlinx.coroutines.test) 98 | } 99 | androidMain.dependencies { 100 | implementation(libs.kotlin.stdlib) 101 | } 102 | androidUnitTest.dependencies { 103 | implementation(libs.junit) 104 | implementation(libs.mockito.core) 105 | implementation(libs.kotlinx.coroutines.test) 106 | } 107 | jsMain.dependencies { 108 | implementation(libs.kotlinx.coroutines.core.js) 109 | } 110 | jsTest.dependencies { 111 | implementation(kotlin("test-js")) 112 | implementation(libs.kotlinx.coroutines.test) 113 | } 114 | appleMain.dependencies { 115 | implementation(libs.kotlinx.coroutines.core) 116 | } 117 | } 118 | } 119 | 120 | android { 121 | namespace = BuildConfig.Android.NAMESPACE 122 | compileSdk = BuildConfig.Android.COMPILE_SDK 123 | defaultConfig { 124 | minSdk = BuildConfig.Android.MIN_SDK 125 | } 126 | } 127 | 128 | tasks.dokkaHtml { 129 | outputDirectory.set(BuildConfig.Dokka.outputDirectory) 130 | dokkaSourceSets { 131 | configureEach { 132 | noStdlibLink.set(false) 133 | noJdkLink.set(false) 134 | externalDocumentationLink { 135 | url.set(URL(BuildConfig.Dokka.DOC_LINK)) 136 | packageListUrl.set(URL(BuildConfig.Dokka.PKG_LIST)) 137 | } 138 | displayName.set( 139 | when (val name = displayName.get() ?: name) { 140 | "jvm" -> "JVM" 141 | "js" -> "JavaScript" 142 | else -> name.capitalize() 143 | } 144 | ) 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /core/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /core/src/androidMain/kotlin/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/core/src/androidMain/kotlin/.keep -------------------------------------------------------------------------------- /core/src/androidMain/kotlin/io/goatbytes/kmmify/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.goatbytes.kmmify 19 | 20 | /** 21 | * Provides a common interface to interact with platform-specific features. 22 | */ 23 | actual class Platform actual constructor() { 24 | /** 25 | * Retrieves the type of the platform on which the application is running. 26 | * @return The enum value representing the platform type. 27 | */ 28 | actual fun type(): PlatformType = PlatformType.Android 29 | } 30 | -------------------------------------------------------------------------------- /core/src/androidUnitTest/kotlin/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/core/src/androidUnitTest/kotlin/.keep -------------------------------------------------------------------------------- /core/src/androidUnitTest/kotlin/io/goatbytes/kmmify/PlatformTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.goatbytes.kmmify 19 | 20 | import org.junit.Assert.assertEquals 21 | import org.junit.Test 22 | 23 | class PlatformTest { 24 | 25 | @Test 26 | fun `test platform type is android`() { 27 | assertEquals(Platform().type(), PlatformType.Android) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /core/src/appleMain/kotlin/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/core/src/appleMain/kotlin/.keep -------------------------------------------------------------------------------- /core/src/commonMain/kotlin/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/core/src/commonMain/kotlin/.keep -------------------------------------------------------------------------------- /core/src/commonMain/kotlin/io/goatbytes/kmmify/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.goatbytes.kmmify 19 | 20 | /** 21 | * Provides a common interface to interact with platform-specific features. 22 | */ 23 | expect class Platform() { 24 | /** 25 | * Retrieves the type of the platform on which the application is running. 26 | * @return The enum value representing the platform type. 27 | */ 28 | fun type(): PlatformType 29 | } 30 | -------------------------------------------------------------------------------- /core/src/commonMain/kotlin/io/goatbytes/kmmify/PlatformType.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.goatbytes.kmmify 19 | 20 | /** 21 | * Represents a hierarchy of platform types supported in a Kotlin Multiplatform project. 22 | * This sealed class enables type-safe representation of platform-specific traits and operations. 23 | */ 24 | sealed class PlatformType { 25 | 26 | /** 27 | * Provides a common name property that must be implemented by all platform types. 28 | */ 29 | abstract val name: String 30 | 31 | /** 32 | * Represents the Android operating system. 33 | */ 34 | data object Android : PlatformType() { 35 | override val name get() = "Android" 36 | } 37 | 38 | /** 39 | * Represents the Java Virtual Machine platform typically used for desktop or server-side apps. 40 | */ 41 | data object JVM : PlatformType() { 42 | override val name get() = "JVM" 43 | } 44 | 45 | /** 46 | * Represents the JavaScript environment, commonly used for web platforms. 47 | */ 48 | data object JS : PlatformType() { 49 | override val name get() = "JS" 50 | } 51 | 52 | /** 53 | * Represents a generic category for native platforms, serving as a base class for specific 54 | * native operating systems. 55 | */ 56 | abstract class Native : PlatformType() { 57 | /** 58 | * Represents the iOS operating system, commonly used in iPhone and iPad devices. 59 | */ 60 | data object IOS : Native() { 61 | override val name get() = "iOS" 62 | } 63 | 64 | /** 65 | * Represents the macOS operating system, used in computers manufactured by Apple. 66 | */ 67 | data object MacOS : Native() { 68 | override val name get() = "macOS" 69 | } 70 | 71 | /** 72 | * Represents the tvOS operating system, used in Apple TV devices. 73 | */ 74 | data object TVOS : Native() { 75 | override val name get() = "tvOS" 76 | } 77 | 78 | /** 79 | * Represents the watchOS operating system, used in Apple Watch devices. 80 | */ 81 | data object WatchOS : Native() { 82 | override val name get() = "watchOS" 83 | } 84 | 85 | /** 86 | * Represents the Linux operating system, commonly used in a variety of desktop, server, and 87 | * embedded systems. 88 | */ 89 | data object Linux : Native() { 90 | override val name get() = "Linux" 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /core/src/commonTest/kotlin/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/core/src/commonTest/kotlin/.keep -------------------------------------------------------------------------------- /core/src/iosMain/kotlin/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/core/src/iosMain/kotlin/.keep -------------------------------------------------------------------------------- /core/src/iosMain/kotlin/io/goatbytes/kmmify/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.goatbytes.kmmify 19 | 20 | /** 21 | * Provides a common interface to interact with platform-specific features. 22 | */ 23 | actual class Platform actual constructor() { 24 | /** 25 | * Retrieves the type of the platform on which the application is running. 26 | * @return The enum value representing the platform type. 27 | */ 28 | actual fun type(): PlatformType = PlatformType.Native.IOS 29 | } 30 | -------------------------------------------------------------------------------- /core/src/jsMain/kotlin/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/core/src/jsMain/kotlin/.keep -------------------------------------------------------------------------------- /core/src/jsMain/kotlin/io/goatbytes/kmmify/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.goatbytes.kmmify 19 | 20 | /** 21 | * Provides a common interface to interact with platform-specific features. 22 | */ 23 | actual class Platform actual constructor() { 24 | /** 25 | * Retrieves the type of the platform on which the application is running. 26 | * @return The enum value representing the platform type. 27 | */ 28 | actual fun type(): PlatformType = PlatformType.JS 29 | } 30 | -------------------------------------------------------------------------------- /core/src/jsTest/kotlin/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/core/src/jsTest/kotlin/.keep -------------------------------------------------------------------------------- /core/src/jsTest/kotlin/io/goatbytes/kmmify/PlatformTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.goatbytes.kmmify 19 | 20 | import kotlin.test.Test 21 | import kotlin.test.assertEquals 22 | 23 | class PlatformTest { 24 | 25 | @Test 26 | fun testPlatformTypeIsJS() { 27 | assertEquals(Platform().type(), PlatformType.JS) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /core/src/jvmMain/kotlin/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/core/src/jvmMain/kotlin/.keep -------------------------------------------------------------------------------- /core/src/jvmMain/kotlin/io/goatbytes/kmmify/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.goatbytes.kmmify 19 | 20 | /** 21 | * Provides a common interface to interact with platform-specific features. 22 | */ 23 | actual class Platform actual constructor() { 24 | /** 25 | * Retrieves the type of the platform on which the application is running. 26 | * @return The enum value representing the platform type. 27 | */ 28 | actual fun type(): PlatformType = PlatformType.JVM 29 | } 30 | -------------------------------------------------------------------------------- /core/src/jvmTest/kotlin/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/core/src/jvmTest/kotlin/.keep -------------------------------------------------------------------------------- /core/src/jvmTest/kotlin/io/goatbytes/kmmify/PlatformTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.goatbytes.kmmify 19 | 20 | import org.junit.Assert.assertEquals 21 | import org.junit.Test 22 | 23 | class PlatformTest { 24 | 25 | @Test 26 | fun `test platform type is android`() { 27 | assertEquals(Platform().type(), PlatformType.JVM) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /core/src/linuxMain/kotlin/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/core/src/linuxMain/kotlin/.keep -------------------------------------------------------------------------------- /core/src/linuxMain/kotlin/io/goatbytes/kmmify/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.goatbytes.kmmify 19 | 20 | /** 21 | * Provides a common interface to interact with platform-specific features. 22 | */ 23 | actual class Platform actual constructor() { 24 | /** 25 | * Retrieves the type of the platform on which the application is running. 26 | * @return The enum value representing the platform type. 27 | */ 28 | actual fun type(): PlatformType = PlatformType.Native.Linux 29 | } 30 | -------------------------------------------------------------------------------- /core/src/macosMain/kotlin/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/core/src/macosMain/kotlin/.keep -------------------------------------------------------------------------------- /core/src/macosMain/kotlin/io/goatbytes/kmmify/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.goatbytes.kmmify 19 | 20 | /** 21 | * Provides a common interface to interact with platform-specific features. 22 | */ 23 | actual class Platform actual constructor() { 24 | /** 25 | * Retrieves the type of the platform on which the application is running. 26 | * @return The enum value representing the platform type. 27 | */ 28 | actual fun type(): PlatformType = PlatformType.Native.MacOS 29 | } 30 | -------------------------------------------------------------------------------- /core/src/tvosMain/kotlin/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/core/src/tvosMain/kotlin/.keep -------------------------------------------------------------------------------- /core/src/tvosMain/kotlin/io/goatbytes/kmmify/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.goatbytes.kmmify 19 | 20 | /** 21 | * Provides a common interface to interact with platform-specific features. 22 | */ 23 | actual class Platform actual constructor() { 24 | /** 25 | * Retrieves the type of the platform on which the application is running. 26 | * @return The enum value representing the platform type. 27 | */ 28 | actual fun type(): PlatformType = PlatformType.Native.TVOS 29 | } 30 | -------------------------------------------------------------------------------- /core/src/watchosMain/kotlin/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/core/src/watchosMain/kotlin/.keep -------------------------------------------------------------------------------- /core/src/watchosMain/kotlin/io/goatbytes/kmmify/Platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.goatbytes.kmmify 19 | 20 | /** 21 | * Provides a common interface to interact with platform-specific features. 22 | */ 23 | actual class Platform actual constructor() { 24 | /** 25 | * Retrieves the type of the platform on which the application is running. 26 | * @return The enum value representing the platform type. 27 | */ 28 | actual fun type(): PlatformType = PlatformType.Native.WatchOS 29 | } 30 | -------------------------------------------------------------------------------- /detekt.yml: -------------------------------------------------------------------------------- 1 | # build: https://detekt.dev/docs/introduction/configuration/ 2 | build: 3 | maxIssues: 0 4 | 5 | # comments: https://detekt.dev/docs/rules/comments/ 6 | comments: 7 | active: true 8 | CommentOverPrivateFunction: 9 | active: false 10 | CommentOverPrivateProperty: 11 | active: false 12 | DeprecatedBlockTag: 13 | active: true 14 | EndOfSentenceFormat: 15 | active: false 16 | KDocReferencesNonPublicProperty: 17 | active: true 18 | OutdatedDocumentation: 19 | active: true 20 | UndocumentedPublicClass: 21 | active: true 22 | UndocumentedPublicFunction: 23 | active: true 24 | 25 | # complexity: https://detekt.dev/docs/rules/complexity/ 26 | complexity: 27 | active: true 28 | LongParameterList: 29 | active: true 30 | constructorThreshold: 10 31 | functionThreshold: 8 32 | NestedScopeFunctions: 33 | active: true 34 | 35 | # exceptions: https://detekt.dev/docs/rules/exceptions/ 36 | exceptions: 37 | active: true 38 | 39 | # formatting: https://detekt.dev/docs/rules/formatting/ 40 | formatting: 41 | autoCorrect: true 42 | ClassName: 43 | active: true 44 | IfElseWrapping: 45 | active: true 46 | Indentation: 47 | active: true 48 | indentSize: 2 49 | KDocFormatting: 50 | active: true 51 | enableParamNameAlignment: true 52 | enableParameterListWrapping: true 53 | MaxLineLength: 54 | active: true 55 | maxLineLength: 100 56 | NewLineAtEndOfFile: 57 | active: true 58 | NoConsecutiveBlankLines: 59 | active: true 60 | NoEmptyClassBody: 61 | active: true 62 | SpacingAroundColon: 63 | active: true 64 | SpacingAroundComma: 65 | active: true 66 | SpacingAroundCurly: 67 | active: true 68 | includeSpacesBeforeBrace: true 69 | SpacingAroundKeywords: 70 | active: true 71 | SpacingAroundOperators: 72 | active: true 73 | SpacingAroundParens: 74 | active: true 75 | includeSpacesBeforeParenthesis: true 76 | 77 | # naming: https://detekt.dev/docs/rules/naming/ 78 | naming: 79 | BooleanPropertyNaming: 80 | active: true 81 | 82 | # style: https://detekt.dev/docs/rules/style/ 83 | style: 84 | active: true 85 | MagicNumber: 86 | active: true 87 | ignoreNumbers: [ '-2', '-1', '0', '0.5', '1', '2', '3', '31', '100', '1000' ] 88 | WildcardImport: 89 | active: true 90 | ForbiddenComment: 91 | active: true 92 | allowedPatterns: "(TODO|FIXME):\\s\\[[a-zA-Z]{2,}-?\\d{2,}\\]\\s" 93 | -------------------------------------------------------------------------------- /docs/assets/css/app.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | :root { 19 | --md-primary-fg-color: #007BFF; 20 | --md-primary-fg-color--light: #288EFA; 21 | --md-primary-fg-color--dark: #005DC1; 22 | } 23 | -------------------------------------------------------------------------------- /docs/assets/img/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/docs/assets/img/banner.png -------------------------------------------------------------------------------- /docs/assets/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/docs/assets/img/favicon.png -------------------------------------------------------------------------------- /docs/assets/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/docs/assets/img/logo.png -------------------------------------------------------------------------------- /docs/assets/js/app.js: -------------------------------------------------------------------------------- 1 | console.log(` 2 | _)) 3 | > *\\ _~ 4 | \`;'\\\\__-' \\_ 5 | | ) _ \\ \\ 6 | / / \`\` w w 7 | w w 8 | `); -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # Welcome to kmmify 2 | 3 | Welcome to the official documentation for **kmmify**—a robust and refined template designed to 4 | supercharge your Kotlin Multiplatform development. Our template simplifies the process of building 5 | cross-platform applications by sharing business logic across iOS, Android, Web, and Desktop 6 | platforms, while accommodating platform-specific nuances. 7 | 8 | ## Why kmmify? 9 | 10 | **kmmify** was born out of a need to refine and optimize the official Kotlin Multiplatform Library 11 | template. By reworking it significantly, we've tailored a template that not only meets the evolving 12 | demands of modern software projects but also offers a streamlined setup process that gets you up and 13 | running swiftly. This template is ideal for developers looking to leverage Kotlin Multiplatform's 14 | true potential by facilitating shared codebases across multiple platforms. 15 | 16 | ## Features 17 | 18 | - **Unified Project Structure**: Organize and maintain a single codebase that runs on all major 19 | platforms. 20 | - **Pre-configured Build Scripts**: Jumpstart your development with ready-to-use Gradle scripts. 21 | - **Integrated Code Analysis**: Maintain high-quality code with Detekt integrated for static code 22 | analysis. 23 | - **Ready-to-Deploy Documentation**: Comes with MkDocs configuration for immediate project 24 | documentation setup. 25 | 26 | ## Getting Started 27 | 28 | To get started with **kmmify**, clone the repository and build your project using the following 29 | commands: 30 | 31 | ```shell 32 | git clone https://github.com/goatbytes/kmmify.git 33 | cd kmmify 34 | ./gradlew build 35 | ``` 36 | 37 | ## About GoatBytes.IO 38 | 39 | ![GoatBytesLogo](assets/img/banner.png) 40 | 41 | At **GoatBytes.IO**, our mission is to develop secure software solutions that empower businesses to 42 | transform the world. With a focus on innovation and excellence, we strive to deliver cutting-edge 43 | products that meet the evolving needs of businesses across various industries. 44 | 45 | [![GitHub](https://img.shields.io/badge/GitHub-GoatBytes-181717?logo=github)](https://github.com/goatbytes) 46 | [![Twitter](https://img.shields.io/badge/Twitter-GoatBytes-1DA1F2?logo=twitter)](https://twitter.com/goatbytes) 47 | [![LinkedIn](https://img.shields.io/badge/LinkedIn-GoatBytes-0077B5?logo=linkedin)](https://www.linkedin.com/company/goatbytes) 48 | [![Instagram](https://img.shields.io/badge/Instagram-GoatBytes.io-E4405F?logo=instagram)](https://www.instagram.com/goatbytes.io/) -------------------------------------------------------------------------------- /docs/overrides/partials/copyright.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2024 GoatBytes.IO 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | # 17 | 18 | #Gradle 19 | org.gradle.jvmargs=-Xmx6g -XX:+UseParallelGC -XX:MaxMetaspaceSize=4g 20 | org.gradle.caching=true 21 | org.gradle.configuration-cache=true 22 | #Kotlin 23 | kotlin.code.style=official 24 | kotlin.js.compiler=ir 25 | #MPP 26 | kotlin.mpp.enableCInteropCommonization=true 27 | kotlin.mpp.stability.nowarn=true 28 | #Android 29 | android.useAndroidX=true 30 | android.nonTransitiveRClass=true 31 | #Native 32 | kotlin.native.cacheKind.linuxX64=none -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | #noinspection GradleDependency 3 | agp = "8.7.2" 4 | dokka = "1.9.20" 5 | kotlin = "2.0.10" 6 | coroutines = "1.9.0" 7 | detekt = "1.23.6" 8 | mockito = "5.14.2" 9 | nexus-publish = "2.0.0" 10 | junit = "4.13.2" 11 | 12 | [libraries] 13 | junit = { module = "junit:junit", version.ref = "junit" } 14 | detekt-formatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detekt" } 15 | kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } 16 | kotlinx-coroutines-core-js = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core-js", version.ref = "coroutines" } 17 | kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" } 18 | kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } 19 | kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } 20 | mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito" } 21 | nexus-publish = { module = "io.github.gradle-nexus.publish-plugin:io.github.gradle-nexus.publish-plugin.gradle.plugin", version.ref = "nexus-publish" } 22 | 23 | [plugins] 24 | android-library = { id = "com.android.library", version.ref = "agp" } 25 | detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } 26 | dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } 27 | kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } 28 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goatbytes/kmmify/4148d17f02476056ebb4c8bb20209a38e05c8204/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # SPDX-License-Identifier: Apache-2.0 19 | # 20 | 21 | ############################################################################## 22 | # 23 | # Gradle start up script for POSIX generated by Gradle. 24 | # 25 | # Important for running: 26 | # 27 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 28 | # noncompliant, but you have some other compliant shell such as ksh or 29 | # bash, then to run this script, type that shell name before the whole 30 | # command line, like: 31 | # 32 | # ksh Gradle 33 | # 34 | # Busybox and similar reduced shells will NOT work, because this script 35 | # requires all of these POSIX shell features: 36 | # * functions; 37 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 38 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 39 | # * compound commands having a testable exit status, especially «case»; 40 | # * various built-in commands including «command», «set», and «ulimit». 41 | # 42 | # Important for patching: 43 | # 44 | # (2) This script targets any POSIX shell, so it avoids extensions provided 45 | # by Bash, Ksh, etc; in particular arrays are avoided. 46 | # 47 | # The "traditional" practice of packing multiple parameters into a 48 | # space-separated string is a well documented source of bugs and security 49 | # problems, so this is (mostly) avoided, by progressively accumulating 50 | # options in "$@", and eventually passing that to Java. 51 | # 52 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 53 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 54 | # see the in-line comments for details. 55 | # 56 | # There are tweaks for specific operating systems such as AIX, CygWin, 57 | # Darwin, MinGW, and NonStop. 58 | # 59 | # (3) This script is generated from the Groovy template 60 | # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 61 | # within the Gradle project. 62 | # 63 | # You can find Gradle at https://github.com/gradle/gradle/. 64 | # 65 | ############################################################################## 66 | 67 | # Attempt to set APP_HOME 68 | 69 | # Resolve links: $0 may be a link 70 | app_path=$0 71 | 72 | # Need this for daisy-chained symlinks. 73 | while 74 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 75 | [ -h "$app_path" ] 76 | do 77 | ls=$( ls -ld "$app_path" ) 78 | link=${ls#*' -> '} 79 | case $link in #( 80 | /*) app_path=$link ;; #( 81 | *) app_path=$APP_HOME$link ;; 82 | esac 83 | done 84 | 85 | # This is normally unused 86 | # shellcheck disable=SC2034 87 | APP_BASE_NAME=${0##*/} 88 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) 89 | APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s 90 | ' "$PWD" ) || exit 91 | 92 | # Use the maximum available, or set MAX_FD != -1 to use that value. 93 | MAX_FD=maximum 94 | 95 | warn () { 96 | echo "$*" 97 | } >&2 98 | 99 | die () { 100 | echo 101 | echo "$*" 102 | echo 103 | exit 1 104 | } >&2 105 | 106 | # OS specific support (must be 'true' or 'false'). 107 | cygwin=false 108 | msys=false 109 | darwin=false 110 | nonstop=false 111 | case "$( uname )" in #( 112 | CYGWIN* ) cygwin=true ;; #( 113 | Darwin* ) darwin=true ;; #( 114 | MSYS* | MINGW* ) msys=true ;; #( 115 | NONSTOP* ) nonstop=true ;; 116 | esac 117 | 118 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 119 | 120 | 121 | # Determine the Java command to use to start the JVM. 122 | if [ -n "$JAVA_HOME" ] ; then 123 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 124 | # IBM's JDK on AIX uses strange locations for the executables 125 | JAVACMD=$JAVA_HOME/jre/sh/java 126 | else 127 | JAVACMD=$JAVA_HOME/bin/java 128 | fi 129 | if [ ! -x "$JAVACMD" ] ; then 130 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 131 | 132 | Please set the JAVA_HOME variable in your environment to match the 133 | location of your Java installation." 134 | fi 135 | else 136 | JAVACMD=java 137 | if ! command -v java >/dev/null 2>&1 138 | then 139 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 140 | 141 | Please set the JAVA_HOME variable in your environment to match the 142 | location of your Java installation." 143 | fi 144 | fi 145 | 146 | # Increase the maximum file descriptors if we can. 147 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 148 | case $MAX_FD in #( 149 | max*) 150 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 151 | # shellcheck disable=SC2039,SC3045 152 | MAX_FD=$( ulimit -H -n ) || 153 | warn "Could not query maximum file descriptor limit" 154 | esac 155 | case $MAX_FD in #( 156 | '' | soft) :;; #( 157 | *) 158 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 159 | # shellcheck disable=SC2039,SC3045 160 | ulimit -n "$MAX_FD" || 161 | warn "Could not set maximum file descriptor limit to $MAX_FD" 162 | esac 163 | fi 164 | 165 | # Collect all arguments for the java command, stacking in reverse order: 166 | # * args from the command line 167 | # * the main class name 168 | # * -classpath 169 | # * -D...appname settings 170 | # * --module-path (only if needed) 171 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 172 | 173 | # For Cygwin or MSYS, switch paths to Windows format before running java 174 | if "$cygwin" || "$msys" ; then 175 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 176 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 177 | 178 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 179 | 180 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 181 | for arg do 182 | if 183 | case $arg in #( 184 | -*) false ;; # don't mess with options #( 185 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 186 | [ -e "$t" ] ;; #( 187 | *) false ;; 188 | esac 189 | then 190 | arg=$( cygpath --path --ignore --mixed "$arg" ) 191 | fi 192 | # Roll the args list around exactly as many times as the number of 193 | # args, so each arg winds up back in the position where it started, but 194 | # possibly modified. 195 | # 196 | # NB: a `for` loop captures its iteration list before it begins, so 197 | # changing the positional parameters here affects neither the number of 198 | # iterations, nor the values presented in `arg`. 199 | shift # remove old arg 200 | set -- "$@" "$arg" # push replacement arg 201 | done 202 | fi 203 | 204 | 205 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 206 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 207 | 208 | # Collect all arguments for the java command: 209 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, 210 | # and any embedded shellness will be escaped. 211 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be 212 | # treated as '${Hostname}' itself on the command line. 213 | 214 | set -- \ 215 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 216 | -classpath "$CLASSPATH" \ 217 | org.gradle.wrapper.GradleWrapperMain \ 218 | "$@" 219 | 220 | # Stop when "xargs" is not available. 221 | if ! command -v xargs >/dev/null 2>&1 222 | then 223 | die "xargs is not available" 224 | fi 225 | 226 | # Use "xargs" to parse quoted args. 227 | # 228 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 229 | # 230 | # In Bash we could simply go: 231 | # 232 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 233 | # set -- "${ARGS[@]}" "$@" 234 | # 235 | # but POSIX shell has neither arrays nor command substitution, so instead we 236 | # post-process each arg (as a line of input to sed) to backslash-escape any 237 | # character that might be a shell metacharacter, then use eval to reverse 238 | # that process (while maintaining the separation between arguments), and wrap 239 | # the whole thing up as a single "set" statement. 240 | # 241 | # This will of course break if any of these variables contains a newline or 242 | # an unmatched quote. 243 | # 244 | 245 | eval "set -- $( 246 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 247 | xargs -n1 | 248 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 249 | tr '\n' ' ' 250 | )" '"$@"' 251 | 252 | exec "$JAVACMD" "$@" 253 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | @rem SPDX-License-Identifier: Apache-2.0 17 | @rem 18 | 19 | @if "%DEBUG%"=="" @echo off 20 | @rem ########################################################################## 21 | @rem 22 | @rem Gradle startup script for Windows 23 | @rem 24 | @rem ########################################################################## 25 | 26 | @rem Set local scope for the variables with windows NT shell 27 | if "%OS%"=="Windows_NT" setlocal 28 | 29 | set DIRNAME=%~dp0 30 | if "%DIRNAME%"=="" set DIRNAME=. 31 | @rem This is normally unused 32 | set APP_BASE_NAME=%~n0 33 | set APP_HOME=%DIRNAME% 34 | 35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 37 | 38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 40 | 41 | @rem Find java.exe 42 | if defined JAVA_HOME goto findJavaFromJavaHome 43 | 44 | set JAVA_EXE=java.exe 45 | %JAVA_EXE% -version >NUL 2>&1 46 | if %ERRORLEVEL% equ 0 goto execute 47 | 48 | echo. 1>&2 49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 50 | echo. 1>&2 51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 52 | echo location of your Java installation. 1>&2 53 | 54 | goto fail 55 | 56 | :findJavaFromJavaHome 57 | set JAVA_HOME=%JAVA_HOME:"=% 58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 59 | 60 | if exist "%JAVA_EXE%" goto execute 61 | 62 | echo. 1>&2 63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 64 | echo. 1>&2 65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 66 | echo location of your Java installation. 1>&2 67 | 68 | goto fail 69 | 70 | :execute 71 | @rem Setup the command line 72 | 73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 74 | 75 | 76 | @rem Execute Gradle 77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 78 | 79 | :end 80 | @rem End local scope for the variables with windows NT shell 81 | if %ERRORLEVEL% equ 0 goto mainEnd 82 | 83 | :fail 84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 85 | rem the _cmd.exe /c_ return code! 86 | set EXIT_CODE=%ERRORLEVEL% 87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 89 | exit /b %EXIT_CODE% 90 | 91 | :mainEnd 92 | if "%OS%"=="Windows_NT" endlocal 93 | 94 | :omega 95 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: kmmify 2 | site_url: https://kmmify.goatbytes.io 3 | repo_name: kmmify 4 | repo_url: https://github.com/goatbytes/kmmify 5 | site_description: "A cutting-edge cross-platform SDK designed to streamline the process of uniquely identifying devices across different platforms." 6 | site_author: GoatBytes.IO 7 | remote_branch: gh-pages 8 | edit_uri: "" 9 | 10 | nav: 11 | - 'Overview': index.md 12 | - 'Documentation': docs/index.html 13 | - 'KMP Wizard': https://kmp.jetbrains.com/ 14 | - 'KMP Template Gallery': https://kmp.jetbrains.com/#templateGallery 15 | - 'KMP Development': https://www.jetbrains.com/help/kotlin-multiplatform-dev/get-started.html 16 | 17 | theme: 18 | name: 'material' 19 | favicon: assets/img/favicon.png 20 | logo: assets/img/logo.png 21 | custom_dir: docs/overrides 22 | features: 23 | - instant 24 | - navigation.instant 25 | - navigation.sections 26 | - navigation.top 27 | - search.suggest 28 | - search.highlight 29 | # - toc.integrate 30 | - content.code.annotate 31 | palette: 32 | - scheme: default # Palette toggle for light mode 33 | media: "(prefers-color-scheme: light)" 34 | primary: 'custom' 35 | accent: 'white' 36 | toggle: 37 | icon: material/brightness-7 38 | name: Switch to dark mode 39 | - scheme: slate # Palette toggle for dark mode 40 | media: "(prefers-color-scheme: dark)" 41 | primary: 'custom' 42 | accent: 'white' 43 | toggle: 44 | icon: material/brightness-4 45 | name: Switch to light mode 46 | font: 47 | heading: 'Red Hat Display' 48 | text: 'Red Hat Text' 49 | code: 'Red Hat Mono' 50 | icon: 51 | repo: fontawesome/brands/github 52 | 53 | markdown_extensions: 54 | - admonition 55 | - meta 56 | - pymdownx.blocks.admonition 57 | - pymdownx.blocks.tab: 58 | alternate_style: true 59 | - pymdownx.blocks.details 60 | - pymdownx.blocks.definition 61 | - pymdownx.superfences 62 | - pymdownx.details 63 | - pymdownx.emoji: 64 | emoji_index: !!python/name:material.extensions.emoji.twemoji 65 | emoji_generator: !!python/name:material.extensions.emoji.to_svg 66 | - pymdownx.mark 67 | - pymdownx.highlight: 68 | anchor_linenums: true 69 | line_spans: __span 70 | pygments_lang_class: true 71 | - pymdownx.inlinehilite 72 | - pymdownx.snippets 73 | - footnotes 74 | - attr_list 75 | - md_in_html 76 | 77 | plugins: 78 | - search 79 | - minify: 80 | minify_html: true 81 | - git-revision-date-localized: 82 | type: timeago 83 | fallback_to_build_date: true 84 | 85 | extra: 86 | homepage: https://goatbytes.io 87 | social: 88 | - icon: fontawesome/brands/x-twitter 89 | link: https://x.com/goatbytes 90 | - icon: fontawesome/brands/instagram 91 | link: https://instagram.com/goatbytes.io 92 | - icon: fontawesome/brands/github 93 | link: https://github.com/goatbytes 94 | - icon: fontawesome/brands/linkedin 95 | link: https://www.linkedin.com/company/goatbytes 96 | analytics: 97 | provider: google 98 | property: G-V0TQY16GNY 99 | generator: false 100 | 101 | extra_css: 102 | - 'assets/css/app.css' 103 | 104 | extra_javascript: 105 | - 'assets/js/app.js' 106 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 GoatBytes.IO 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | pluginManagement { 19 | repositories { 20 | google() 21 | mavenCentral() 22 | gradlePluginPortal() 23 | } 24 | } 25 | 26 | dependencyResolutionManagement { 27 | @Suppress("UnstableApiUsage") 28 | repositories { 29 | google() 30 | mavenCentral() 31 | } 32 | } 33 | 34 | rootProject.name = "kmmify" 35 | include(":core") 36 | --------------------------------------------------------------------------------