├── packages ├── dispatcher-converter │ ├── docs │ │ └── FolderOperations.md │ ├── test │ │ ├── newtestfiletarget.vhost │ │ ├── oldtest │ │ │ └── fileone.vhost │ │ ├── newtestfiletarget2.vhost │ │ ├── newtestoldfile.txt │ │ └── FolderOperationsTest.js │ ├── index.js │ ├── docs.js │ ├── package.json │ ├── CHANGELOG.md │ ├── executors │ │ ├── config.yaml │ │ ├── singleFileMain.js │ │ └── main.js │ └── src │ │ └── util │ │ ├── FolderOperations.js │ │ └── constants.js ├── repository-modernizer │ ├── test │ │ ├── resources │ │ │ ├── com.adobe.test.config │ │ │ ├── com.adobe.test.cfg.json │ │ │ ├── filter.xml │ │ │ ├── com.adobe.config.test.cfg.json │ │ │ ├── com.adobe.config.test.xml │ │ │ ├── pom.xml │ │ │ └── sub-project │ │ │ │ └── pom.xml │ │ ├── config.yaml │ │ ├── restructure-config.test.js │ │ ├── multiProjectConfig.yaml │ │ └── projectWithSubProjectConfig.yaml │ ├── validator │ │ ├── config.yaml │ │ ├── validate.js │ │ └── constants.js │ ├── resources │ │ ├── ui.apps │ │ │ ├── src │ │ │ │ └── main │ │ │ │ │ └── content │ │ │ │ │ └── META-INF │ │ │ │ │ └── vault │ │ │ │ │ └── filter.xml │ │ │ └── pom.xml │ │ ├── ui.content │ │ │ ├── src │ │ │ │ └── main │ │ │ │ │ └── content │ │ │ │ │ └── META-INF │ │ │ │ │ └── vault │ │ │ │ │ └── filter.xml │ │ │ └── pom.xml │ │ ├── ui.config │ │ │ ├── src │ │ │ │ └── main │ │ │ │ │ └── content │ │ │ │ │ └── META-INF │ │ │ │ │ └── vault │ │ │ │ │ └── filter.xml │ │ │ └── pom.xml │ │ ├── all │ │ │ ├── src │ │ │ │ └── main │ │ │ │ │ └── content │ │ │ │ │ └── META-INF │ │ │ │ │ └── vault │ │ │ │ │ ├── filter.xml │ │ │ │ │ └── definition │ │ │ │ │ └── .content.xml │ │ │ └── pom.xml │ │ ├── analyse │ │ │ └── pom.xml │ │ └── ui.apps.structure │ │ │ └── pom.xml │ ├── jest.setup.js │ ├── CHANGELOG.md │ ├── package.json │ ├── junit.xml │ └── executors │ │ ├── repository-modernizer.js │ │ └── config.yaml ├── index-converter │ ├── test │ │ ├── resources │ │ │ ├── filter.xml │ │ │ ├── ensureDefinitions │ │ │ │ ├── oak-index │ │ │ │ │ ├── .content.xml │ │ │ │ │ └── custLucene │ │ │ │ │ │ └── .content.xml │ │ │ │ └── config │ │ │ │ │ └── com.adobe.acs.commons.oak.impl.EnsureOakIndex.xml │ │ │ ├── tika │ │ │ │ └── config.xml │ │ │ ├── _oak_index │ │ │ │ ├── testAssetID │ │ │ │ │ └── .content.xml │ │ │ │ ├── test-lead-form │ │ │ │ │ └── .content.xml │ │ │ │ ├── test-lead-form1 │ │ │ │ │ └── .content.xml │ │ │ │ └── .content.xml │ │ │ ├── _oak_index_1 │ │ │ │ ├── testAssetID │ │ │ │ │ └── .content.xml │ │ │ │ └── test-lead-form │ │ │ │ │ └── .content.xml │ │ │ ├── expectedCustomIndex.json │ │ │ ├── expectedNested1.json │ │ │ ├── output_json.json │ │ │ └── expectedNested.json │ │ ├── ensure-definition-converter-test.js │ │ ├── map-processing-util-test.js │ │ └── index-converter-util-test.js │ ├── resources │ │ └── tika │ │ │ └── config.xml │ ├── CHANGELOG.md │ ├── executors │ │ ├── config.yaml │ │ └── index-converter.js │ ├── package.json │ ├── src │ │ └── util │ │ │ ├── constants.js │ │ │ └── map-processing-util.js │ └── index.js └── commons │ ├── CHANGELOG.md │ ├── index.js │ ├── package.json │ ├── src │ ├── constants.js │ ├── logger.js │ ├── conversion_report │ │ ├── templates │ │ │ ├── repository-modernizer-report.md │ │ │ ├── dispatcher-converter-report.md │ │ │ └── index-converter-report.md │ │ ├── conversion_operation.js │ │ ├── detection_list.js │ │ ├── conversion_step.js │ │ └── summary_report_writer.js │ └── util.js │ ├── test │ ├── ConversionOperationTest.js │ └── ConversionStepTest.js │ └── README.md ├── .npmignore ├── .prettierrc ├── lerna.json ├── COPYRIGHT ├── .editorconfig ├── .changeset ├── config.json └── README.md ├── ISSUE_TEMPLATE.md ├── .eslintrc.json ├── .github └── workflows │ ├── codecovCoverage.yml │ └── publish.yml ├── .gitignore ├── CONTRIBUTING.md ├── package.json ├── codecov.yml ├── PULL_REQUEST_TEMPLATE.md ├── CODE_OF_CONDUCT.md └── README.md /packages/dispatcher-converter/docs/FolderOperations.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/dispatcher-converter/test/newtestfiletarget.vhost: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/dispatcher-converter/test/oldtest/fileone.vhost: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/dispatcher-converter/test/newtestfiletarget2.vhost: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/dispatcher-converter/test/newtestoldfile.txt: -------------------------------------------------------------------------------- 1 | Test ContentTest Content -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.log 3 | doc/ 4 | browser/ 5 | *.tgz 6 | .eslintrc.json 7 | .babelrc 8 | webpack.config.js -------------------------------------------------------------------------------- /packages/repository-modernizer/test/resources/com.adobe.test.config: -------------------------------------------------------------------------------- 1 | refreshThreshold=I"168" 2 | syncHandlers=["default"] 3 | -------------------------------------------------------------------------------- /packages/repository-modernizer/validator/config.yaml: -------------------------------------------------------------------------------- 1 | uiAppsPackagePaths: 2 | uiContentPackagePaths: 3 | allPackagePath: 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSpacing": true, 3 | "printWidth": 80, 4 | "arrowParens": "always", 5 | "endOfLine": "auto" 6 | } 7 | -------------------------------------------------------------------------------- /packages/repository-modernizer/test/resources/com.adobe.test.cfg.json: -------------------------------------------------------------------------------- 1 | { 2 | "refreshThreshold":"168", 3 | "syncHandlers":["default"] 4 | } 5 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": ["packages/*"], 3 | "version": "independent", 4 | "npmClient": "yarn", 5 | "useWorkspaces": true 6 | } 7 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | Copyright 2020 Adobe 2 | 3 | Adobe holds the copyright for all the files found in this repository. 4 | 5 | See the LICENSE file for licensing information. 6 | -------------------------------------------------------------------------------- /packages/index-converter/test/resources/filter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /packages/repository-modernizer/resources/ui.apps/src/main/content/META-INF/vault/filter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/repository-modernizer/resources/ui.content/src/main/content/META-INF/vault/filter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/repository-modernizer/resources/ui.config/src/main/content/META-INF/vault/filter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 4 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | end_of_line = lf 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /packages/index-converter/test/resources/ensureDefinitions/oak-index/.content.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@1.5.0/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "access": "public", 6 | "baseBranch": "master", 7 | "updateInternalDependencies": "patch" 8 | } -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Expected Behaviour 2 | 3 | ### Actual Behaviour 4 | 5 | ### Reproduce Scenario (including but not limited to) 6 | 7 | #### Steps to Reproduce 8 | 9 | #### Platform and Version 10 | 11 | #### Sample Code that illustrates the problem 12 | 13 | #### Logs taken while reproducing problem 14 | -------------------------------------------------------------------------------- /packages/index-converter/test/resources/ensureDefinitions/config/com.adobe.acs.commons.oak.impl.EnsureOakIndex.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /packages/commons/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @adobe/aem-cs-source-migration-commons 2 | 3 | ## 0.0.5 4 | 5 | ### Patch Changes 6 | 7 | - a721a77: CQ-4329547 : [Dispatcher converter] Error running the tool on AMS configs which includes sym-linked files, invalid includes 8 | 9 | ## 0.0.4 10 | 11 | ### Patch Changes 12 | 13 | - dbd23f2: CQ-4327181 : Changes to dispatcher converter aligned with archetype 28. 14 | -------------------------------------------------------------------------------- /packages/index-converter/resources/tika/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | text/plain 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /packages/index-converter/test/resources/tika/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | text/plain 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /packages/repository-modernizer/test/resources/filter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /packages/index-converter/test/resources/_oak_index/testAssetID/.content.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /packages/index-converter/test/resources/_oak_index_1/testAssetID/.content.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "commonjs": true, 4 | "es6": true, 5 | "node": true, 6 | "mocha": true 7 | }, 8 | "extends": [ 9 | "eslint:recommended", 10 | "plugin:prettier/recommended" 11 | ], 12 | "globals": { 13 | "Atomics": "readonly", 14 | "SharedArrayBuffer": "readonly" 15 | }, 16 | "parserOptions": { 17 | "ecmaVersion": 2018, 18 | "sourceType": "module" 19 | }, 20 | "rules": {} 21 | } -------------------------------------------------------------------------------- /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/master/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /packages/index-converter/test/resources/expectedCustomIndex.json: -------------------------------------------------------------------------------- 1 | {"test-lead-form-custom-1":{"_attributes":{"jcr:primaryType":"oak:QueryIndexDefinition","async":"async","fulltextEnabled":"{Boolean}false","includedPaths":"[/etc/test]","type":"lucene","compatVersion":"{Long}2","queryPaths":"[/etc/test]"},"indexRules":{"_attributes":{"jcr:primaryType":"nt:unstructured"},"sling:Folder":{"_attributes":{"jcr:primaryType":"nt:unstructured"},"properties":{"_attributes":{"jcr:primaryType":"nt:unstructured"},"jcrcreated":{"_attributes":{"jcr:primaryType":"nt:unstructured","name":"jcr:created","propertyIndex":"{Boolean}true","type":"Date"}},"pageSource":{"_attributes":{"jcr:primaryType":"nt:unstructured","name":"pageSource","propertyIndex":"{Boolean}true","type":"String"}}}}}}} 2 | -------------------------------------------------------------------------------- /.github/workflows/codecovCoverage.yml: -------------------------------------------------------------------------------- 1 | name: Workflow for Codecov Action 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | 6 | codecoverage: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout Repo 10 | uses: actions/checkout@v2 11 | 12 | - name: Setup Node.js 10 13 | uses: actions/setup-node@v1 14 | with: 15 | node-version: 10 16 | 17 | - name: Install Dependencies 18 | run: yarn install --ignore-engines 19 | 20 | - name: Execute Tests & generate coverage 21 | run: yarn test 22 | 23 | - name: Execute lint check 24 | run: yarn lint 25 | 26 | - name: upload code coverage for all packages 27 | run: bash <(curl -s https://codecov.io/bash) -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .vscode 3 | *.iml 4 | 5 | package-lock.json 6 | yarn.lock 7 | 8 | # output folder 9 | target 10 | 11 | # Logs 12 | logs 13 | *.log 14 | npm-debug.log* 15 | yarn-debug.log* 16 | yarn-error.log* 17 | 18 | # Runtime data 19 | pids 20 | *.pid 21 | *.seed 22 | *.pid.lock 23 | 24 | # Directory for instrumented libs generated by jscoverage/JSCover 25 | lib-cov 26 | 27 | # Test Output 28 | .nyc_output 29 | newtest 30 | 31 | # Coverage directory used by tools like istanbul 32 | coverage 33 | *.lcov 34 | 35 | # Compiled binary addons (https://nodejs.org/api/addons.html) 36 | build/Release 37 | 38 | # Dependency directories 39 | node_modules/ 40 | jspm_packages/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | -------------------------------------------------------------------------------- /packages/index-converter/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @adobe/aem-cs-source-migration-index-converter 2 | 3 | ## 0.2.1 4 | 5 | ### Patch Changes 6 | 7 | - Updated dependencies [a721a77] 8 | - @adobe/aem-cs-source-migration-commons@0.0.5 9 | 10 | ## 0.2.0 11 | 12 | ### Minor Changes 13 | 14 | - fbad421: CQ-4325470 : Rebase .content_Cloud_Services.xml (AEMaaCS baseline xml) from the latest AEMaaCS sdk. 15 | CQ-4324272 : Migrate tika config 16 | 17 | ## 0.1.2 18 | 19 | ### Patch Changes 20 | 21 | - Updated dependencies [dbd23f2] 22 | - @adobe/aem-cs-source-migration-commons@0.0.4 23 | 24 | ## 0.1.1 25 | 26 | ### Patch Changes 27 | 28 | - f61d256: CQ-4321487:[Index Converter] Fails when config has no customOakIndexDirectoryPath mentioned 29 | 30 | ## 0.1.0 31 | 32 | ### Minor Changes 33 | 34 | - 39ad328: Enhancement in Index converter tool for considering filter analyzers 35 | -------------------------------------------------------------------------------- /packages/dispatcher-converter/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | Unless required by applicable law or agreed to in writing, software distributed under 7 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 8 | OF ANY KIND, either express or implied. See the License for the specific language 9 | governing permissions and limitations under the License. 10 | */ 11 | 12 | const AEMDispatcherConfigConverter = require("./src/converter/amsDispatcherConfigConverter"); 13 | const SingleFilesConverter = require("./src/converter/singleFilesConverter"); 14 | 15 | module.exports = { AEMDispatcherConfigConverter, SingleFilesConverter }; 16 | -------------------------------------------------------------------------------- /packages/repository-modernizer/jest.setup.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | Unless required by applicable law or agreed to in writing, software distributed under 7 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 8 | OF ANY KIND, either express or implied. See the License for the specific language 9 | governing permissions and limitations under the License. 10 | */ 11 | 12 | const { stdout, stderr } = require("stdout-stderr"); 13 | 14 | jest.setTimeout(30000); 15 | 16 | // trap console log 17 | beforeEach(() => { 18 | stdout.start(); 19 | stderr.start(); 20 | }); 21 | afterEach(() => { 22 | stdout.stop(); 23 | stderr.stop(); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/repository-modernizer/resources/all/src/main/content/META-INF/vault/filter.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /packages/repository-modernizer/validator/validate.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under 8 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | OF ANY KIND, either express or implied. See the License for the specific language 10 | governing permissions and limitations under the License. 11 | */ 12 | 13 | const Validator = require("./validator"); 14 | const fs = require("fs"); 15 | const yaml = require("js-yaml"); 16 | const path = require("path"); 17 | 18 | const yamlFile = fs.readFileSync( 19 | path.join(process.cwd(), "config.yaml"), 20 | "utf8" 21 | ); 22 | let config = yaml.safeLoad(yamlFile); 23 | let validator = new Validator(config); 24 | validator.validate(); 25 | -------------------------------------------------------------------------------- /packages/index-converter/executors/config.yaml: -------------------------------------------------------------------------------- 1 | indexConverter: 2 | # Absolute path to the jcr_root directory of the package containing the Ensure Index Definitions 3 | # (please ignore if there are no Ensure Index Definitions) 4 | # eg. /Users/xyz/sampleCode/CONTENT/src/main/content/jcr_root 5 | ensureIndexDefinitionContentPackageJcrRootPath: 6 | # Absolute path to the jcr_root directory of the package containing the Ensure Oak Index OSGI Configuration 7 | # (please ignore if there are no Ensure Index Definitions) 8 | # eg. /Users/xyz/sampleCode/CONFIG/src/main/content/jcr_root 9 | ensureIndexDefinitionConfigPackageJcrRootPath: 10 | # Version of AEM customer is on, used to determine the baseline index definitions 11 | aemVersion: 12 | # Path to the customer OAK Index Definition directory 13 | # (please ignore if there are no Custom Oak Index Definitions under /oak:index) 14 | # eg /Users/xyz/sampleCode/ui.apps/src/main/content/jcr_root/_oak_index 15 | customOakIndexDirectoryPath: 16 | # Path to the existing package `filter.xml` file 17 | # eg /Users/xyz/sampleCode/ui.apps/src/main/content/META-INF/vault/filter.xml 18 | filterXMLPath: 19 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish Packages 2 | 3 | on: 4 | push: 5 | branches: 6 | - master # Change this to your default branch 7 | 8 | jobs: 9 | 10 | publish-npm: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout Repo 14 | uses: actions/checkout@v2 15 | with: 16 | # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits 17 | fetch-depth: 0 18 | 19 | - name: Setup Node.js 10 20 | uses: actions/setup-node@v1 21 | with: 22 | node-version: 10 23 | 24 | - name: Install Dependencies 25 | run: yarn install --ignore-engines 26 | 27 | - name: Execute Tests 28 | run: yarn test 29 | 30 | - name: Create Release Pull Request or Publish to npm 31 | id: changesets 32 | uses: changesets/action@master 33 | with: 34 | publish: yarn changeset publish 35 | env: 36 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Leave this as is, it's automatically generated 37 | NPM_TOKEN: ${{ secrets.ADOBE_BOT_NPM_TOKEN }} # This will be shared with your repo as an org secret 38 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thanks for choosing to contribute! 4 | 5 | The following are a set of guidelines to follow when contributing to this project. 6 | 7 | ## Code Of Conduct 8 | 9 | This project adheres to the Adobe [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [Grp-opensourceoffice@adobe.com](mailto:Grp-opensourceoffice@adobe.com). 10 | 11 | ## Contributor License Agreement 12 | 13 | All third-party contributions to this project must be accompanied by a signed contributor license agreement. This gives Adobe permission to redistribute your contributions as part of the project. [Sign our CLA](http://opensource.adobe.com/cla.html). You only need to submit an Adobe CLA one time, so if you have submitted one previously, you are good to go! 14 | 15 | ## Code Reviews 16 | 17 | All submissions should come in the form of pull requests and need to be reviewed by project committers. Read [GitHub's pull request documentation](https://help.github.com/articles/about-pull-requests/) for more information on sending pull requests. 18 | 19 | Lastly, please follow the [pull request template](PULL_REQUEST_TEMPLATE.md) when submitting a pull request! 20 | -------------------------------------------------------------------------------- /packages/repository-modernizer/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @adobe/aem-cs-source-migration-repository-modernizer 2 | 3 | ## 1.2.2 4 | 5 | ### Patch Changes 6 | 7 | - Updated dependencies [a721a77] 8 | - @adobe/aem-cs-source-migration-commons@0.0.5 9 | 10 | ## 1.2.1 11 | 12 | ### Patch Changes 13 | 14 | - dbd23f2: CQ-4326843 : null & undefined check rectification in the script. 15 | - Updated dependencies [dbd23f2] 16 | - @adobe/aem-cs-source-migration-commons@0.0.4 17 | 18 | ## 1.2.0 19 | 20 | ### Minor Changes 21 | 22 | - 50b315b: CQ-4325871 : Update filevault-package-maven-plugin version 23 | CQ-4325771 : Sub Projects not getting transformed properly 24 | CQ-4325180 : Review Improvements for repository modernizer tool 25 | CQ-4325182 : LogManager.factory.config issue 26 | 27 | ## 1.1.3 28 | 29 | ### Patch Changes 30 | 31 | - 35f4996: CQ-4309362 : [Repo-modernizer] Create reactor poms for each individual 32 | CQ-4324531 : Multivalued and Datatypes issue 33 | CQ-4323820 : Discrepancies in POM XML after transformation 34 | CQ-4323523 : Increase code coverage for repo-modenizer 35 | 36 | ## 1.1.2 37 | 38 | ### Patch Changes 39 | 40 | - f61d256: CQ-4321083: [Repo-modernizer] Core and Frontend Module not getting transformed in Repo Modernizer 41 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@adobe/aem-cloud-service-source-migration", 3 | "description": "Code refactoring tools created for migrating customers to AEM as a Cloud Service", 4 | "version": "0.0.0", 5 | "repository": "https://github.com/adobe/aem-cloud-service-source-migration", 6 | "author": "Adobe Inc.", 7 | "license": "Apache-2.0", 8 | "homepage": "https://github.com/adobe/aem-cloud-service-source-migration", 9 | "private": true, 10 | "scripts": { 11 | "test": "lerna run test", 12 | "lint": "lerna run lint" 13 | }, 14 | "pre-commit": [ 15 | "lint" 16 | ], 17 | "workspaces": [ 18 | "packages/*" 19 | ], 20 | "lint-staged": { 21 | "*.{js,yaml,md}": [ 22 | "prettier --write", 23 | "git add" 24 | ] 25 | }, 26 | "devDependencies": { 27 | "@changesets/cli": "^2.14.1", 28 | "eslint": "^7.7.0", 29 | "eslint-config-prettier": "^6.11.0", 30 | "eslint-plugin-prettier": "^3.1.4", 31 | "lerna": "^3.22.1", 32 | "lint-staged": "^7.3.0", 33 | "pre-commit": "^1.2.2", 34 | "prettier": "^2.0.5" 35 | }, 36 | "dependencies": { 37 | "changeset": "^0.2.6" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/index-converter/test/resources/ensureDefinitions/oak-index/custLucene/.content.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 13 | 14 | 18 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | status: 3 | project: 4 | default: off 5 | dispatcher-converter: 6 | target: auto 7 | threshold: 0% 8 | base: auto 9 | flags: 10 | - unit 11 | branches: 12 | - master 13 | if_ci_failed: error 14 | only_pulls: false 15 | flags: dispatcher-converter 16 | index-converter: 17 | target: auto 18 | threshold: 0% 19 | base: auto 20 | flags: 21 | - unit 22 | branches: 23 | - master 24 | if_ci_failed: error 25 | only_pulls: false 26 | flags: index-converter 27 | repository-modernizer: 28 | target: auto 29 | threshold: 0% 30 | base: auto 31 | flags: 32 | - unit 33 | branches: 34 | - master 35 | if_ci_failed: error 36 | only_pulls: false 37 | flags: repository-modernizer 38 | 39 | flags: 40 | dispatcher-converter: 41 | paths: 42 | - packages/dispatcher-converter/ 43 | index-converter: 44 | paths: 45 | - packages/index-converter/ 46 | repository-modernizer: 47 | paths: 48 | - packages/repository-modernizer/ 49 | tests: 50 | paths: 51 | - test/ -------------------------------------------------------------------------------- /packages/repository-modernizer/resources/all/src/main/content/META-INF/vault/definition/.content.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 23 | 24 | -------------------------------------------------------------------------------- /packages/dispatcher-converter/docs.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under 8 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | OF ANY KIND, either express or implied. See the License for the specific language 10 | governing permissions and limitations under the License. 11 | */ 12 | 13 | const jsdoc2md = require("jsdoc-to-markdown"); 14 | const fs = require("fs"); 15 | 16 | jsdoc2md.render({ files: "src/util/FileOperations.js" }).then((contents) => { 17 | fs.writeFile("docs/FileOperations.md", contents, function (err) { 18 | if (err) throw err; 19 | console.log("File is created successfully."); 20 | }); 21 | }); 22 | 23 | jsdoc2md.render({ files: "src/util/FolderOperations.js" }).then((contents) => { 24 | fs.writeFile("docs/FolderOperations.md", contents, function (err) { 25 | if (err) throw err; 26 | console.log("File is created successfully."); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/commons/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under 8 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | OF ANY KIND, either express or implied. See the License for the specific language 10 | governing permissions and limitations under the License. 11 | */ 12 | 13 | const logger = require("./src/logger"); 14 | const constants = require("./src/constants"); 15 | const util = require("./src/util"); 16 | const ConversionStep = require("./src/conversion_report/conversion_step"); 17 | const ConversionOperation = require("./src/conversion_report/conversion_operation"); 18 | const SummaryReportWriter = require("./src/conversion_report/summary_report_writer"); 19 | const DetectionList = require("./src/conversion_report/detection_list"); 20 | module.exports = { 21 | logger, 22 | constants, 23 | util, 24 | ConversionStep, 25 | ConversionOperation, 26 | SummaryReportWriter, 27 | DetectionList, 28 | }; 29 | -------------------------------------------------------------------------------- /packages/index-converter/test/resources/_oak_index/test-lead-form/.content.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 17 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /packages/index-converter/test/resources/_oak_index/test-lead-form1/.content.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 17 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /packages/index-converter/test/resources/_oak_index_1/test-lead-form/.content.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 17 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /packages/commons/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@adobe/aem-cs-source-migration-commons", 3 | "description": "Common helper utilities used by AEM as a Cloud Service code refactoring tools", 4 | "version": "0.0.5", 5 | "repository": "https://github.com/adobe/aem-cloud-service-source-migration/tree/master/packages/commons", 6 | "author": "Adobe Inc.", 7 | "license": "Apache-2.0", 8 | "homepage": "https://github.com/adobe/aem-cloud-service-source-migration/tree/master/packages/commons", 9 | "bugs": "https://github.com/adobe/aem-cloud-service-source-migration/issues", 10 | "main": "index.js", 11 | "publishConfig": { 12 | "access": "public" 13 | }, 14 | "engines": { 15 | "node": ">=10.0.0" 16 | }, 17 | "dependencies": { 18 | "fs-extra": "^9.0.0", 19 | "glob": "^7.1.6", 20 | "winston": "^3.2.1" 21 | }, 22 | "devDependencies": { 23 | "chai": "^4.2.0", 24 | "istanbul": "^0.4.5", 25 | "jsdoc-to-markdown": "^5.0.3", 26 | "mocha": "^7.1.2", 27 | "mocha-sinon": "^2.1.2", 28 | "nyc": "^15.1.0" 29 | }, 30 | "scripts": { 31 | "lint": "eslint index.js src test", 32 | "test": "nyc mocha && nyc report --reporter=text-lcov > coverage.lcov", 33 | "generateDocumentation": "node docs.js" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/index-converter/test/resources/expectedNested1.json: -------------------------------------------------------------------------------- 1 | {"jcr:root":{"test-lead-form":{"_attributes":{"jcr:primaryType":"oak:QueryIndexDefinition","async":"async","fulltextEnabled":"{Boolean}false","includedPaths":"[/etc/test]","reindex":"{Boolean}false","type":"lucene"},"indexRules":{"_attributes":{"jcr:primaryType":"nt:unstructured"},"sling:Folder":{"_attributes":{"jcr:primaryType":"nt:unstructured"},"properties":{"_attributes":{"jcr:primaryType":"nt:unstructured"},"jcrcreated":{"_attributes":{"jcr:primaryType":"nt:unstructured","name":"jcr:created","propertyIndex":"{Boolean}true","type":"Date"}},"pageSource":{"_attributes":{"jcr:primaryType":"nt:unstructured","name":"pageSource","propertyIndex":"{Boolean}true","type":"String"}}}}}},"_attributes":{"xmlns:oak":"http://jackrabbit.apache.org/oak/ns/1.0","xmlns:slingevent":"http://sling.apache.org/jcr/event/1.0","xmlns:sling":"http://sling.apache.org/jcr/sling/1.0","xmlns:cm":"http://www.adobe.com/aemfd/cm/1.0","xmlns:granite":"http://www.adobe.com/jcr/granite/1.0","xmlns:social":"http://www.adobe.com/social/1.0","xmlns:dam":"http://www.day.com/dam/1.0","xmlns:cq":"http://www.day.com/jcr/cq/1.0","xmlns:jcr":"http://www.jcp.org/jcr/1.0","xmlns:mix":"http://www.jcp.org/jcr/mix/1.0","xmlns:nt":"http://www.jcp.org/jcr/nt/1.0","xmlns:rep":"internal","jcr:mixinTypes":"[rep:AccessControllable]","jcr:primaryType":"nt:unstructured"}}} 2 | -------------------------------------------------------------------------------- /packages/commons/src/constants.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under 8 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | OF ANY KIND, either express or implied. See the License for the specific language 10 | governing permissions and limitations under the License. 11 | */ 12 | 13 | module.exports = { 14 | TARGET_FOLDER: "./target", 15 | 16 | LOG_FILE: "./target/result.log", 17 | 18 | TEMPLATE_FOLDER: "templates", 19 | 20 | TARGET_PROJECT_FOLDER: "./target/project", 21 | 22 | TARGET_PROJECT_SRC_FOLDER: "./target/project/src", 23 | 24 | TARGET_DISPATCHER_FOLDER: "./target/dispatcher", 25 | 26 | TARGET_INDEX_FOLDER: "./target/index", 27 | 28 | TARGET_DISPATCHER_SRC_FOLDER: "./target/dispatcher/src", 29 | 30 | SUMMARY_REPORT_LINE_SEPARATOR: "\n", 31 | 32 | WARNING: "WARNING", 33 | 34 | ACTION_ADDED: "Added", 35 | 36 | ACTION_DELETED: "Deleted", 37 | 38 | ACTION_REMOVED: "Removed", 39 | 40 | ACTION_RENAMED: "Renamed", 41 | 42 | ACTION_MODIFIED: "Modified", 43 | 44 | ACTION_REPLACED: "Replaced", 45 | }; 46 | -------------------------------------------------------------------------------- /packages/commons/src/logger.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under 8 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | OF ANY KIND, either express or implied. See the License for the specific language 10 | governing permissions and limitations under the License. 11 | */ 12 | 13 | const constants = require("./constants"); 14 | const winston = require("winston"); 15 | const path = require("path"); 16 | 17 | const logger = new winston.createLogger({ 18 | level: "verbose", 19 | format: winston.format.combine( 20 | winston.format.timestamp({ format: `ddd, DD MMM YYYY HH:mm:ss` }), 21 | winston.format.printf((log) => { 22 | return `${log.timestamp} | ${log.level}: ${log.message}`; 23 | }) 24 | ), 25 | transports: [ 26 | new winston.transports.File({ 27 | colorize: true, 28 | json: false, 29 | filename: path.join(process.cwd(), constants.LOG_FILE), 30 | level: "info", 31 | }), 32 | ], 33 | }); 34 | 35 | logger.stream = { 36 | write: function (message) { 37 | logger.info(message); 38 | }, 39 | }; 40 | 41 | module.exports = logger; 42 | -------------------------------------------------------------------------------- /packages/commons/test/ConversionOperationTest.js: -------------------------------------------------------------------------------- 1 | const AssertionError = require("chai").assert; 2 | const assert = require("chai").assert; 3 | const conversionOperation = require("../src/conversion_report/conversion_operation"); 4 | 5 | describe("ConversionOperation", () => { 6 | beforeEach(() => { 7 | this.conversionOp = new conversionOperation( 8 | "type", 9 | "location", 10 | "action" 11 | ); 12 | }); 13 | 14 | it("test get operation type", () => { 15 | try { 16 | assert.isTrue( 17 | this.conversionOp.getOperationType().toString() === "type", 18 | "Type is as expected" 19 | ); 20 | } catch (e) { 21 | if (e instanceof AssertionError) { 22 | throw e; 23 | } 24 | } 25 | }); 26 | 27 | it("test get operation location", () => { 28 | try { 29 | assert.isTrue( 30 | this.conversionOp.getOperationLocation().toString() === 31 | "location", 32 | "Location is as expected" 33 | ); 34 | } catch (e) { 35 | if (e instanceof AssertionError) { 36 | throw e; 37 | } 38 | } 39 | }); 40 | 41 | it("test get operation action", () => { 42 | try { 43 | assert.isTrue( 44 | this.conversionOp.getOperationAction().toString() === "action" 45 | ); 46 | } catch (e) { 47 | if (e instanceof AssertionError) { 48 | throw e; 49 | } 50 | } 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /packages/repository-modernizer/test/resources/com.adobe.config.test.cfg.json: -------------------------------------------------------------------------------- 1 | { 2 | "localeLangSettings":[{"localeLanguage":"us-en_us","destinationPath":"/content/hbtbt/us/en/products","byCategoryPath":"/content/hbtbt/us/en/products/by-category","categoryFragmentPath":"/content/experience-fragments/hbtbt/us/en/products","alternativeProductsTitle":"Related Products","productDocumentType":"Product","navigationTitle":"","heroTitleField":"longLabel"},{"localeLanguage":"in-en","destinationPath":"/content/hbtbt/in/en/products","byCategoryPath":"/content/hbtbt/in/en/products/by-category","categoryFragmentPath":"/content/experience-fragments/hbtbt/in/en/products","alternativeProductsTitle":"Related Products","productDocumentType":"Product","navigationTitle":"","heroTitleField":"longLabel"},{"localeLanguage":"gb-en_gb","destinationPath":"/content/hbtbt/gb/en/products","byCategoryPath":"/content/hbtbt/gb/en/products/by-category","categoryFragmentPath":"/content/experience-fragments/hbtbt/gb/en/products","alternativeProductsTitle":"Related Products","productDocumentType":"Product","navigationTitle":"","heroTitleField":"longLabel"},{"localeLanguage":"de-de_de","destinationPath":"/content/hbtbt/de/de/products","byCategoryPath":"/content/hbtbt/de/de/products/by-category","categoryFragmentPath":"/content/experience-fragments/hbtbt/de/de/products","alternativeProductsTitle":"Related Products","productDocumentType":"Product","navigationTitle":"","heroTitleField":"longLabel"}], 3 | "enabled:Boolean":true, 4 | "error-page.system-path":"/content/404", 5 | "serve-authenticated-from-cache:Boolean":true, 6 | "test-array":["test1","test2"], 7 | "test-complex":"{0,date,yyyy-MM-dd HH:mm:ss.SSS} {4} [{3}] {5}" 8 | } 9 | -------------------------------------------------------------------------------- /packages/index-converter/executors/index-converter.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | Unless required by applicable law or agreed to in writing, software distributed under 7 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 8 | OF ANY KIND, either express or implied. See the License for the specific language 9 | governing permissions and limitations under the License. 10 | */ 11 | 12 | const IndexConverter = require(".."); 13 | const fs = require("fs"); 14 | const yaml = require("js-yaml"); 15 | const { 16 | constants: commons_constants, 17 | logger, 18 | util, 19 | } = require("@adobe/aem-cs-source-migration-commons"); 20 | const yamlFile = fs.readFileSync(process.cwd() + "/config.yaml", "utf8"); 21 | let config = yaml.safeLoad(yamlFile); 22 | // if target index definition folder exists, delete it 23 | if (fs.existsSync(commons_constants.TARGET_FOLDER)) { 24 | logger.info( 25 | "Deleting existing target folder, path :" + 26 | commons_constants.TARGET_FOLDER 27 | ); 28 | util.deleteFolderRecursive(commons_constants.TARGET_FOLDER); 29 | logger.info( 30 | "Deleted existing target folder, path :" + 31 | commons_constants.TARGET_FOLDER 32 | ); 33 | } 34 | 35 | executeIndexConversion(config); 36 | 37 | async function executeIndexConversion(config) { 38 | IndexConverter.performIndexConversion(config.indexConverter, ".."); 39 | } 40 | -------------------------------------------------------------------------------- /packages/dispatcher-converter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@adobe/aem-cs-source-migration-dispatcher-converter", 3 | "description": "AEM as a Cloud Service Dispatcher Converter tool", 4 | "version": "1.5.1", 5 | "repository": "https://github.com/adobe/aem-cloud-service-source-migration/tree/master/packages/dispatcher-converter", 6 | "author": "Adobe Inc.", 7 | "license": "Apache-2.0", 8 | "homepage": "https://github.com/adobe/aem-cloud-service-source-migration/tree/master/packages/dispatcher-converter", 9 | "bugs": "https://github.com/adobe/aem-cloud-service-source-migration/issues", 10 | "main": "index.js", 11 | "publishConfig": { 12 | "access": "public" 13 | }, 14 | "engines": { 15 | "node": ">=10.0.0" 16 | }, 17 | "dependencies": { 18 | "@adobe/aem-cs-source-migration-commons": "^0.0.5", 19 | "glob": "^7.1.6", 20 | "js-yaml": "^3.14.0", 21 | "log-timestamp": "^0.3.0", 22 | "winston": "^3.2.1", 23 | "yaml": "^1.10.0" 24 | }, 25 | "devDependencies": { 26 | "chai": "^4.2.0", 27 | "istanbul": "^0.4.5", 28 | "jsdoc-to-markdown": "^5.0.3", 29 | "mocha": "^7.1.2", 30 | "mocha-sinon": "^2.1.2", 31 | "nyc": "^15.1.0" 32 | }, 33 | "scripts": { 34 | "lint": "eslint index.js src test executors --ignore-pattern executors/target/", 35 | "test": "nyc mocha && nyc report --reporter=text-lcov > coverage.lcov", 36 | "coverage": "nyc --reporter=lcov --reporter=text-lcov npm test", 37 | "convert": "node main.js", 38 | "convertSingleFile": "node singleFileMain.js", 39 | "generateDocumentation": "node docs.js" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/repository-modernizer/validator/constants.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under 8 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | OF ANY KIND, either express or implied. See the License for the specific language 10 | governing permissions and limitations under the License. 11 | */ 12 | 13 | module.exports = { 14 | UI_APPS: "ui.apps", 15 | 16 | UI_CONTENT: "ui.content", 17 | 18 | // Filter path from project root 19 | FILTER_PATH: "/src/main/content/META-INF/vault/filter.xml", 20 | 21 | // filter.xml starting lines 22 | FILTER_XML_START: [ 23 | '', 24 | '', 25 | ], 26 | 27 | FILTER_XML_END: [""], 28 | 29 | FILTER_SECTION_END: [""], 30 | 31 | FILEVAULT_PLUGIN: "filevault-package-maven-plugin", 32 | 33 | FILEVAULT_PLUGIN_EXPECTED_VERSION: "1.1.4", 34 | 35 | PACKAGE_TYPE: "", 36 | 37 | PLUGINS_SECTION_START: "", 38 | 39 | PLUGINS_SECTION_END: "", 40 | 41 | ARTIFACT_ID_START_TAG: " ", 42 | 43 | ARTIFACT_ID_END_TAG: "", 44 | 45 | CLOUD_MANAGER_TARGET: "", 46 | 47 | POM_XML: "pom.xml", 48 | 49 | VERSION_START_TAG: "", 50 | 51 | VERSION_END_TAG: "", 52 | 53 | CONFIGURATION_START_TAG: "", 54 | }; 55 | -------------------------------------------------------------------------------- /packages/index-converter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@adobe/aem-cs-source-migration-index-converter", 3 | "description": "AEM as a Cloud Service Index Converter tool", 4 | "version": "0.2.1", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/adobe/aem-cloud-service-source-migration/tree/master/packages/index-converter" 8 | }, 9 | "author": "Adobe Inc.", 10 | "license": "Apache-2.0", 11 | "homepage": "https://github.com/adobe/aem-cloud-service-source-migration/tree/master/packages/index-converter", 12 | "bugs": { 13 | "url": "https://github.com/adobe/aem-cloud-service-source-migration/issues" 14 | }, 15 | "main": "index.js", 16 | "publishConfig": { 17 | "access": "public" 18 | }, 19 | "engines": { 20 | "node": ">=10.0.0" 21 | }, 22 | "dependencies": { 23 | "@adobe/aem-cs-source-migration-commons": "^0.0.5", 24 | "fs-extra": "^9.0.1", 25 | "js-yaml": "^3.14.0", 26 | "jsondiffpatch": "^0.4.1", 27 | "merge-json": "0.1.0-b.3", 28 | "winston": "^3.3.3", 29 | "xml-formatter": "^2.1.3", 30 | "xml-js": "^1.6.11", 31 | "yaml": "^1.10.0" 32 | }, 33 | "devDependencies": { 34 | "chai": "^4.2.0", 35 | "istanbul": "^0.4.5", 36 | "jsdoc-to-markdown": "^5.0.3", 37 | "mocha": "^8.1.3", 38 | "mocha-sinon": "^2.1.2", 39 | "nyc": "^15.1.0" 40 | }, 41 | "scripts": { 42 | "lint": "eslint index.js src test executors --ignore-pattern executors/target/", 43 | "test": "nyc mocha && nyc report --reporter=text-lcov > coverage.lcov", 44 | "coverage": "nyc --reporter=lcov --reporter=text-lcov npm test", 45 | "generateDocumentation": "node docs.js" 46 | }, 47 | "directories": { 48 | "test": "test" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Description 4 | 5 | 6 | 7 | ## Related Issue 8 | 9 | 10 | 11 | 12 | 13 | 14 | ## Motivation and Context 15 | 16 | 17 | 18 | ## How Has This Been Tested? 19 | 20 | 21 | 22 | 23 | 24 | ## Screenshots (if appropriate): 25 | 26 | ## Types of changes 27 | 28 | 29 | 30 | - [ ] Bug fix (non-breaking change which fixes an issue) 31 | - [ ] New feature (non-breaking change which adds functionality) 32 | - [ ] Breaking change (fix or feature that would cause existing functionality to change) 33 | 34 | ## Checklist: 35 | 36 | 37 | 38 | 39 | - [ ] I have signed the [Adobe Open Source CLA](http://opensource.adobe.com/cla.html). 40 | - [ ] My code follows the code style of this project. 41 | - [ ] My change requires a change to the documentation. 42 | - [ ] I have updated the documentation accordingly. 43 | - [ ] I have read the **CONTRIBUTING** document. 44 | - [ ] I have added tests to cover my changes. 45 | - [ ] All new and existing tests passed. 46 | -------------------------------------------------------------------------------- /packages/index-converter/test/resources/output_json.json: -------------------------------------------------------------------------------- 1 | { 2 | "xmlns:cm": "http://", 3 | "xmlns:oak": "http://jackrabbit.apache.org/oak/ns/1.0", 4 | "xmlns:slingevent": "http://sling.apache.org/jcr/event/1.0", 5 | "xmlns:sling": "http://sling.apache.org/jcr/sling/1.0", 6 | "xmlns:granite": "http://www.adobe.com/jcr/granite/1.0", 7 | "xmlns:social": "http://www.adobe.com/social/1.0", 8 | "xmlns:dam": "http://www.day.com/dam/1.0", 9 | "xmlns:cq": "http://www.day.com/jcr/cq/1.0", 10 | "xmlns:jcr": "http://www.jcp.org/jcr/1.0", 11 | "xmlns:mix": "http://www.jcp.org/jcr/mix/1.0", 12 | "xmlns:nt": "http://www.jcp.org/jcr/nt/1.0", 13 | "xmlns:rep": "internal", 14 | "jcr:mixinTypes": "[rep:AccessControllable]", 15 | "jcr:primaryType": "nt:unstructured", 16 | "socialLucene": { 17 | "jcr:primaryType": "oak:QueryIndexDefinition", 18 | "async": "[async,nrt]", 19 | "compatVersion": "{Long}2", 20 | "evaluatePathRestrictions": "{Boolean}true", 21 | "name": "socialLucene", 22 | "reindex": "{Boolean}false", 23 | "reindexCount": "{Long}1", 24 | "seed": "{Long}2686807359705661613", 25 | "type": "lucene", 26 | "indexRules": { 27 | "jcr:primaryType": "nt:unstructured", 28 | "social:asiResource": { 29 | "jcr:primaryType": "nt:unstructured", 30 | "indexNodeName": "{Boolean}true", 31 | "properties": { 32 | "jcr:primaryType": "nt:unstructured", 33 | "social:baseType": { 34 | "jcr:primaryType": "nt:unstructured", 35 | "name": "social:baseType", 36 | "propertyIndex": "{Boolean}true" 37 | }, 38 | "resourceType": { 39 | "jcr:primaryType": "nt:unstructured", 40 | "name": "sling:resourceType", 41 | "propertyIndex": "{Boolean}true" 42 | } 43 | } 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/repository-modernizer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@adobe/aem-cs-source-migration-repository-modernizer", 3 | "description": "AEM as a Cloud Service Project Restructuring tool", 4 | "version": "1.2.2", 5 | "repository": "https://github.com/adobe/aem-cloud-service-source-migration/tree/master/packages/repository-modernizer", 6 | "author": "Adobe Inc.", 7 | "license": "Apache-2.0", 8 | "homepage": "https://github.com/adobe/aem-cloud-service-source-migration/tree/master/packages/repository-modernizer", 9 | "bugs": "https://github.com/adobe/aem-cloud-service-source-migration/issues", 10 | "main": "index.js", 11 | "publishConfig": { 12 | "access": "public" 13 | }, 14 | "engines": { 15 | "node": ">=10.0.0" 16 | }, 17 | "scripts": { 18 | "lint": "eslint index.js src validator executors --ignore-pattern executors/target/", 19 | "test": "jest --coverage" 20 | }, 21 | "dependencies": { 22 | "@adobe/aem-cs-source-migration-commons": "^0.0.5", 23 | "dirty-json": "^0.9.2", 24 | "fs-extra": "^9.0.0", 25 | "js-yaml": "^3.14.0", 26 | "node-fetch": "^2.6.1", 27 | "node-pom-parser": "^0.1.1", 28 | "rewire": "^5.0.0", 29 | "stdout-stderr": "^0.1.9", 30 | "winston": "^3.2.1", 31 | "xml-js": "^1.6.11", 32 | "yaml": "^1.10.0" 33 | }, 34 | "devDependencies": { 35 | "jest": "^26.4.2", 36 | "jest-junit": "^6.0.0" 37 | }, 38 | "jest": { 39 | "collectCoverage": true, 40 | "testPathIgnorePatterns": [ 41 | "/tests/fixtures/" 42 | ], 43 | "coveragePathIgnorePatterns": [ 44 | "/tests/fixtures/" 45 | ], 46 | "reporters": [ 47 | "default", 48 | "jest-junit" 49 | ], 50 | "testEnvironment": "node", 51 | "setupFilesAfterEnv": [ 52 | "./jest.setup.js" 53 | ], 54 | "clearMocks": true 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /packages/dispatcher-converter/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @adobe/aem-cs-source-migration-dispatcher-converter 2 | 3 | ## 1.5.1 4 | 5 | ### Patch Changes 6 | 7 | - a3a70fd: CQ-4357130 : [Dispatcher Converter] Duplicate variables present in consolidated custom vars file 8 | 9 | ## 1.5.0 10 | 11 | ### Minor Changes 12 | 13 | - 6b9df60: CQ-4329547 : [Dispatcher converter] Error running the tool on AMS configs which includes sym-linked files, invalid includes 14 | CQ-4330105 : [Dispatcher Converter] Migration failure for AMS based project due to rules files inclusion. 15 | 16 | ### Patch Changes 17 | 18 | - Updated dependencies [a721a77] 19 | - @adobe/aem-cs-source-migration-commons@0.0.5 20 | 21 | ## 1.4.0 22 | 23 | ### Minor Changes 24 | 25 | - fbad421: CQ-4328313 : Issue with vhostsToConvert & \$Include property 26 | CQ-4328889 : Rules file inclusion issue. 27 | CQ-4315907 : Customisation required for existing custom-variables into global.vars for AMS configs 28 | 29 | ## 1.3.0 30 | 31 | ### Minor Changes 32 | 33 | - dbd23f2: CQ-4327181 : Changes to dispatcher converter aligned with archetype 28. 34 | CQ-4327905 : [Unilever][dispatcher converter] Outstanding issue. 35 | CQ-4327568 : [Dispatcher Converter] Issue in the conversion when duplicate farm files are present. 36 | CQ-4327400 : [Dispatcher Converter] RewriteRules getting commented. 37 | CQ-4327400 : Dispatcher Converter Tool - Unilever Issues. 38 | CQ-4326843 : Properties undefined rectification in the script. 39 | 40 | ### Patch Changes 41 | 42 | - Updated dependencies [dbd23f2] 43 | - @adobe/aem-cs-source-migration-commons@0.0.4 44 | 45 | ## 1.2.1 46 | 47 | ### Patch Changes 48 | 49 | - 50b315b: Fix for error on empty configuration 50 | 51 | ## 1.2.0 52 | 53 | ### Minor Changes 54 | 55 | - f61d256: CQ-4321146:[Dispatcher-Convertor] Unable to covert non-standard dispatcher configurations ,CQ-4321398: Fix symlink logic for AMS dispatcher converter 56 | 57 | ## 1.1.1 58 | 59 | ### Patch Changes 60 | 61 | - b7d34f8: Fixing rule file and rewrite path in farm and vhost files 62 | -------------------------------------------------------------------------------- /packages/commons/src/conversion_report/templates/repository-modernizer-report.md: -------------------------------------------------------------------------------- 1 | # AEM as a Cloud Service - Repository Modernizer Report 2 | This report contains the changes that have been made to your repository package structure by the tool. 3 | After reviewing these changes, you should simply run the validator on the new packages, to check the state. 4 | 5 | ## Project Structure changes 6 | 7 | AEM requires a separation of content and code, which means a single content package cannot deploy 8 | to both `/apps` and runtime-writable areas (e.g. `/content` , `/conf` , `/home` , or anything not 9 | `/apps`) of the repository. Instead, the application must separate code and content into discrete 10 | packages for deployment into AEM. 11 | 12 | Adobe Experience Manager Maven projects to be AEM Cloud Service compatible, need to ensure that 13 | * they respect the split of mutable and immutable content 14 | * the requisite dependencies are established to create non-conflicting, deterministic deployments 15 | * they are packaged in a deployable structure - AEM application deployments must be comprised 16 | of a single AEM package. This package should in turn contain sub-packages that comprise 17 | everything required by the application to function, including code, configuration and any 18 | supporting baseline content. 19 | 20 | The objective of this tool is to modernize any given project(s) into AEM Cloud Service compatible 21 | structure, by creating the following deployment structure : 22 | - The `ui.apps` package, or Code Package, contains all the code to be deployed and only deploys 23 | to `/apps` 24 | - The `ui.config` package, or OSGi Configuration Package, contains all OSGi configurations 25 | - The `ui.content` package, or Content Package, contains all content and configuration 26 | - The `all` package is a container package that ONLY includes the `ui.apps` and `ui.content` 27 | packages as embeds 28 | 29 | For conversion of the provided packages to AEM as a Cloud Service compatible package structure, 30 | we have made the following changes to the dispatcher configuration: 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /packages/index-converter/test/resources/_oak_index/.content.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 14 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 34 | 35 | 36 | 37 | 42 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /packages/commons/src/conversion_report/conversion_operation.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under 8 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | OF ANY KIND, either express or implied. See the License for the specific language 10 | governing permissions and limitations under the License. 11 | */ 12 | 13 | class ConversionOperation { 14 | /* 15 | * ConversionOperation describes a single operation (can be add/remove/rename/replace/delete operation) which has been 16 | * performed on the source code as part of some conversion step. 17 | */ 18 | 19 | /** 20 | * 21 | * @param {String} operationType The type of operation performed. 22 | * @param {String} operationLocation The location at which the operation has been performed. 23 | * @param {String} operationAction The gist of the operation performed. 24 | * 25 | */ 26 | constructor(operationType, operationLocation, operationAction) { 27 | this.action = operationAction; 28 | this.location = operationLocation; 29 | this.type = operationType; 30 | } 31 | 32 | /** 33 | * 34 | * @returns {String} 35 | * @private 36 | * 37 | * Get the type of operation performed 38 | */ 39 | getOperationType() { 40 | return this.type; 41 | } 42 | 43 | /** 44 | * 45 | * @returns {String} 46 | * @private 47 | * 48 | * Get the location at which the operation has been performed 49 | */ 50 | getOperationLocation() { 51 | return this.location; 52 | } 53 | 54 | /** 55 | * 56 | * @returns {String} 57 | * @private 58 | * 59 | * Get the gist of the operation performed 60 | */ 61 | getOperationAction() { 62 | return this.action; 63 | } 64 | } 65 | 66 | module.exports = ConversionOperation; 67 | -------------------------------------------------------------------------------- /packages/repository-modernizer/test/resources/com.adobe.config.test.xml: -------------------------------------------------------------------------------- 1 | 2 | 51 | -------------------------------------------------------------------------------- /packages/index-converter/test/resources/expectedNested.json: -------------------------------------------------------------------------------- 1 | {"_declaration":{"_attributes":{"version":"1.0","encoding":"UTF-8"}},"jcr:root":{"_attributes":{"xmlns:oak":"http://jackrabbit.apache.org/oak/ns/1.0","xmlns:sling":"http://sling.apache.org/jcr/sling/1.0","xmlns:jcr":"http://www.jcp.org/jcr/1.0","xmlns:nt":"http://www.jcp.org/jcr/nt/1.0","xmlns:rep":"internal","jcr:mixinTypes":"[rep:AccessControllable]","jcr:primaryType":"nt:unstructured"},"ntBaseLucene":{},"verb":{},"reference":{},"testAssetID":{"_attributes":{"jcr:primaryType":"oak:QueryIndexDefinition","propertyNames":"{Name}[test:AssetID]","reindex":"{Boolean}false","reindexCount":"{Long}0","type":"property"}},"testAssetID1":{"_attributes":{"jcr:primaryType":"oak:QueryIndexDefinition","propertyNames":"{Name}[test:AssetID1]","reindex":"{Boolean}false","reindexCount":"{Long}0","type":"property"}},"lockCreated":{},"principalName":{},"cqTagLucene":{},"lucene":{},"guideComponentType":{},"externalId":{},"slingAlias":{},"test-lead-form":{"_attributes":{"jcr:primaryType":"oak:QueryIndexDefinition","async":"async","fulltextEnabled":"{Boolean}false","includedPaths":"[/etc/test]","reindex":"{Boolean}false","type":"lucene"},"indexRules":{"_attributes":{"jcr:primaryType":"nt:unstructured"},"sling:Folder":{"_attributes":{"jcr:primaryType":"nt:unstructured"},"properties":{"_attributes":{"jcr:primaryType":"nt:unstructured"},"jcrcreated":{"_attributes":{"jcr:primaryType":"nt:unstructured","name":"jcr:created","propertyIndex":"{Boolean}true","type":"Date"}},"pageSource":{"_attributes":{"jcr:primaryType":"nt:unstructured","name":"pageSource","propertyIndex":"{Boolean}true","type":"String"}}}}}},"test-lead-form1":{"_attributes":{"jcr:primaryType":"oak:QueryIndexDefinition","async":"async","fulltextEnabled":"{Boolean}false","includedPaths":"[/etc/test]","reindex":"{Boolean}false","type":"lucene"},"indexRules":{"_attributes":{"jcr:primaryType":"nt:unstructured"},"sling:Folder":{"_attributes":{"jcr:primaryType":"nt:unstructured"},"properties":{"_attributes":{"jcr:primaryType":"nt:unstructured"},"jcrcreated":{"_attributes":{"jcr:primaryType":"nt:unstructured","name":"jcr:created","propertyIndex":"{Boolean}true","type":"Date"}},"pageSource":{"_attributes":{"jcr:primaryType":"nt:unstructured","name":"pageSource","propertyIndex":"{Boolean}true","type":"String"}}}}}}}} 2 | -------------------------------------------------------------------------------- /packages/commons/test/ConversionStepTest.js: -------------------------------------------------------------------------------- 1 | const AssertionError = require("chai").assert; 2 | const assert = require("chai").assert; 3 | const conversionStep = require("../src/conversion_report/conversion_step"); 4 | const conversionOperation = require("../src/conversion_report/conversion_operation"); 5 | const constants = require("../src/constants"); 6 | 7 | describe("ConversionSteps", () => { 8 | beforeEach(() => { 9 | this.step = new conversionStep("rule", "description"); 10 | }); 11 | 12 | it("test get operations", () => { 13 | try { 14 | this.step.addOperation( 15 | new conversionOperation( 16 | constants.ACTION_DELETED, 17 | "location", 18 | "Action" 19 | ) 20 | ); 21 | assert.isTrue( 22 | this.step.getOperations().length > 0, 23 | "Length is greater than 0" 24 | ); 25 | } catch (e) { 26 | if (e instanceof AssertionError) { 27 | throw e; 28 | } 29 | } 30 | }); 31 | 32 | it("test get description", () => { 33 | try { 34 | assert.isTrue( 35 | this.step.getDescription().toString() === "description" 36 | ); 37 | } catch (e) { 38 | if (e instanceof AssertionError) { 39 | throw e; 40 | } 41 | } 42 | }); 43 | 44 | it("test get rule", () => { 45 | try { 46 | assert.isTrue(this.step.getRule().toString() === "rule"); 47 | } catch (e) { 48 | if (e instanceof AssertionError) { 49 | throw e; 50 | } 51 | } 52 | }); 53 | 54 | it("test is Performed", () => { 55 | try { 56 | this.step.addOperation( 57 | new conversionOperation( 58 | constants.ACTION_DELETED, 59 | "location", 60 | "Action" 61 | ) 62 | ); 63 | assert.isTrue(this.step.isPerformed().toString() === "true"); 64 | } catch (e) { 65 | if (e instanceof AssertionError) { 66 | throw e; 67 | } 68 | } 69 | }); 70 | }); 71 | -------------------------------------------------------------------------------- /packages/commons/src/conversion_report/detection_list.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under 8 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | OF ANY KIND, either express or implied. See the License for the specific language 10 | governing permissions and limitations under the License. 11 | */ 12 | 13 | class DetectionList { 14 | /* 15 | * DetectionList describes a list of elements that has been detected with the objective of source migration. 16 | */ 17 | 18 | /** 19 | * 20 | * @param {String} heading The header or tile of the list which describes the list of elements. 21 | * 22 | */ 23 | constructor(heading = "") { 24 | this.heading = heading; 25 | this.detection_list = []; 26 | } 27 | /** 28 | * 29 | * @param {element} 30 | * @private 31 | * 32 | * Add an element that was detected while executing the migration. 33 | */ 34 | addList(element) { 35 | this.detection_list.push(element); 36 | } 37 | 38 | /** 39 | * 40 | * @returns {String} 41 | * @private 42 | * 43 | * Get the heading of the list of elements. 44 | */ 45 | getHeading() { 46 | return this.heading; 47 | } 48 | 49 | /** 50 | * 51 | * @returns {[List[String]]} 52 | * @private 53 | * 54 | * Get the list of elements detected while executing the migration. 55 | */ 56 | getDetectionList() { 57 | return this.detection_list; 58 | } 59 | 60 | /** 61 | * 62 | * @returns {boolean} 63 | * @private 64 | * 65 | * Find whether any element has been detected while executing the migration 66 | * 67 | * Return: 68 | * boolean: `true` if at least one element has been detected or added, else `false` 69 | */ 70 | isDetected() { 71 | return this.detection_list.length > 0; 72 | } 73 | } 74 | 75 | module.exports = DetectionList; 76 | -------------------------------------------------------------------------------- /packages/repository-modernizer/test/config.yaml: -------------------------------------------------------------------------------- 1 | # groupId to be used for newly created packages 2 | groupId: test.aem 3 | # information about parent pom 4 | parentPom: 5 | # absolute path to the parent pom file 6 | path: /test/resources/pom.xml 7 | # the artifactId to be set for the parent pom 8 | artifactId: test-aem-parent 9 | # the application title to be set for the parent pom 10 | appTitle: test-AEM Parent 11 | # version to be to be set for the parent pom 12 | version: 1.0.0-SNAPSHOT 13 | # information required for all package 14 | all: 15 | # prefix that is to be used to set the artifactId for all package 16 | artifactId: test-aem 17 | # application title 18 | appTitle: Test-AEM Code Repository 19 | # version to be set for all pom 20 | version: 1.0.0-SNAPSHOT 21 | # information about projects 22 | projects: 23 | - # absolute path to the project folder 24 | projectPath: /test/resources 25 | # relative path(s) (w.r.t. the project folder) to the existing content package(s) that needs to be restructured 26 | # (expects one or more relative paths to be provided in array format) 27 | existingContentPackageFolder: 28 | - /empty_content 29 | # relative path (w.r.t. the existing content package folder) to the filter.xml file 30 | # (If not specified, default path `/src/main/content/META-INF/vault/filter.xml` will be used.) 31 | relativePathToExistingFilterXml: /src/main/content/META-INF/vault/filter.xml 32 | # relative path (w.r.t. the existing content package folder) to the jcr_root directory 33 | # (If not specified, default path `/src/main/content/jcr_root` will be used) 34 | relativePathToExistingJcrRoot: /jcr_root 35 | # prefix that is to be used to set the artifactId for newly created ui.apps and ui.content packages 36 | artifactId: test-content-aem 37 | # application title 38 | appTitle: test-content 39 | # project specific version to be used for content packages 40 | version: 2.0.0-SNAPSHOT 41 | # application ID (will be used for config and package folder names) 42 | appId: test 43 | # Array of relative path(s) (w.r.t. the project folder) to the existing code bundles (will be embedded in the all package). 44 | coreBundles: 45 | - /core 46 | -------------------------------------------------------------------------------- /packages/repository-modernizer/test/restructure-config.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | Unless required by applicable law or agreed to in writing, software distributed under 7 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 8 | OF ANY KIND, either express or implied. See the License for the specific language 9 | governing permissions and limitations under the License. 10 | */ 11 | const { 12 | logger, 13 | constants, 14 | util, 15 | ConversionStep, 16 | } = require("@adobe/aem-cs-source-migration-commons"); 17 | const rewire = require("rewire"); 18 | let srcPath="./test/resources/"; 19 | let configpath = "./test/resources/ui.config/"; 20 | const configRewire = rewire("./../src/restructure-config"); 21 | const fs = require("fs"); 22 | const fsPromises = require('fs').promises; 23 | 24 | describe(" restructure config", function () { 25 | 26 | test("formatConfig", async () => { 27 | util.deleteFolderRecursive(configpath); 28 | fs.mkdirSync(configpath); 29 | let oldConfigs=['com.adobe.config.test.xml','com.adobe.test.config']; 30 | let newConfigs=['com.adobe.config.test.cfg.json','com.adobe.test.cfg.json']; 31 | let conversionStep = new ConversionStep(); 32 | for (const val of oldConfigs) { 33 | await fsPromises.copyFile(srcPath+val, configpath+val) 34 | .then(function() { 35 | console.log("File Copied"); 36 | }) 37 | .catch(function(error) { 38 | console.log(error); 39 | }); 40 | await configRewire.__get__("formatConfig")(configpath+val,conversionStep); 41 | } 42 | for (const val of newConfigs) { 43 | let fileContent = util.getXMLContentSync(configpath+val); 44 | let content= util.getXMLContentSync(srcPath+val); 45 | expect(fileContent).toEqual(expect.arrayContaining(content)); 46 | } 47 | if (fs.existsSync(configpath)){ 48 | util.deleteFolderRecursive(configpath); 49 | } 50 | }); 51 | 52 | }); 53 | -------------------------------------------------------------------------------- /packages/dispatcher-converter/executors/config.yaml: -------------------------------------------------------------------------------- 1 | dispatcherConverter: 2 | # Absolute path to the src folder of the dispatcher sdk. You must include the src folder itself in the path. 3 | sdkSrc: 4 | # Add information about on-premise dispatcher configuration here 5 | onPremise: 6 | # Absolute path to the dispatcher.any file 7 | # farm files should have ".farm" extension for adding content of a farm file to the output directory. 8 | dispatcherAnySrc: 9 | # Path to the httpd.conf file (the main apache config file). 10 | # If `vhostsToConvert` is not specified you can use this property to find vhosts by parsing the main apache file 11 | httpdSrc: 12 | # Array of paths to vhosts files and/or vhost folders containing vhost files you wish to convert to cloud service configurations. 13 | vhostsToConvert: 14 | # Array of mapped objects that replace existing variables with new variables. 15 | # The original variable is first and the variable to replace is second. 16 | variablesToReplace: 17 | # This can be a file that you want to append to every vhost file in case you need logic added to all configurations. 18 | # This is useful to replace logic that was once stored in your main apache config file. 19 | appendToVhosts: 20 | # Array of paths to existing dispatcher configuration root folders to scan for the included files. 21 | # These paths help to map includes in the configurations to their current location in the provided folder structure. 22 | # In case the files are distributed across all the folders use command `for i in $(find `pwd` -type d); do echo "- \"$i/\""; done` for unix based system 23 | # and `dir /s /b /o:n /ad` for windows to generate folder/sub-folder and paste the output here. 24 | pathToPrepend: 25 | # Only port 80 is supported in AEM as a Cloud Service - if you were using a non standard port here and need it mapped 26 | # in AEM, provide it here - all other vhosts with non default ports will be removed. 27 | portsToMap: 28 | # Add information about Adobe Managed Services dispatcher configuration here 29 | ams: 30 | # Path to dispatcher configuration folder 31 | # (expected immediate subfolders - subfolders start with conf, conf.d, conf.dispatcher.d and conf.modules.d) 32 | cfg: 33 | -------------------------------------------------------------------------------- /packages/repository-modernizer/resources/analyse/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 4.0.0 19 | 20 | 21 | 22 | 23 | 24 | ${groupId} 25 | ${rootArtifactId} 26 | ${rootVersion} 27 | ../pom.xml 28 | 29 | 30 | 31 | 32 | 33 | ${artifactId}.analyse 34 | ${appTitle} - Project Analyser 35 | Project analysis for ${appTitle} 36 | aem-analyse 37 | 38 | 39 | 40 | 41 | com.adobe.aem 42 | aemanalyser-maven-plugin 43 | true 44 | 45 | 46 | 47 | 48 | 49 | 50 | ${groupId} 51 | ${artifactId}.all 52 | ${version} 53 | zip 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /packages/repository-modernizer/resources/ui.apps.structure/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | 7 | 8 | 9 | ${groupId} 10 | ${rootArtifactId} 11 | ${rootVersion} 12 | ${relativePath} 13 | 14 | 15 | 16 | 17 | 18 | ${artifactId}.ui.apps.structure 19 | ${version} 20 | content-package 21 | ${appTitle} - Repository Structure Package 22 | 23 | Empty package that defines the structure of the Adobe Experience Manager repository the Code packages in this project deploy into. 24 | Any roots in the Code packages of this project should have their parent enumerated in the Filters list below. 25 | 26 | 27 | 28 | 29 | 30 | org.apache.jackrabbit 31 | filevault-package-maven-plugin 32 | true 33 | 34 | 35 | none 36 | 37 | true 38 | 39 | 40 | 41 | 42 | 43 | com.day.jcr.vault 44 | content-package-maven-plugin 45 | true 46 | 47 | true 48 | true 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /packages/repository-modernizer/resources/ui.config/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | 7 | 8 | 9 | ${groupId} 10 | ${rootArtifactId} 11 | ${rootVersion} 12 | ../pom.xml 13 | 14 | 15 | 16 | 17 | 18 | ${artifactId}.ui.config 19 | content-package 20 | ${version} 21 | ${appTitle} - UI config 22 | UI config package for ${appTitle} 23 | 24 | 25 | 26 | 27 | 28 | src/content/jcr_root 29 | 30 | 31 | 32 | org.apache.jackrabbit 33 | filevault-package-maven-plugin 34 | true 35 | 36 | ${groupId} 37 | ${artifactId}.ui.config 38 | application 39 | false 40 | merge 41 | 42 | none 43 | 44 | 45 | 46 | 47 | com.day.jcr.vault 48 | content-package-maven-plugin 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /packages/repository-modernizer/junit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /packages/repository-modernizer/executors/repository-modernizer.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under 8 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | OF ANY KIND, either express or implied. See the License for the specific language 10 | governing permissions and limitations under the License. 11 | */ 12 | 13 | const RepositoryModernizer = require(".."); 14 | const { 15 | logger, 16 | constants, 17 | util, 18 | } = require("@adobe/aem-cs-source-migration-commons"); 19 | const fs = require("fs"); 20 | const yaml = require("js-yaml"); 21 | 22 | // if `target` folder already exists, delete it 23 | if (fs.existsSync(constants.TARGET_FOLDER)) { 24 | logger.info("Deleting existing ./target folder."); 25 | console.log("Deleting existing ./target folder."); 26 | util.deleteFolderRecursive(constants.TARGET_FOLDER); 27 | logger.info("./target deleted successfully"); 28 | console.log("./target deleted successfully"); 29 | } 30 | fs.mkdirSync(constants.TARGET_FOLDER); 31 | const yamlFile = fs.readFileSync(process.cwd() + "/config.yaml", "utf8"); 32 | let config = yaml.safeLoad(yamlFile); 33 | executeRepoModernizer(config); 34 | /** 35 | * 36 | * @param object config yaml object containing info of project to be restructured 37 | * 38 | * Main script to be executed to re-structure Project 39 | */ 40 | async function executeRepoModernizer(config) { 41 | console.log("Restructuring..."); 42 | try { 43 | if ( 44 | await RepositoryModernizer.checkConfig(config.repositoryModernizer) 45 | ) { 46 | await RepositoryModernizer.performModernization( 47 | config.repositoryModernizer, 48 | ".." 49 | ); 50 | logger.info("Restructuring Completed!"); 51 | console.log("Restructuring Completed!"); 52 | console.log( 53 | `Please check ${constants.TARGET_PROJECT_SRC_FOLDER} folder for transformed configuration files.` 54 | ); 55 | console.log( 56 | `Please check ${constants.TARGET_PROJECT_FOLDER} for summary report.` 57 | ); 58 | console.log(`Please check ${constants.LOG_FILE} for logs.`); 59 | } else { 60 | console.log( 61 | `Missing configuration! Please check ${constants.LOG_FILE} for more information.` 62 | ); 63 | } 64 | } catch (error) { 65 | logger.error(error); 66 | console.log(error); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /packages/dispatcher-converter/test/FolderOperationsTest.js: -------------------------------------------------------------------------------- 1 | const assert = require("chai").assert; 2 | let folderOperations = require("../src/util/FolderOperations"); 3 | const { ConversionStep } = require("@adobe/aem-cs-source-migration-commons"); 4 | const fs = require("fs"); 5 | 6 | const testFolder = "testFolder"; 7 | const renamedFolder = "renamedFolder"; 8 | 9 | describe("FolderOperations", () => { 10 | beforeEach(() => { 11 | if (!fs.existsSync(testFolder)) { 12 | fs.mkdirSync(testFolder); 13 | } 14 | }); 15 | 16 | afterEach(function () { 17 | if (fs.existsSync(testFolder)) { 18 | fs.rmdirSync(testFolder); 19 | } 20 | if (fs.existsSync(renamedFolder)) { 21 | fs.rmdirSync(renamedFolder); 22 | } 23 | }); 24 | 25 | it("should delete folder", () => { 26 | if (fs.existsSync(testFolder)) { 27 | let folderOperation = new folderOperations(); 28 | try { 29 | folderOperation.deleteFolder(testFolder, new ConversionStep()); 30 | assert.equal(fs.existsSync(testFolder), false); 31 | } catch (err) { 32 | if (err) { 33 | assert.fail("Folder not deleted " + err); 34 | } 35 | } 36 | } else if (!fs.existsSync(testFolder)) { 37 | assert.equal(fs.existsSync(testFolder), false); 38 | } 39 | }); 40 | 41 | it("should not delete folder if does not exist", () => { 42 | let folderName = "dummyFolder"; 43 | let folderOperation = new folderOperations(); 44 | 45 | folderOperation.deleteFolder(folderName, new ConversionStep()); 46 | assert.equal(fs.existsSync(testFolder), true); 47 | }); 48 | 49 | it("should rename folder", () => { 50 | if (fs.existsSync(testFolder)) { 51 | let folderOperation = new folderOperations(); 52 | try { 53 | folderOperation.renameFolder( 54 | testFolder, 55 | renamedFolder, 56 | new ConversionStep() 57 | ); 58 | assert.equal(fs.existsSync(renamedFolder), true); 59 | } catch (err) { 60 | assert.fail("Folder not renamed " + err); 61 | } 62 | } else if (!fs.existsSync(testFolder)) { 63 | assert.fail(fs.existsSync(testFolder), false); 64 | } 65 | }); 66 | 67 | it("should not rename folder if does not exist", () => { 68 | let folderName = "dummyFolder"; 69 | let folderOperation = new folderOperations(); 70 | 71 | folderOperation.renameFolder( 72 | folderName, 73 | renamedFolder, 74 | new ConversionStep() 75 | ); 76 | assert.equal(fs.existsSync(testFolder), true); 77 | }); 78 | }); 79 | -------------------------------------------------------------------------------- /packages/commons/src/conversion_report/conversion_step.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under 8 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | OF ANY KIND, either express or implied. See the License for the specific language 10 | governing permissions and limitations under the License. 11 | */ 12 | 13 | class ConversionStep { 14 | /* 15 | * ConversionStep describes a single step (or rule) that has been performed with the objective of source migration. 16 | * Each step (or rule) can have multiple ConversionOperation performed as part of it. 17 | */ 18 | 19 | /** 20 | * 21 | * @param {String} rule The rule that is being followed while executing the particular ConversionStep. 22 | * @param {String} description The details of the rule that is being followed for ConversionStep. 23 | * 24 | */ 25 | constructor(rule = "", description = "") { 26 | this.rule = rule; 27 | this.description = description; 28 | this.operations_performed = []; 29 | } 30 | 31 | /** 32 | * 33 | * @param {ConversionOperation} 34 | * @private 35 | * 36 | * Add an operation that was performed while executing the ConversionStep 37 | */ 38 | addOperation(operation) { 39 | this.operations_performed.push(operation); 40 | } 41 | 42 | /** 43 | * 44 | * @returns {String} 45 | * @private 46 | * 47 | * Get the rule that is being followed while executing the particular ConversionStep. 48 | */ 49 | getRule() { 50 | return this.rule; 51 | } 52 | 53 | /** 54 | * 55 | * @returns {String} 56 | * @private 57 | * 58 | * Get the details of the rule that is being followed while executing the particular ConversionStep. 59 | */ 60 | getDescription() { 61 | return this.description; 62 | } 63 | 64 | /** 65 | * 66 | * @returns {[List[ConversionOperation]]} 67 | * @private 68 | * 69 | * Get the list of operations performed while executing the particular ConversionStep 70 | */ 71 | getOperations() { 72 | return this.operations_performed; 73 | } 74 | 75 | /** 76 | * 77 | * @returns {boolean} 78 | * @private 79 | * 80 | * Find whether any operation has been performed while executing the particular ConversionStep 81 | * 82 | * Return: 83 | * boolean: `true` if at least one operation has been performed, else `false` 84 | */ 85 | isPerformed() { 86 | return this.operations_performed.length > 0; 87 | } 88 | } 89 | 90 | module.exports = ConversionStep; 91 | -------------------------------------------------------------------------------- /packages/commons/src/conversion_report/templates/dispatcher-converter-report.md: -------------------------------------------------------------------------------- 1 | # AEM as a Cloud Service - Dispatcher Conversion Report 2 | This report contains the changes that have been made to your dispatcher configurations by the converter. After reviewing these changes, you should simply run the dispatcher validator on the new configurations, with the `dispatcher` subcommand: `validator dispatcher .` to check the state. For any error, see the [Troubleshooting](./TroubleShooting.md) section of the 3 | validator tool documentation. 4 | #### Test your configuration with a local deployment (requires Docker installation) 5 | 6 | Using the script `docker_run.sh` in the Dispatcher SDK, you can test that 7 | your configuration does not contain any other error that would only show up in 8 | deployment: 9 | 10 | ##### Step 1: Generate deployment information with the validator 11 | 12 | ``` 13 | validator full -d out . 14 | ``` 15 | This validates the full configuration and generates deployment information in `out` 16 | 17 | ##### Step 2: Start the dispatcher in a docker image with that deployment information 18 | 19 | With your AEM publish server running on your macOS computer, listening on port 4503, 20 | you can run start the dispatcher in front of that server as follows: 21 | ``` 22 | $ docker_run.sh out docker.for.mac.localhost:4503 8080 23 | ``` 24 | This will start the container and expose Apache on local port 8080. 25 | 26 | If the validator no longer reports any issue and the docker container starts up without 27 | any failures or warnings, you're ready to move your configuration to a `dispatcher/src` 28 | subdirectory of your git repository. 29 | 30 | 31 | ## Dispatcher Configuration changes 32 | 33 | The structure of the project's dispatcher configurations folder should be as shown bellow : 34 | ```./ 35 | ├── conf.d 36 | │ ├── available_vhosts 37 | │ │ └── default.vhost 38 | │ ├── dispatcher_vhost.conf 39 | │ ├── enabled_vhosts 40 | │ │ ├── README 41 | │ │ └── default.vhost -> ../available_vhosts/default.vhost 42 | │ └── rewrites 43 | │ │ ├── default_rewrite.rules 44 | │ │ └── rewrite.rules 45 | │ └── variables 46 | | ├── custom.vars 47 | │ └── global.vars 48 | └── conf.dispatcher.d 49 | ├── available_farms 50 | │ └── default.farm 51 | ├── cache 52 | │ ├── default_invalidate.any 53 | │ ├── default_rules.any 54 | │ └── rules.any 55 | ├── clientheaders 56 | │ ├── clientheaders.any 57 | │ └── default_clientheaders.any 58 | ├── dispatcher.any 59 | ├── enabled_farms 60 | │ ├── README 61 | │ └── default.farm -> ../available_farms/default.farm 62 | ├── filters 63 | │ ├── default_filters.any 64 | │ └── filters.any 65 | ├── renders 66 | │ └── default_renders.any 67 | └── virtualhosts 68 | ├── default_virtualhosts.any 69 | └── virtualhosts.any 70 | ``` 71 | 72 | For conversion of the provided configurations to Dispatcher configuration for AEM as a Cloud Service, we have made the following changes to the dispatcher configuration: 73 | -------------------------------------------------------------------------------- /packages/commons/README.md: -------------------------------------------------------------------------------- 1 | 12 | 13 | [![Version](https://img.shields.io/npm/v/@adobe/aem-cs-source-migration-commons.svg)](https://npmjs.org/package/@adobe/aem-cs-source-migration-commons) 14 | [![Downloads/week](https://img.shields.io/npm/dw/@adobe/aem-cs-source-migration-commons.svg)](https://npmjs.org/package/@adobe/aem-cs-source-migration-commons) 15 | 16 | # @adobe/aem-cs-source-migration-commons 17 | 18 | `aem-cs-source-migration-commons` library provides common functionalities and helper utilities used 19 | by AEM as a Cloud Service Code Refactoring Tools (packages). 20 | 21 | 22 | # Introduction 23 | 24 | While the Code Refactoring tools (modules) are created for different purposes, they each end up 25 | defining a set of utility methods and functionalities that are similar. 26 | To avoid duplicate code or functionalities, common utilities are extracted out into its own module, 27 | which can then be included by the tools and used. 28 | 29 | This project offers a set of functionalities that can be shared among different code refactoring tool modules: 30 | 31 | * Logging Functionality 32 | * Summary Report Generation Functionality 33 | * Common Utility Methods and Constants 34 | 35 | # Usage 36 | 37 | ## Installing the Utilities 38 | 39 | This project uses [node](http://nodejs.org) and [npm](https://npmjs.com). Check your system if you 40 | already have these utilities installed. 41 | 42 | It can be installed like any other `Node.js` module. 43 | 44 | ```shell script 45 | $ npm install @adobe/aem-cs-source-migration-commons 46 | ``` 47 | 48 | ## Adding the Module Requirement 49 | 50 | Follow the steps below to add the module to your `Node.js` project: 51 | 52 | 1. [Install](#install) the module in your project. 53 | 1. Add the `require` function in the module in the javascript file where it will be consumed: 54 | 55 | ```javascript 56 | const Commons = require('@adobe/aem-cs-source-migration-commons'); 57 | ``` 58 | or by destructuring assignment syntax (as per requirement) 59 | 60 | ```javascript 61 | const { 62 | logger, 63 | constants, 64 | util, 65 | ConversionStep, 66 | ConversionOperation, 67 | SummaryReportWriter} = require('@adobe/aem-cs-source-migration-commons'); 68 | ``` 69 | 70 | # Contributing 71 | 72 | Contributions are welcomed! Refer to [Contributing Guide](../../CONTRIBUTING.md) for more information. 73 | 74 | # Licensing 75 | 76 | This project is licensed under the Apache V2 License. Refer to [LICENSE](../../LICENSE) for more information. 77 | -------------------------------------------------------------------------------- /packages/dispatcher-converter/executors/singleFileMain.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under 8 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | OF ANY KIND, either express or implied. See the License for the specific language 10 | governing permissions and limitations under the License. 11 | */ 12 | 13 | const { SingleFilesConverter } = require("../index"); 14 | const { 15 | logger, 16 | constants, 17 | util, 18 | } = require("@adobe/aem-cs-source-migration-commons"); 19 | const utilConstants = require("../src/util/constants"); 20 | const fs = require("fs"); 21 | const yaml = require("js-yaml"); 22 | const path = require("path"); 23 | 24 | const yamlFile = fs.readFileSync( 25 | path.join(process.cwd(), "config.yaml"), 26 | "utf8" 27 | ); 28 | let config = yaml.safeLoad(yamlFile); 29 | 30 | // if `target` folder already exists, delete it 31 | if (fs.existsSync(constants.TARGET_FOLDER)) { 32 | util.deleteFolderRecursive(constants.TARGET_FOLDER); 33 | logger.info("./target is removed successfully"); 34 | } 35 | 36 | // Copy files to target folder 37 | try { 38 | util.copyFolderSync( 39 | config.dispatcherConverter.sdkSrc, 40 | constants.TARGET_DISPATCHER_SRC_FOLDER 41 | ); 42 | // creates marker file if not already present as part of dispatcher sdk 43 | // marker file is used to validate the dispatcher configurations with latest checks 44 | util.ensureFileExistsSync( 45 | utilConstants.USE_SOURCES_DIRECTLY, 46 | path.join(constants.TARGET_DISPATCHER_SRC_FOLDER, utilConstants.OPT_IN) 47 | ); 48 | logger.info("Files successfully copied to target folder"); 49 | } catch (err) { 50 | logger.error( 51 | "Error copying " + 52 | config.dispatcherConverter.onPremise.sdkSrc + 53 | " to " + 54 | constants.TARGET_DISPATCHER_SRC_FOLDER + 55 | " with error " + 56 | err 57 | ); 58 | } 59 | 60 | //instantiate and run the converter 61 | let aemDispatcherConfigConverter = new SingleFilesConverter( 62 | config.dispatcherConverter 63 | ); 64 | 65 | if (aemDispatcherConfigConverter.checkConfig(config.dispatcherConverter)) { 66 | aemDispatcherConfigConverter.transform(); 67 | 68 | // log some final details 69 | console.log("\nTransformation Complete!\n"); 70 | console.log( 71 | `Please check ${constants.TARGET_DISPATCHER_SRC_FOLDER} folder for transformed configuration files.` 72 | ); 73 | console.log( 74 | `Please check ${constants.TARGET_DISPATCHER_FOLDER} for summary report.` 75 | ); 76 | console.log(`Please check ${constants.LOG_FILE} for logs.`); 77 | } else { 78 | console.log( 79 | `Missing configuration! Please check ${constants.LOG_FILE} for more information.` 80 | ); 81 | } 82 | -------------------------------------------------------------------------------- /packages/commons/src/conversion_report/templates/index-converter-report.md: -------------------------------------------------------------------------------- 1 | # AEM as a Cloud Service - Index Converter Report 2 | This report contains the changes that have been made to Custom Oak Index Definitions and Ensure Indexes while doing migration into AEM as a Cloud Service compatible Oak Index Definitions by the tool. 3 | 4 | ## Ensure Definitions 5 | 6 | Refer to [Ensure Oak Index](https://adobe-consulting-services.github.io/acs-aem-commons/features/ensure-oak-index/index.html) to learn how to define and create Oak Definitions. These were created (in place of actual Oak index definitions) so that they do not wipe out the actual index data when updating the node, necessitating a reindex. 7 | 8 | AEM as a Cloud Service has no support for Ensure Definitions, and hence they need to be converted to Oak Index Definitions (then further migrated into AEM as a Cloud Service compatible Custom Oak Index Definitions) as per below guidelines: 9 | 10 | * If property ignore is set to true, ignore/skip the Ensure Definition 11 | * Update the `jcr:primaryType` to `oak:QueryIndexDefinition` 12 | * Remove any properties that are to be ignored as mentioned in OSGi configurations 13 | * Remove subtree `/facets/jcr:content` from Ensure Definition 14 | 15 | Custom Oak Index Definitions are categorized as: 16 | 17 | * **Custom OOTB (Product) Oak Index Definitions**: Modification into existing OOTB Oak Index Definitions 18 | -* **Newly created Oak Index Definitions** 19 | 20 | ## Operations For Custom OOTB (Product) Oak Index Definition 21 | 22 | * This tool will parse the Custom OOTB (Product) Oak Index Definition and fetch the associated OOTB Index Definition. 23 | * It will compare the Custom OOTB Oak Index Definition to the associated OOTB Index Definition and retrieve the difference between Custom OOTB Index Definition. and associated OOTB Index Definition. That difference or delta is basically customization done by the user in OOTB Oak Index Definition. 24 | * It will validate the retrieved customization as per AEM as Cloud Service compatible OAK Index Definitions guidelines. 25 | * It will merge validated customization of Custom OOTB Oak Index Definition to corresponding OAK Index Definition present on AEM as a Cloud Service. 26 | 27 | ## Naming Conventions for Custom OOTB (Product) Oak Index Definition 28 | 29 | ```"Name of the corresponding OAK Index Definition on AEM as a Cloud Service"-"latest version of this index on AEM as a Cloud Service "-"custom"-1``` 30 | 31 | eg. damAssetLucene-6-custom-1 32 | 33 | ## Operations For Newly created Custom Oak Index Definition 34 | 35 | * It will parse and validate the Custom Oak Index Definition as per AEM as Cloud Service compatible OAK Index Definitions guidelines. 36 | * It will rename the Custom Oak Index Definition. 37 | 38 | ## Naming Conventions for Newly created Custom Oak Index Definition : 39 | 40 | ```"Name of the Custom Oak Index Definition"-"custom"-1``` 41 | 42 | for example, testindex-custom-1 43 | 44 | This tool will update the filter path in filter.xml as well based on the new name of Custom OAK Index Definitions. 45 | 46 | for example, from ``` to ``` 47 | -------------------------------------------------------------------------------- /packages/dispatcher-converter/executors/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under 8 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | OF ANY KIND, either express or implied. See the License for the specific language 10 | governing permissions and limitations under the License. 11 | */ 12 | 13 | const { AEMDispatcherConfigConverter } = require("../index"); 14 | const { 15 | logger, 16 | constants, 17 | util, 18 | } = require("@adobe/aem-cs-source-migration-commons"); 19 | const fs = require("fs"); 20 | const path = require("path"); 21 | const yaml = require("js-yaml"); 22 | const utilConstants = require("../src/util/constants"); 23 | const yamlFile = fs.readFileSync( 24 | path.join(process.cwd(), "config.yaml"), 25 | "utf8" 26 | ); 27 | let config = yaml.safeLoad(yamlFile); 28 | 29 | // if `target` folder already exists, delete it 30 | if (fs.existsSync(constants.TARGET_FOLDER)) { 31 | util.deleteFolderRecursive(constants.TARGET_FOLDER); 32 | logger.info("./target is removed successfully"); 33 | } 34 | 35 | // Copy files to target folder 36 | try { 37 | util.copyFolderSync( 38 | config.dispatcherConverter.ams.cfg, 39 | constants.TARGET_DISPATCHER_SRC_FOLDER, 40 | ["enabled_farms", "enabled_vhosts"] 41 | ); 42 | // ensures marker file is created if not present as part of dispatcher sdk 43 | // marker file is used to validate the dispatcher configurations with latest checks 44 | util.ensureFileExistsSync( 45 | utilConstants.USE_SOURCES_DIRECTLY, 46 | path.join(constants.TARGET_DISPATCHER_SRC_FOLDER, utilConstants.OPT_IN) 47 | ); 48 | logger.info("Files successfully copied to target folder"); 49 | } catch (err) { 50 | logger.error( 51 | "Error copying " + 52 | config.dispatcherConverter.ams.cfg + 53 | " to " + 54 | constants.TARGET_DISPATCHER_SRC_FOLDER + 55 | " with error " + 56 | err 57 | ); 58 | } 59 | //instantiate and run the converter 60 | let aemDispatcherConfigConverter = new AEMDispatcherConfigConverter( 61 | config.dispatcherConverter, 62 | constants.TARGET_DISPATCHER_SRC_FOLDER 63 | ); 64 | if (aemDispatcherConfigConverter.checkConfig(config.dispatcherConverter)) { 65 | aemDispatcherConfigConverter.transform(); 66 | 67 | // log some final details 68 | console.log("\nTransformation Complete!\n"); 69 | console.log( 70 | `Please check ${constants.TARGET_DISPATCHER_SRC_FOLDER} folder for transformed configuration files.` 71 | ); 72 | console.log( 73 | `Please check ${constants.TARGET_DISPATCHER_FOLDER} for summary report.` 74 | ); 75 | console.log(`Please check ${constants.LOG_FILE} for logs.`); 76 | } else { 77 | console.log( 78 | `Missing configuration! Please check ${constants.LOG_FILE} for more information.` 79 | ); 80 | } 81 | -------------------------------------------------------------------------------- /packages/index-converter/src/util/constants.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | Unless required by applicable law or agreed to in writing, software distributed under 7 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 8 | OF ANY KIND, either express or implied. See the License for the specific language 9 | governing permissions and limitations under the License. 10 | */ 11 | 12 | module.exports = { 13 | INDEX_RULE: "indexRules", 14 | 15 | JCR_PRIMARY_TYPE: "jcr:primaryType", 16 | 17 | XMLNS_OAK: "xmlns:oak", 18 | 19 | TARGET_FOLDER: "./target", 20 | 21 | UTF_8: "utf8", 22 | 23 | NT_BASE: "nt:base", 24 | 25 | OUTPUT_FILE_NAME: ".content.xml", 26 | 27 | XML_HEADER: '', 28 | 29 | LINE_SEPARATOR: "\n", 30 | 31 | INCLUDED_PATH: "includedPaths", 32 | 33 | QUERY_PATHS: "queryPaths", 34 | 35 | COMPAT_VERSION: "compatVersion", 36 | 37 | TAGS: "tags", 38 | 39 | FILTER_XML_NAME: "filter.xml", 40 | 41 | TYPE_OAK_QUERY_INDEX_DEFINITION: "oak:QueryIndexDefinition", 42 | 43 | TYPE_OAK_UNSTRUCTURED: "oak:Unstructured", 44 | 45 | ENSURE_DEFINITIONS_FOLDER: "convertedEnsureDefinitions", 46 | 47 | ENSURE_OAK_INDEX_CONFIG_FILE: 48 | "com.adobe.acs.commons.oak.impl.EnsureOakIndex*.xml", 49 | 50 | ENSURE_OAK_INDEX_MANAGER_CONFIG_FILE: 51 | "com.adobe.acs.commons.oak.impl.EnsureOakIndexManagerImpl.xml", 52 | 53 | ENSURE_DEFINITIONS_PATH: "ensure-definitions.path", 54 | 55 | ENSURE_DEFINITION_PROPERTIES_IGNORE: "properties.ignore", 56 | 57 | JCR_PROPERTY_IGNORE: "ignore", 58 | 59 | JCR_VALUE_TRUE: "{Boolean}true", 60 | 61 | NODE_FACETS: "facets", 62 | 63 | NODE_JCR_CONTENT: "jcr:content", 64 | 65 | XML_EXTENSION: ".*.xml", 66 | 67 | INPUT_CONTENT_XML: ".content.xml", 68 | 69 | JCR_ROOT: "jcr:root", 70 | 71 | XML_HEADER_PROPERTIES: [ 72 | "xmlns:oak", 73 | "xmlns:slingevent", 74 | "xmlns:sling", 75 | "xmlns:cm", 76 | "xmlns:granite", 77 | "xmlns:social", 78 | "xmlns:dam", 79 | "xmlns:cq", 80 | "xmlns:jcr", 81 | "xmlns:mix", 82 | "xmlns:nt", 83 | "xmlns:rep", 84 | "jcr:mixinTypes", 85 | ], 86 | 87 | FILTER_FOOTER_TAG: "", 88 | 89 | INDEX_CONVERTER_REPORT: "index-converter-report.md", 90 | 91 | CLOUD_SERVICE_INDEX_FILE_NAME: ".content_Cloud_Services.xml", 92 | 93 | INDEX_CUSTOM_SUFFIX: "-custom-1", 94 | 95 | JSON_ATTRIBUTES_KEY: "_attributes", 96 | 97 | JSON_DECLARATION_KEY: "_declaration", 98 | 99 | INDEX_ANALYZERS: "analyzers", 100 | 101 | TIKA_REQUIRED_INDEXES: ["lucene", "graphqlConfig", "damAssetLucene"], 102 | 103 | TIKA: "tika", 104 | 105 | CONFIX_XML_NAME: "config.xml", 106 | 107 | RESOURCES_FOLDER: "resources", 108 | }; 109 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Adobe Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at Grp-opensourceoffice@adobe.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ 75 | -------------------------------------------------------------------------------- /packages/repository-modernizer/resources/ui.content/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | 7 | 8 | 9 | ${groupId} 10 | ${rootArtifactId} 11 | ${rootVersion} 12 | ${relativePath} 13 | 14 | 15 | 16 | 17 | 18 | ${artifactId}.ui.content 19 | content-package 20 | ${version} 21 | ${appTitle} - UI content 22 | UI content package for ${appTitle} 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | org.apache.jackrabbit 34 | filevault-package-maven-plugin 35 | true 36 | 37 | ${groupId} 38 | ${artifactId}.ui.content 39 | content 40 | merge 41 | 42 | none 43 | 44 | 45 | 46 | 47 | 48 | 49 | com.day.jcr.vault 50 | content-package-maven-plugin 51 | true 52 | 53 | true 54 | true 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /packages/repository-modernizer/test/multiProjectConfig.yaml: -------------------------------------------------------------------------------- 1 | # groupId to be used for newly created packages 2 | groupId: test.aem 3 | # information about parent pom 4 | parentPom: 5 | # absolute path to the parent pom file 6 | path: /test/resources/pom.xml 7 | # the artifactId to be set for the parent pom 8 | artifactId: test-aem-parent 9 | # the application title to be set for the parent pom 10 | appTitle: test-AEM Parent 11 | # version to be to be set for the parent pom 12 | version: 1.0.0-SNAPSHOT 13 | # information required for all package 14 | all: 15 | # prefix that is to be used to set the artifactId for all package 16 | artifactId: test-aem 17 | # application title 18 | appTitle: Test-AEM Code Repository 19 | # version to be set for all pom 20 | version: 1.0.0-SNAPSHOT 21 | # information about projects 22 | projects: 23 | - # absolute path to the project folder 24 | projectPath: /test/resources 25 | # relative path(s) (w.r.t. the project folder) to the existing content package(s) that needs to be restructured 26 | # (expects one or more relative paths to be provided in array format) 27 | existingContentPackageFolder: 28 | - /empty_content 29 | # relative path (w.r.t. the existing content package folder) to the filter.xml file 30 | # (If not specified, default path `/src/main/content/META-INF/vault/filter.xml` will be used.) 31 | relativePathToExistingFilterXml: /src/main/content/META-INF/vault/filter.xml 32 | # relative path (w.r.t. the existing content package folder) to the jcr_root directory 33 | # (If not specified, default path `/src/main/content/jcr_root` will be used) 34 | relativePathToExistingJcrRoot: /jcr_root 35 | # prefix that is to be used to set the artifactId for newly created ui.apps and ui.content packages 36 | artifactId: test-content-aem-one 37 | # application title 38 | appTitle: test-content-one 39 | # project specific version to be used for content packages 40 | version: 2.0.0-SNAPSHOT 41 | # application ID (will be used for config and package folder names) 42 | appId: test-one 43 | # Array of relative path(s) (w.r.t. the project folder) to the existing code bundles (will be embedded in the all package). 44 | coreBundles: 45 | - /core 46 | - # absolute path to the project folder 47 | projectPath: /test/resources 48 | # relative path(s) (w.r.t. the project folder) to the existing content package(s) that needs to be restructured 49 | # (expects one or more relative paths to be provided in array format) 50 | existingContentPackageFolder: 51 | - /empty_content 52 | # relative path (w.r.t. the existing content package folder) to the filter.xml file 53 | # (If not specified, default path `/src/main/content/META-INF/vault/filter.xml` will be used.) 54 | relativePathToExistingFilterXml: /src/main/content/META-INF/vault/filter.xml 55 | # relative path (w.r.t. the existing content package folder) to the jcr_root directory 56 | # (If not specified, default path `/src/main/content/jcr_root` will be used) 57 | relativePathToExistingJcrRoot: /jcr_root 58 | # prefix that is to be used to set the artifactId for newly created ui.apps and ui.content packages 59 | artifactId: test-content-aem-two 60 | # application title 61 | appTitle: test-content-two 62 | # project specific version to be used for content packages 63 | version: 2.0.0-SNAPSHOT 64 | # application ID (will be used for config and package folder names) 65 | appId: test-two 66 | # Array of relative path(s) (w.r.t. the project folder) to the existing code bundles (will be embedded in the all package). 67 | coreBundles: 68 | - /core 69 | -------------------------------------------------------------------------------- /packages/repository-modernizer/test/projectWithSubProjectConfig.yaml: -------------------------------------------------------------------------------- 1 | # groupId to be used for newly created packages 2 | groupId: test.aem 3 | # information about parent pom 4 | parentPom: 5 | # absolute path to the parent pom file 6 | path: /test/resources/pom.xml 7 | # the artifactId to be set for the parent pom 8 | artifactId: test-aem-parent 9 | # the application title to be set for the parent pom 10 | appTitle: test-AEM Parent 11 | # version to be to be set for the parent pom 12 | version: 1.0.0-SNAPSHOT 13 | # information required for all package 14 | all: 15 | # prefix that is to be used to set the artifactId for all package 16 | artifactId: test-aem 17 | # application title 18 | appTitle: Test-AEM Code Repository 19 | # version to be set for all pom 20 | version: 1.0.0-SNAPSHOT 21 | # information about projects 22 | projects: 23 | - # absolute path to the project folder 24 | projectPath: /test/resources 25 | # relative path(s) (w.r.t. the project folder) to the existing content package(s) that needs to be restructured 26 | # (expects one or more relative paths to be provided in array format) 27 | existingContentPackageFolder: 28 | - /empty_content 29 | # relative path (w.r.t. the existing content package folder) to the filter.xml file 30 | # (If not specified, default path `/src/main/content/META-INF/vault/filter.xml` will be used.) 31 | relativePathToExistingFilterXml: /src/main/content/META-INF/vault/filter.xml 32 | # relative path (w.r.t. the existing content package folder) to the jcr_root directory 33 | # (If not specified, default path `/src/main/content/jcr_root` will be used) 34 | relativePathToExistingJcrRoot: /jcr_root 35 | # prefix that is to be used to set the artifactId for newly created ui.apps and ui.content packages 36 | artifactId: test-content-aem 37 | # application title 38 | appTitle: test-content 39 | # project specific version to be used for content packages 40 | version: 2.0.0-SNAPSHOT 41 | # application ID (will be used for config and package folder names) 42 | appId: test 43 | # Array of relative path(s) (w.r.t. the project folder) to the existing code bundles (will be embedded in the all package). 44 | coreBundles: 45 | - /core 46 | subProjects: 47 | - # absolute path to the project folder 48 | projectPath: /test/resources/sub-project 49 | # relative path(s) (w.r.t. the project folder) to the existing content package(s) that needs to be restructured 50 | # (expects one or more relative paths to be provided in array format) 51 | existingContentPackageFolder: 52 | - /empty_content 53 | # relative path (w.r.t. the existing content package folder) to the filter.xml file 54 | # (If not specified, default path `/src/main/content/META-INF/vault/filter.xml` will be used.) 55 | relativePathToExistingFilterXml: /src/main/content/META-INF/vault/filter.xml 56 | # relative path (w.r.t. the existing content package folder) to the jcr_root directory 57 | # (If not specified, default path `/src/main/content/jcr_root` will be used) 58 | relativePathToExistingJcrRoot: /jcr_root 59 | # prefix that is to be used to set the artifactId for newly created ui.apps and ui.content packages 60 | artifactId: test-content-sub-project 61 | # application title 62 | appTitle: test-content-sub-project 63 | # project specific version to be used for content packages 64 | version: 2.0.0-SNAPSHOT 65 | # application ID (will be used for config and package folder names) 66 | appId: test-sub-project 67 | # Array of relative path(s) (w.r.t. the project folder) to the existing code bundles (will be embedded in the all package). 68 | coreBundles: 69 | - /core 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /packages/dispatcher-converter/src/util/FolderOperations.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under 8 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | OF ANY KIND, either express or implied. See the License for the specific language 10 | governing permissions and limitations under the License. 11 | */ 12 | 13 | const { 14 | logger, 15 | constants: commons_constants, 16 | ConversionOperation, 17 | util, 18 | } = require("@adobe/aem-cs-source-migration-commons"); 19 | const path = require("path"); 20 | const fs = require("fs"); 21 | 22 | class FolderOperationsUtility { 23 | constructor() {} 24 | 25 | // A utility class that provides various static methods pertaining for manipulation of dispatcher files 26 | /** 27 | * 28 | * @param dirPath The directory to be deleted 29 | * @param conversionStep The conversion step to which the performed actions are to be added. 30 | * @returns {boolean} 31 | * 32 | * Delete specified folder. 33 | */ 34 | deleteFolder(dirPath, conversionStep) { 35 | // if is directory 36 | if (fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory()) { 37 | try { 38 | util.deleteFolderRecursive(dirPath); 39 | conversionStep.addOperation( 40 | new ConversionOperation( 41 | commons_constants.ACTION_DELETED, 42 | dirPath, 43 | "Deleted folder " + dirPath 44 | ) 45 | ); 46 | logger.info( 47 | "FolderOperationsUtility: Deleted folder " + dirPath 48 | ); 49 | } catch (err) { 50 | logger.error( 51 | "FolderOperationsUtility: error while deleting file, " + 52 | err.filename + 53 | "-" + 54 | err.stderr 55 | ); 56 | } 57 | return true; 58 | } 59 | } 60 | 61 | /** 62 | * 63 | * @param src_path The directory to be renamed 64 | * @param dest_path The directory where file is to be renamed 65 | * @param conversionStep The conversion step to which the performed actions are to be added. 66 | * @returns {boolean} 67 | * 68 | * Rename specified folder. 69 | */ 70 | renameFolder(src_path, dest_path, conversionStep) { 71 | // if path exists 72 | if (fs.existsSync(src_path) && fs.lstatSync(src_path).isDirectory()) { 73 | try { 74 | fs.renameSync(src_path, dest_path); 75 | conversionStep.addOperation( 76 | new ConversionOperation( 77 | commons_constants.ACTION_RENAMED, 78 | path.dirname(src_path), 79 | "Renamed folder " + 80 | path.basename(src_path) + 81 | " to " + 82 | path.basename(dest_path) 83 | ) 84 | ); 85 | logger.info( 86 | "FolderOperationsUtility: Renamed folder " + 87 | src_path + 88 | "to" + 89 | dest_path 90 | ); 91 | } catch (err) { 92 | logger.error( 93 | "FolderOperationsUtility: " + 94 | err.filename + 95 | "-" + 96 | err.stderr 97 | ); 98 | } 99 | return true; 100 | } 101 | } 102 | } 103 | 104 | module.exports = FolderOperationsUtility; 105 | -------------------------------------------------------------------------------- /packages/repository-modernizer/test/resources/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 4.0.0 7 | 8 | 9 | 10 | 11 | 12 | com.ni.apps.aem 13 | ni-parent 14 | 2 15 | 16 | 17 | com.ni.apps.aem 18 | content-parent 19 | 3.4-SNAPSHOT 20 | pom 21 | 22 | AEM Repository for the Content Team - Reactor Project 23 | Maven Multimodule project for building the Content Team tenant. 24 | 25 | 26 | scm:git:https://ni@dev.azure.com/ni/IT/_git/content-aem 27 | scm:git:https://ni@dev.azure.com/ni/IT/_git/content-aem 28 | https://dev.azure.com/ni/IT/_git/content-aem 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | com.apps.aem 38 | test.apps 39 | 1.3-SNAPSHOT 40 | 41 | 42 | com.apps.aem 43 | test.core 44 | 1.0.1 45 | 46 | 47 | com.adobe.aem 48 | uber-jar 49 | 1.0.1 50 | 51 | 52 | com.adobe.aem 53 | aem.test.core 54 | 1.0.1 55 | 56 | 57 | 58 | 59 | 60 | 61 | src/main/filters/testfilter.properties 62 | 63 | 64 | 65 | io.github.zlika 66 | reproducible-build-maven-plugin 67 | 0.11 68 | 69 | 70 | 71 | strip-jar 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | org.codehaus.mojo 81 | jaxws-maven-plugin 82 | 2.5 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | with-content 91 | 92 | true 93 | 94 | 95 | content 96 | 97 | 98 | 99 | with-tests 100 | 101 | false 102 | 103 | 104 | content 105 | integration-tests 106 | 107 | 108 | 109 | it-only 110 | 111 | true 112 | 113 | 114 | 115 | 116 | helpers-bundle 117 | widgets-bundle 118 | workflows-bundle 119 | components-bundle 120 | commerce-bundle 121 | workflow 122 | vcm-migration-bundle 123 | sub-project 124 | 125 | 126 | 127 | website 128 | file:///tmp/fake.com/ 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /packages/repository-modernizer/test/resources/sub-project/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 4.0.0 7 | 8 | 9 | 10 | 11 | 12 | com.ni.apps.aem 13 | content-parent 14 | 3.4-SNAPSHOT 15 | 16 | 17 | com.ni.apps.aem 18 | sub-project-content-parent 19 | 3.4-SNAPSHOT 20 | pom 21 | 22 | AEM Repository for the Content Team - Reactor Project 23 | Maven Multimodule project for building the Content Team tenant. 24 | 25 | 26 | scm:git:https://ni@dev.azure.com/ni/IT/_git/content-aem 27 | scm:git:https://ni@dev.azure.com/ni/IT/_git/content-aem 28 | https://dev.azure.com/ni/IT/_git/content-aem 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | com.apps.aem 38 | test.apps 39 | 1.3-SNAPSHOT 40 | 41 | 42 | com.apps.aem 43 | test.core 44 | 1.0.1 45 | 46 | 47 | com.adobe.aem 48 | uber-jar 49 | 1.0.1 50 | 51 | 52 | com.adobe.aem 53 | aem.test.core 54 | 1.0.1 55 | 56 | 57 | 58 | 59 | 60 | 61 | src/main/filters/testfilter.properties 62 | 63 | 64 | 65 | io.github.zlika 66 | reproducible-build-maven-plugin 67 | 0.11 68 | 69 | 70 | 71 | strip-jar 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | org.codehaus.mojo 81 | jaxws-maven-plugin 82 | 2.5 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | with-content 91 | 92 | true 93 | 94 | 95 | content 96 | 97 | 98 | 99 | with-tests 100 | 101 | false 102 | 103 | 104 | content 105 | integration-tests 106 | 107 | 108 | 109 | it-only 110 | 111 | true 112 | 113 | 114 | 115 | 116 | helpers-bundle 117 | widgets-bundle 118 | workflows-bundle 119 | components-bundle 120 | commerce-bundle 121 | workflow 122 | vcm-migration-bundle 123 | 124 | 125 | 126 | website 127 | file:///tmp/fake.com/ 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /packages/index-converter/test/ensure-definition-converter-test.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | Unless required by applicable law or agreed to in writing, software distributed under 7 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 8 | OF ANY KIND, either express or implied. See the License for the specific language 9 | governing permissions and limitations under the License. 10 | */ 11 | const assert = require("chai").assert; 12 | const constants = require("../src/util/constants.js"); 13 | const ensureDefinitionConverter = require("../src/ensure-definition-converter.js"); 14 | const commons = require("@adobe/aem-cs-source-migration-commons"); 15 | const fs = require("fs"); 16 | const path = require("path"); 17 | 18 | const testEnsureDefinitionFolder = "test/resources/ensureDefinitions"; 19 | const testEnsureDefinitionOakIndexFolder = path.join( 20 | testEnsureDefinitionFolder, 21 | "oak-index" 22 | ); 23 | 24 | describe("ensure-definition-converter-util", function () { 25 | describe("Convert Ensure Definitions", function () { 26 | it("should convert to Oak Index Definitions", function () { 27 | let config = { 28 | ensureIndexDefinitionContentPackageJcrRootPath: 29 | testEnsureDefinitionFolder, 30 | ensureIndexDefinitionConfigPackageJcrRootPath: 31 | testEnsureDefinitionFolder, 32 | }; 33 | assert.isTrue( 34 | ensureDefinitionConverter.performConversion(config, []) 35 | ); 36 | assert.isTrue( 37 | fs.existsSync( 38 | path.join( 39 | commons.constants.TARGET_INDEX_FOLDER, 40 | constants.ENSURE_DEFINITIONS_FOLDER 41 | ) 42 | ) 43 | ); 44 | assert.isFalse( 45 | fs.existsSync( 46 | path.join( 47 | commons.constants.TARGET_INDEX_FOLDER, 48 | constants.ENSURE_DEFINITIONS_FOLDER, 49 | "damAssetLucene", 50 | ".content.xml" 51 | ) 52 | ) 53 | ); 54 | assert.isTrue( 55 | fs.existsSync( 56 | path.join( 57 | commons.constants.TARGET_INDEX_FOLDER, 58 | constants.ENSURE_DEFINITIONS_FOLDER, 59 | "custLucene", 60 | ".content.xml" 61 | ) 62 | ) 63 | ); 64 | // clean up 65 | commons.util.deleteFolderRecursive( 66 | path.join( 67 | commons.constants.TARGET_INDEX_FOLDER, 68 | constants.ENSURE_DEFINITIONS_FOLDER 69 | ) 70 | ); 71 | }); 72 | }); 73 | 74 | describe("No Ensure Definitions", function () { 75 | it("should skip conversion to Oak Index Definitions", function () { 76 | let config = { 77 | aemVersion: 64, 78 | }; 79 | assert.isFalse( 80 | ensureDefinitionConverter.performConversion(config, []) 81 | ); 82 | assert.isFalse( 83 | fs.existsSync( 84 | path.join( 85 | commons.constants.TARGET_INDEX_FOLDER, 86 | constants.ENSURE_DEFINITIONS_FOLDER 87 | ) 88 | ) 89 | ); 90 | }); 91 | }); 92 | 93 | describe("Wrong Ensure Definitions path in config", function () { 94 | it("should skip conversion to Oak Index Definitions", function () { 95 | let config = { 96 | ensureIndexDefinitionContentPackageJcrRootPath: 97 | testEnsureDefinitionFolder, 98 | ensureIndexDefinitionConfigPackageJcrRootPath: 99 | testEnsureDefinitionOakIndexFolder, 100 | }; 101 | assert.isFalse( 102 | ensureDefinitionConverter.performConversion(config, []) 103 | ); 104 | assert.isFalse( 105 | fs.existsSync( 106 | path.join( 107 | commons.constants.TARGET_INDEX_FOLDER, 108 | constants.ENSURE_DEFINITIONS_FOLDER 109 | ) 110 | ) 111 | ); 112 | }); 113 | }); 114 | }); 115 | -------------------------------------------------------------------------------- /packages/index-converter/test/map-processing-util-test.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | Unless required by applicable law or agreed to in writing, software distributed under 7 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 8 | OF ANY KIND, either express or implied. See the License for the specific language 9 | governing permissions and limitations under the License. 10 | */ 11 | const assert = require("chai").assert; 12 | const mapUtil = require("../src/util/map-processing-util.js"); 13 | const xmlUtil = require("../src/util/xml-processing-util.js"); 14 | const path = require("path"); 15 | const constants = require("../src/util/constants.js"); 16 | 17 | describe("Map-Processing-Util", function () { 18 | describe("Construct Map from Json Object", function () { 19 | it("should construct a map from json object", function () { 20 | let baseLineXMLPath = path.join("./resources/.content_65.xml"); 21 | let baseLineJsonObject = 22 | xmlUtil.buildJsonObjectFromXML(baseLineXMLPath); 23 | let baseLineMap = new Map(); 24 | mapUtil.buildMapFromJsonObject( 25 | baseLineJsonObject[constants.JCR_ROOT], 26 | baseLineMap 27 | ); 28 | try { 29 | assert.isTrue( 30 | baseLineMap.get("socialLucene") == "social:asiResource", 31 | "Map returned successfully" 32 | ); 33 | } catch (e) { 34 | assert.fail("Not able to return Map"); 35 | } 36 | }); 37 | }); 38 | 39 | describe("Build Custom Index Array and Custom OOTB Index Map ", function () { 40 | it("should construct Custom index Array and Custom OOTB Index Map", function () { 41 | try { 42 | let baseLineXMLPath = path.join("./resources/.content_65.xml"); 43 | let customIndexXMLPath = path.join( 44 | "./test/resources/inputCustom1.xml" 45 | ); 46 | let baseLineJsonObject = 47 | xmlUtil.buildJsonObjectFromXML(baseLineXMLPath); 48 | let allCustomIndexJsonObject = 49 | xmlUtil.buildJsonObjectFromXML(customIndexXMLPath); 50 | let allCustomIndexMap = new Map(); 51 | mapUtil.buildMapFromJsonObject( 52 | allCustomIndexJsonObject[constants.JCR_ROOT], 53 | allCustomIndexMap 54 | ); 55 | let baseLineMap = new Map(); 56 | mapUtil.buildMapFromJsonObject( 57 | baseLineJsonObject[constants.JCR_ROOT], 58 | baseLineMap 59 | ); 60 | let customOOTBIndexMap = new Map(); 61 | let customIndex = []; 62 | mapUtil.buildCustomIndexMap( 63 | allCustomIndexMap, 64 | baseLineMap, 65 | customOOTBIndexMap, 66 | customIndex 67 | ); 68 | assert.isTrue( 69 | customOOTBIndexMap.keys().next().value == "damAssetLucene", 70 | "Custom OOTB Index key is fetched successfully" 71 | ); 72 | assert.isTrue( 73 | customOOTBIndexMap.values().next().value == 74 | "damAssetLucene", 75 | "Custom OOTB Index Value is fetched successfully" 76 | ); 77 | assert.isTrue( 78 | customIndex[0] == "test-lead-form", 79 | "Custom Index Value is fetched successfully" 80 | ); 81 | } catch (e) { 82 | console.log(e); 83 | assert.fail("Not able to return Map", e); 84 | } 85 | }); 86 | }); 87 | 88 | describe("Build on prem to Cloud service instance index relationship map", function () { 89 | it("should construct onPremToCloud map", function () { 90 | try { 91 | let baseLineMap = new Map(); 92 | baseLineMap.set("a", "1,2"); 93 | baseLineMap.set("b", "3,4"); 94 | 95 | let cloudServiceIndexMap = new Map(); 96 | cloudServiceIndexMap.set("a1", "1,2"); 97 | cloudServiceIndexMap.set("d1", "3,2"); 98 | 99 | let onPremToCloudMap = new Map(); 100 | mapUtil.buildRelationshipMapOnPremToCloud( 101 | baseLineMap, 102 | cloudServiceIndexMap, 103 | onPremToCloudMap 104 | ); 105 | 106 | assert.isTrue( 107 | onPremToCloudMap.values().next().value == "a1", 108 | "Index name on cloud is fetched successfully" 109 | ); 110 | assert.isTrue( 111 | onPremToCloudMap.keys().next().value == "a", 112 | "Index name on prem is fetched successfully" 113 | ); 114 | } catch (e) { 115 | assert.fail("Not able to return Map"); 116 | } 117 | }); 118 | }); 119 | }); 120 | -------------------------------------------------------------------------------- /packages/index-converter/src/util/map-processing-util.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | Unless required by applicable law or agreed to in writing, software distributed under 7 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 8 | OF ANY KIND, either express or implied. See the License for the specific language 9 | governing permissions and limitations under the License. 10 | */ 11 | 12 | const constants = require("./constants"); 13 | 14 | module.exports = { 15 | /** 16 | * 17 | * @param jsonObject json object of content xml. 18 | * @param map {Key : name of the index, Value: node under indexRules Node}. 19 | * 20 | * Build @param map from @param jsonObject. 21 | * 22 | */ 23 | buildMapFromJsonObject: (jsonObject, map) => { 24 | buildMapFromJsonObject(jsonObject, map, null); 25 | }, 26 | /** 27 | * 28 | * @param allCustomIndexMap map built based on customer Oak index content.xml {Key : name of the index, Value: node names under indexRules Node}. 29 | * @param baseLineMap map built based on base aem version content.xml {Key : name of the index, Value: node under indexRules Node}. 30 | * @param customOOTBIndexMap map of Custom Product indexes {Key : name of the index in custom oak index xml , Value: name of corresponding product index in baseline xml}. 31 | * @param customIndexes array of those indexes which are newly created by customer 32 | * 33 | * Build @param customOOTBIndexMap @param customIndexes from @param allCustomIndexMap and @param baseLineMap. 34 | * 35 | */ 36 | 37 | buildCustomIndexMap: ( 38 | allCustomIndexMap, 39 | baseLineMap, 40 | customOOTBIndexMap, 41 | customIndexes 42 | ) => { 43 | let relatedKey = null; 44 | for (let [key, val] of allCustomIndexMap) { 45 | relatedKey = null; 46 | relatedKey = getKeyByValue(baseLineMap, val); 47 | if (relatedKey != null) { 48 | if (!val.includes(constants.NT_BASE)) { 49 | customOOTBIndexMap.set(key, relatedKey); 50 | } 51 | } else { 52 | customIndexes.push(key); 53 | } 54 | } 55 | }, 56 | /** 57 | * 58 | * @param baseLineMap map built based on base aem version content.xml {Key : name of the index, Value: node names under indexRules Node}. 59 | * @param indexOnCloudServicesMap map of Product indexes present in cloud service aem instance {Key : name of the index, Value: node names under indexRules Node}. 60 | * @param onPremToCloudMap map to be populated {Key: name of index in baseline,Value: name of index in cloud service aem content.xml } 61 | * 62 | * Populate @param onPremToCloudMap based on @param baseLineMap and @param indexOnCloudServicesMap. 63 | * 64 | */ 65 | buildRelationshipMapOnPremToCloud: ( 66 | baseLineMap, 67 | indexOnCloudServicesMap, 68 | onPremToCloudMap 69 | ) => { 70 | let baseLineMapKeys = baseLineMap.keys(); 71 | 72 | for (const baseLineKey of baseLineMapKeys) { 73 | let correspondingKey = checkSimilarKeyInOtherMap( 74 | baseLineKey, 75 | indexOnCloudServicesMap 76 | ); 77 | if (correspondingKey != null) { 78 | onPremToCloudMap.set(baseLineKey, correspondingKey); 79 | } 80 | } 81 | }, 82 | }; 83 | 84 | function getKeyByValue(indexMap, value) { 85 | let ans = null; 86 | for (let [key, val] of indexMap) { 87 | if (value.toString() == val.toString()) { 88 | ans = key; 89 | } 90 | } 91 | return ans; 92 | } 93 | /** 94 | * 95 | * @param jsonObject index json object. 96 | * @param map map {Key : name of the index, Value: node names under indexRules Node}. 97 | * 98 | * Populate @param map based on @param jsonObject. 99 | * 100 | */ 101 | function buildMapFromJsonObject(jsonObject, map, indexName) { 102 | for (const [key, value] of Object.entries(jsonObject)) { 103 | if (key == constants.INDEX_RULE) { 104 | for (let k in value) { 105 | if (k != constants.JCR_PRIMARY_TYPE) { 106 | if (indexName != null && map.has(indexName)) { 107 | map[indexName] = map[indexName] || []; 108 | map[indexName].push(k); 109 | map.set(indexName, map[indexName]); 110 | } else { 111 | map.set(indexName, k); 112 | } 113 | } 114 | } 115 | } else if (typeof value === "object" && value !== null) { 116 | for (let k in value) { 117 | if (k == constants.INDEX_RULE || k == constants.XMLNS_OAK) { 118 | indexName = key; 119 | buildMapFromJsonObject(value, map, indexName); 120 | } 121 | } 122 | } 123 | } 124 | } 125 | 126 | function checkSimilarKeyInOtherMap(baseLineKey, indexOnCloudServicesMap) { 127 | let indexOnCloudServicesMapKeys = indexOnCloudServicesMap.keys(); 128 | for (const key of indexOnCloudServicesMapKeys) { 129 | if (key.includes(baseLineKey)) { 130 | indexOnCloudServicesMap.delete(key); 131 | return key; 132 | } 133 | } 134 | return null; 135 | } 136 | -------------------------------------------------------------------------------- /packages/index-converter/test/index-converter-util-test.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | Unless required by applicable law or agreed to in writing, software distributed under 7 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 8 | OF ANY KIND, either express or implied. See the License for the specific language 9 | governing permissions and limitations under the License. 10 | */ 11 | const _ = require("lodash"); 12 | const assert = require("chai").assert; 13 | const indexUtil = require("../src/util/index-converter-util.js"); 14 | const xmlUtil = require("../src/util/xml-processing-util.js"); 15 | const { 16 | util: commons_util, 17 | constants: common_constants, 18 | } = require("@adobe/aem-cs-source-migration-commons"); 19 | const fs = require("fs"); 20 | const path = require("path"); 21 | const constants = require("../src/util/constants"); 22 | 23 | describe("index-converter-util", function () { 24 | describe("Test migration Of Custom OOTB Indexes", function () { 25 | it("should construct finalJsonObject", function () { 26 | let finalJsonObject = {}; 27 | let baseLineXMLPath = path.join("test/resources/.content_65.xml"); 28 | let customIndexXMLPath = path.join( 29 | "test/resources/inputCustom1.xml" 30 | ); 31 | let indexOnCloudXMLPath = path.join( 32 | "test/resources/.content_Cloud_Services.xml" 33 | ); 34 | let baseLineJsonObject = 35 | xmlUtil.buildJsonObjectFromXML(baseLineXMLPath); 36 | let allCustomIndexJsonObject = 37 | xmlUtil.buildJsonObjectFromXML(customIndexXMLPath); 38 | let indexOnCloudJsonObject = 39 | xmlUtil.buildJsonObjectFromXML(indexOnCloudXMLPath); 40 | let customOOTBIndexMap = new Map(); 41 | customOOTBIndexMap.set("damAssetLucene", "damAssetLucene"); 42 | let onPremToCloudMap = new Map(); 43 | onPremToCloudMap.set("damAssetLucene", "damAssetLucene-6"); 44 | let transformationMap = new Map(); 45 | 46 | indexUtil.migrationOfCustomOOTBIndex( 47 | finalJsonObject, 48 | customOOTBIndexMap, 49 | baseLineJsonObject, 50 | allCustomIndexJsonObject, 51 | indexOnCloudJsonObject, 52 | onPremToCloudMap, 53 | transformationMap 54 | ); 55 | 56 | let migratedTikaConfigs = indexUtil.migrateTikaConfig( 57 | transformationMap, 58 | path.join("", constants.RESOURCES_FOLDER) 59 | ); 60 | assert.isTrue(migratedTikaConfigs.length == 1); 61 | commons_util.deleteFolderRecursive( 62 | common_constants.TARGET_INDEX_FOLDER 63 | ); 64 | 65 | let actualJson = JSON.stringify(finalJsonObject); 66 | let expectedFilePath = path.join( 67 | "test/resources/expectedCustomOOTB.json" 68 | ); 69 | fs.readFile(expectedFilePath, "utf8", (err, data) => { 70 | try { 71 | if (err) { 72 | throw err; 73 | } 74 | assert.isTrue( 75 | _.isEqual(data.trim(), actualJson.trim()), 76 | "JSON Object constructed successfully and both are equal" 77 | ); 78 | } catch (e) { 79 | assert.fail( 80 | "Not able to create Json Object or actual json object does not match to expected json object" 81 | ); 82 | } 83 | }); 84 | }); 85 | }); 86 | 87 | describe("Test migration Of Custom Indexes", function () { 88 | it("should construct finalJsonObject", function () { 89 | let finalJsonObject = {}; 90 | let customIndexXMLPath = path.join( 91 | "test/resources/inputCustom1.xml" 92 | ); 93 | let allCustomIndexJsonObject = 94 | xmlUtil.buildJsonObjectFromXML(customIndexXMLPath); 95 | let customIndex = ["test-lead-form"]; 96 | let transformationMap = new Map(); 97 | 98 | indexUtil.migrationOfCustomIndex( 99 | finalJsonObject, 100 | customIndex, 101 | allCustomIndexJsonObject, 102 | transformationMap 103 | ); 104 | 105 | let actualJson = JSON.stringify(finalJsonObject); 106 | let expectedFilePath = path.join( 107 | "test/resources/expectedCustomIndex.json" 108 | ); 109 | fs.readFile(expectedFilePath, "utf8", (err, data) => { 110 | try { 111 | if (err) { 112 | throw err; 113 | } 114 | assert.isTrue( 115 | _.isEqual(data.trim(), actualJson.trim()), 116 | "JSON Object constructed successfully and both are equal" 117 | ); 118 | } catch (e) { 119 | assert.fail( 120 | "Not able to create Json Object or actual json object does not match to expected json object", 121 | e 122 | ); 123 | } 124 | }); 125 | }); 126 | }); 127 | }); 128 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 12 | 13 | [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) 14 | [![Codecov Coverage](https://img.shields.io/codecov/c/github/adobe/aem-cloud-service-source-migration/master.svg?style=flat-square)](https://codecov.io/gh/adobe/aem-cloud-service-source-migration/) 15 | 16 | # aem-cloud-service-source-migration 17 | 18 | This monorepo contains the code refactoring tools that help customers to migrate to AEM as a 19 | Cloud Service. 20 | 21 | # Available Tools 22 | - [Dispatcher Converter](./packages/dispatcher-converter) - configuring existing on-premise or 23 | Adobe Managed Services (AMS) dispatcher configurations to AEM as a Cloud Service compatible 24 | dispatcher configuration. 25 | - [Repository Modernizer](./packages/repository-modernizer) - restructure existing projects 26 | into AEM as a Cloud Service compatible packages. 27 | - [Index Converter](./packages/index-converter) - migrate existing Custom Oak Index Defintions 28 | into AEM as a Cloud Service compatible Custom Oak Index Defintions. 29 | 30 | ## Setup 31 | ``` 32 | npm install yarn lerna -g 33 | yarn install 34 | ``` 35 | 36 | ## Test 37 | ``` 38 | yarn test 39 | ``` 40 | 41 | ## Publishing to npm 42 | This repository has been configured to automatically publish the tool packages to `npm` registry. 43 | Publishing packages involve two components : 44 | #### 1. Changesets 45 | We leverage [changesets](https://github.com/atlassian/changesets) which lets contributors declare 46 | how their changes should be released, automates updating package versions, and changelogs, and 47 | publishing new versions of packages based on the provided information. 48 | A `changeset` is an intent to release a set of packages at particular semver bump types with a 49 | summary of the changes made. 50 | The `@changesets/cli` package allows us to create multiple `changeset` files as we make changes, 51 | then combine any number of `changeset` files into a release. A `changeset` is created using the 52 | `changeset CLI` using the command below : 53 | ``` 54 | yarn changeset 55 | ``` 56 | When run, we get a number of questions about which packages are affected and what semver range 57 | this `changeset` should bump (major, minor, or patch). 58 | ```shell script 59 | maji@MAJI-WX-2 MINGW32 ~/Documents/GitHub/aem-cloud-service-source-migration (master) 60 | $ yarn changeset 61 | yarn run v1.22.4 62 | $ C:\Users\maji\Documents\GitHub\aem-cloud-service-source-migration\node_modules\.bin\changeset 63 | � Which packages would you like to include? · @adobe/aem-cs-source-migration-dispatcher-converter 64 | � Which packages should have a major bump? · No items were selected 65 | � Which packages should have a minor bump? · No items were selected 66 | � The following packages will be patch bumped: 67 | � @adobe/aem-cs-source-migration-dispatcher-converter@1.1.0 68 | � Please enter a summary for this change (this will be in the changelogs). Submit empty line to open external editor 69 | � Summary · Fixing rule file and rewrite path in farm and vhost files 70 | � === Releasing the following packages === 71 | � [Patch] 72 | � @adobe/aem-cs-source-migration-dispatcher-converter 73 | � ╔════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗ 74 | � ║ ========= NOTE ======== ║ 75 | � ║All dependents of these packages that will be incompatible with the new version will be patch bumped when this changeset is applied.║ 76 | � ╚════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝ 77 | � Is this your desired changeset? (Y/n) · true 78 | � Changeset added! - you can now commit it 79 | � 80 | � If you want to modify or expand on the changeset summary, you can find it here 81 | � info C:\Users\maji\Documents\GitHub\aem-cloud-service-source-migration\.changeset\fluffy-turkeys-wink.md 82 | Done in 101.92s. 83 | ``` 84 | This will produce a `changeset` file (./changest/fluffy-turkeys-wink.md) whose content would look something like : 85 | ```markdown 86 | --- 87 | "@adobe/aem-cs-source-migration-dispatcher-converter": patch 88 | --- 89 | Fixing rule file and rewrite path in farm and vhost files 90 | ``` 91 | This `changeset` file will get deleted automatically later (and merged into the CHANGELOG.md) when our 92 | Github Action processes it. Please create a `changeset` for each package that needs to be published. 93 | 94 | #### 2. Github Action 95 | The preconfigured [Github publish action](https://github.com/adobe/aem-cloud-service-source-migration/blob/master/.github/workflows/publish.yml) 96 | will look for the presence of `changeset` files in all commits to `master` branch. If found, it 97 | will automatically create a PR including all of the version bumps and `CHANGELOG.mds` that need 98 | to happen from any given `changeset`. We can then merge that PR after reviewing all the version bumps. 99 | Merging will trigger the automated publish for the mentioned packages to the `npm` registry. 100 | 101 | # Contributing 102 | 103 | Contributions are welcomed! Refer to [Contributing Guide](../../CONTRIBUTING.md) for more information. 104 | 105 | # Licensing 106 | 107 | This project is licensed under the Apache V2 License. Refer to [LICENSE](../../LICENSE) for more information. 108 | 109 | 110 | # Reporting 111 | 112 | Please follow the [Issue template](ISSUE_TEMPLATE.md) to report issues or to request enhancements. 113 | -------------------------------------------------------------------------------- /packages/repository-modernizer/executors/config.yaml: -------------------------------------------------------------------------------- 1 | repositoryModernizer: 2 | # groupId to be used for newly created packages 3 | groupId: 4 | # information about parent pom 5 | parentPom: 6 | # absolute path to the parent pom file 7 | path: 8 | # the artifactId to be set for the parent pom 9 | artifactId: 10 | # the application title to be set for the parent pom 11 | appTitle: 12 | # version to be to be set for the parent pom 13 | version: 14 | # information required for all and analyse packages 15 | all: 16 | # prefix that is to be used to set the artifactId for all and analyse packages 17 | artifactId: 18 | # application title 19 | appTitle: 20 | # version to be set for all pom 21 | version: 22 | # information about projects (expects an array of project information) 23 | # NOTE : For multiple projects create separate copies of the info section for each project 24 | projects: 25 | - # absolute path to the project folder 26 | projectPath: 27 | # Array of relative path(s) (w.r.t. the project folder) to the existing content package(s) that needs to be restructured. 28 | # NOTE : only content packages are expected here, NOT bundle/jar artifacts/sub-projects 29 | existingContentPackageFolder: 30 | - 31 | # relative path (w.r.t. the existing content package folder) to the filter.xml file 32 | # (If not specified, default path `/src/main/content/META-INF/vault/filter.xml` will be used.) 33 | relativePathToExistingFilterXml: 34 | # relative path (w.r.t. the existing content package folder) to the jcr_root directory 35 | # (If not specified, default path `/src/main/content/jcr_root` will be used) 36 | relativePathToExistingJcrRoot: 37 | # prefix that is to be used to set the artifactId for newly created packages 38 | artifactId: 39 | # application title 40 | appTitle: 41 | # application ID (will be used for config and package folder names) 42 | appId: 43 | # project specific version to be used for content packages 44 | version: 45 | # Array of relative path(s) (w.r.t. the project folder) to the existing code bundles (will be embedded in the all package). 46 | coreBundles: 47 | - 48 | # OSGi config folders that need to be renamed. 49 | # The existing/source OSGi config folder PATH (JCR path stating from '/apps') is expected as key 50 | # and the replacement OSGi folder NAME is expected as value. See examples below : 51 | # /apps/my-appId/config.prod : config.publish.prod 52 | # /apps/system/config.author.dev1 : config.author.dev 53 | # /apps/system/config.author.dev2 : config.author.dev 54 | # NOTE : 55 | # 1. All OSGi config folders under the same path and with same replacement name will be MERGED 56 | # (as configured in above example). 57 | # 2. If there exists OSGi config files with the same pid/filename in more than one config folders 58 | # which are to be merged, they will not be overwritten. A warning regrading the same will be 59 | # generated in the summary report and result log file. User would need to manually evaluate 60 | # which config to persist 61 | osgiFoldersToRename: 62 | subProjects: 63 | - # absolute path to the project folder 64 | projectPath: 65 | # Array of relative path(s) (w.r.t. the project folder) to the existing content package(s) that needs to be restructured. 66 | # NOTE : only content packages are expected here, NOT bundle/jar artifacts/sub-projects 67 | existingContentPackageFolder: 68 | - 69 | # relative path (w.r.t. the existing content package folder) to the filter.xml file 70 | # (If not specified, default path `/src/main/content/META-INF/vault/filter.xml` will be used.) 71 | relativePathToExistingFilterXml: 72 | # relative path (w.r.t. the existing content package folder) to the jcr_root directory 73 | # (If not specified, default path `/src/main/content/jcr_root` will be used) 74 | relativePathToExistingJcrRoot: 75 | # prefix that is to be used to set the artifactId for newly created packages 76 | artifactId: 77 | # application title 78 | appTitle: 79 | # application ID (will be used for config and package folder names) 80 | appId: 81 | # project specific version to be used for content packages 82 | version: 83 | # Array of relative path(s) (w.r.t. the project folder) to the existing code bundles (will be embedded in the all package). 84 | coreBundles: 85 | - 86 | # OSGi config folders that need to be renamed. 87 | # The existing/source OSGi config folder PATH (JCR path stating from '/apps') is expected as key 88 | # and the replacement OSGi folder NAME is expected as value. See examples below : 89 | # /apps/my-appId/config.prod : config.publish.prod 90 | # /apps/system/config.author.dev1 : config.author.dev 91 | # /apps/system/config.author.dev2 : config.author.dev 92 | # NOTE : 93 | # 1. All OSGi config folders under the same path and with same replacement name will be MERGED 94 | # (as configured in above example). 95 | # 2. If there exists OSGi config files with the same pid/filename in more than one config folders 96 | # which are to be merged, they will not be overwritten. A warning regrading the same will be 97 | # generated in the summary report and result log file. User would need to manually evaluate 98 | # which config to persist 99 | osgiFoldersToRename: 100 | -------------------------------------------------------------------------------- /packages/repository-modernizer/resources/ui.apps/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | 7 | 8 | 9 | ${groupId} 10 | ${rootArtifactId} 11 | ${rootVersion} 12 | ${relativePath} 13 | 14 | 15 | 16 | 17 | 18 | ${artifactId}.ui.apps 19 | content-package 20 | ${version} 21 | ${appTitle} - UI apps 22 | UI apps package for ${appTitle} 23 | 24 | 25 | 26 | 27 | 28 | src/main/content/jcr_root 29 | 30 | 31 | 32 | 33 | 34 | org.apache.jackrabbit 35 | filevault-package-maven-plugin 36 | true 37 | 38 | ${groupId} 39 | ${artifactId}.ui.apps 40 | application 41 | merge 42 | 43 | none 44 | 45 | 46 | 47 | ${groupId} 48 | ${artifactId}.ui.apps.structure 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | com.day.jcr.vault 59 | content-package-maven-plugin 60 | true 61 | 62 | true 63 | true 64 | 65 | 66 | 67 | 68 | org.apache.sling 69 | htl-maven-plugin 70 | 71 | 72 | validate-htl-scripts 73 | 74 | validate 75 | 76 | generate-sources 77 | 78 | true 79 | org.apache.sling.scripting.sightly 80 | 81 | cssClassName 82 | decoration 83 | decorationTagName 84 | wcmmode 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | ${groupId} 99 | ${artifactId}.ui.apps.structure 100 | ${version} 101 | zip 102 | 103 | 104 | 105 | org.apache.sling 106 | org.apache.sling.scripting.sightly.compiler 107 | 1.2.4-1.4.0 108 | provided 109 | 110 | 111 | org.apache.sling 112 | org.apache.sling.scripting.sightly.runtime 113 | 1.2.0-1.4.0 114 | provided 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /packages/dispatcher-converter/src/util/constants.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under 8 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | OF ANY KIND, either express or implied. See the License for the specific language 10 | governing permissions and limitations under the License. 11 | */ 12 | 13 | module.exports = { 14 | DISPATCHER_CONVERTER_REPORT: "dispatcher-converter-report.md", 15 | 16 | TARGET_DISPATCHER_SRC_FOLDER: "./target/dispatcher/src", 17 | 18 | TARGET_SINGLE_DISPATCHER: "./target/disatpcher-single.any", 19 | 20 | CLOSE_CURLY_BRACE: "}", 21 | 22 | CONF: "conf", 23 | 24 | CONF_DISPATCHER_D: "conf.dispatcher.d", 25 | 26 | CONF_D: "conf.d", 27 | 28 | CONF_MODULES_D: "conf.modules.d", 29 | 30 | VHOST: "vhost", 31 | 32 | ANY: "any", 33 | 34 | FARM: "farm", 35 | 36 | ENABLED_FARMS: "enabled_farms", 37 | 38 | ENABLED_VHOSTS: "enabled_vhosts", 39 | 40 | AVAILABLE_VHOSTS: "available_vhosts", 41 | 42 | AVAILABLE_FARMS: "available_farms", 43 | 44 | COMMENT_ANNOTATION: "#", 45 | 46 | VIRTUAL_HOST_SECTION_START: "", 49 | 50 | VIRTUAL_HOST_SECTION_START_PORT_80: ":80>", 51 | 52 | INCLUDE_SYNTAX_IN_VHOST: "Include", 53 | 54 | INCLUDE_SYNTAX_IN_FARM: "$include", 55 | 56 | RENDERS_SECTION: "/renders", 57 | 58 | VIRTUALHOSTS_SECTION_IN_FARM: "/virtualhosts", 59 | 60 | ALLOWED_CLIENTS_SECTION: "/allowedClients", 61 | 62 | CLIENT_HEADER_SECTION: "/clientheader", 63 | 64 | FILTERS_SECTION: "/filter", 65 | 66 | IF_BLOCK_START: "", 69 | 70 | IFMODULE_END: "", 71 | 72 | BLOCK_START: "block_start", 73 | 74 | BLOCK_END: "block_end", 75 | 76 | REWRITES_MODULE: "", 77 | 78 | RULES_SECTION: "/rules", 79 | 80 | WARNING: "WARNING", 81 | 82 | OPT_IN: "opt-in", 83 | 84 | USE_SOURCES_DIRECTLY: "USE_SOURCES_DIRECTLY", 85 | 86 | DEFAULT_INCLUES: [ 87 | "default_invalidate.any", 88 | "default_filters.any", 89 | "default_renders.any", 90 | ], 91 | 92 | // whitelisted directives (in lower case for ease of comparision; directives can be case-insensitive) 93 | WHITELISTED_DIRECTIVES_LIST: [ 94 | "", 95 | "", 96 | "", 97 | "", 98 | "", 99 | "", 100 | "", 101 | "", 102 | "", 103 | "", 104 | "", 105 | "", 106 | "", 107 | "", 108 | "", 109 | "addcharset", 110 | "addencoding", 111 | "addhandler", 112 | "addoutputfilter", 113 | "addoutputfilterbytype", 114 | "addtype", 115 | "alias", 116 | "allow", 117 | "allowencodedslashes", 118 | "allowmethods", 119 | "allowoverride", 120 | "authbasicprovider", 121 | "authgroupfile", 122 | "authname", 123 | "authtype", 124 | "authuserfile", 125 | "balancergrowth", 126 | "balancerinherit", 127 | "balancermember", 128 | "balancerpersist", 129 | "browsermatch", 130 | "browsermatchnocase", 131 | "define", 132 | "deflatecompressionlevel", 133 | "deflatefilternote", 134 | "deflatememlevel", 135 | "deflatewindowsize", 136 | "deny", 137 | "directoryslash", 138 | "dispatcherdeclineroot", 139 | "dispatchernocanonurl", 140 | "dispatcherpasserror", 141 | "dispatcheruseprocessedurl", 142 | "documentroot", 143 | "errordocument", 144 | "expiresactive", 145 | "expiresbytype", 146 | "expiresdefault", 147 | "fileetag", 148 | "filterchain", 149 | "filterdeclare", 150 | "filterprovider", 151 | "forcetype", 152 | "header", 153 | "include", 154 | "includeoptional", 155 | "keepalive", 156 | "limitrequestfieldsize", 157 | "modmimeusepathinfo", 158 | "noproxy", 159 | "options", 160 | "order", 161 | "passenv", 162 | "proxy100continue", 163 | "proxyaddheaders", 164 | "proxybadheader", 165 | "proxyblock", 166 | "proxydomain", 167 | "proxyerroroverride", 168 | "proxyiobuffersize", 169 | "proxymaxforwards", 170 | "proxypass", 171 | "proxypassinherit", 172 | "proxypassinterpolateenv", 173 | "proxypassmatch", 174 | "proxypassreverse", 175 | "proxypassreversecookiedomain", 176 | "proxypassreversecookiepath", 177 | "proxypreservehost", 178 | "proxyreceivebuffersize", 179 | "proxyremote", 180 | "proxyremotematch", 181 | "proxyrequests", 182 | "proxyset", 183 | "proxysourceaddress", 184 | "proxystatus", 185 | "proxytimeout", 186 | "proxyvia", 187 | "redirect", 188 | "redirectmatch", 189 | "remoteipheader", 190 | "remoteiptrustedproxylist", 191 | "requestheader", 192 | "requestreadtimeout", 193 | "require", 194 | "rewritecond", 195 | "rewriteengine", 196 | "rewritemap", 197 | "rewriteoptions", 198 | "rewriterule", 199 | "satisfy", 200 | "scriptalias", 201 | "secrequestbodyaccess", 202 | "secruleengine", 203 | "serveralias", 204 | "servername", 205 | "serversignature", 206 | "setenvif", 207 | "setenvifexpr", 208 | "setenvifnocase", 209 | "sethandler", 210 | "setoutputfilter", 211 | "sslproxyengine", 212 | "substitute", 213 | "traceenable", 214 | "undefine", 215 | "userdir", 216 | ], 217 | }; 218 | -------------------------------------------------------------------------------- /packages/repository-modernizer/resources/all/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | 7 | 8 | 9 | 10 | ${groupId} 11 | ${rootArtifactId} 12 | ${rootVersion} 13 | ../pom.xml 14 | 15 | 16 | 17 | 18 | 19 | ${artifactId}.all 20 | content-package 21 | ${version} 22 | ${appTitle} - All 23 | All content package for ${appTitle} 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | org.apache.jackrabbit 35 | filevault-package-maven-plugin 36 | true 37 | 38 | ${groupId} 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | com.day.jcr.vault 47 | content-package-maven-plugin 48 | true 49 | 50 | true 51 | true 52 | 53 | 54 | 55 | maven-clean-plugin 56 | 2.4.1 57 | 58 | 59 | auto-clean 60 | initialize 61 | 62 | clean 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | autoInstallSinglePackage 76 | 77 | false 78 | 79 | 80 | 81 | 82 | com.day.jcr.vault 83 | content-package-maven-plugin 84 | 85 | 86 | install-package 87 | 88 | install 89 | 90 | 91 | http://${aem.host}:${aem.port}/crx/packmgr/service.jsp 92 | true 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | autoInstallSinglePackagePublish 102 | 103 | false 104 | 105 | 106 | 107 | 108 | com.day.jcr.vault 109 | content-package-maven-plugin 110 | 111 | 112 | install-package-publish 113 | 114 | install 115 | 116 | 117 | http://${aem.publish.host}:${aem.publish.port}/crx/packmgr/service.jsp 118 | true 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /packages/commons/src/conversion_report/summary_report_writer.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under 8 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | OF ANY KIND, either express or implied. See the License for the specific language 10 | governing permissions and limitations under the License. 11 | */ 12 | 13 | const ConversionStep = require("./conversion_step"); 14 | const ConversionOperation = require("./conversion_operation"); 15 | const DetectionList = require("./detection_list"); 16 | const constants = require("../constants"); 17 | const logger = require("../logger"); 18 | const fsExtra = require("fs-extra"); 19 | const fs = require("fs"); 20 | const path = require("path"); 21 | const LINE_SEP = constants.SUMMARY_REPORT_LINE_SEPARATOR; 22 | 23 | class SummaryReportWriter { 24 | // A utility class that provides functionality for creation of summary report for the migration 25 | 26 | /** 27 | * 28 | * @param {Array[ConversionStep || DetectionList]} summaryReportWriter List of conversion_step or detection_list that are to be added to the summary report 29 | * @param String target The path/location where the summary report need to be created 30 | * @param String report_name The name of the base summary report template file 31 | * @private 32 | * 33 | * Create a summary report which contains the conversion_step followed (and operations performed) or detection_list during the conversion 34 | */ 35 | static writeSummaryReport(summaryReportWriter, target, report_name) { 36 | // create a copy of the summary report template file in the target folder 37 | let file_path = path.join(process.cwd(), target, report_name); 38 | try { 39 | fsExtra.copyFileSync( 40 | path.join(__dirname, constants.TEMPLATE_FOLDER, report_name), 41 | file_path 42 | ); 43 | logger.info( 44 | "Base summary report template " + 45 | report_name + 46 | " copied to " + 47 | target 48 | ); 49 | } catch (err) { 50 | logger.error( 51 | "Error copying " + 52 | report_name + 53 | " to " + 54 | target + 55 | " with error " + 56 | err 57 | ); 58 | } 59 | summaryReportWriter.forEach((step) => { 60 | if (step instanceof ConversionStep) { 61 | // only if some operation is actually performed under the conversion_step 62 | if (step.isPerformed()) { 63 | fs.appendFileSync(file_path, LINE_SEP); 64 | fs.appendFileSync(file_path, `#### ${step.getRule()}`); 65 | fs.appendFileSync(file_path, LINE_SEP); 66 | fs.appendFileSync(file_path, step.getDescription()); 67 | fs.appendFileSync(file_path, LINE_SEP); 68 | SummaryReportWriter.appendTableHeader(file_path); 69 | SummaryReportWriter.appendOperation( 70 | file_path, 71 | step.getOperations() 72 | ); 73 | } 74 | } else if (step instanceof DetectionList) { 75 | if (step.isDetected()) { 76 | // only if some element is actually added under the detection_step 77 | fs.appendFileSync(file_path, LINE_SEP); 78 | fs.appendFileSync(file_path, step.getHeading()); 79 | fs.appendFileSync(file_path, LINE_SEP); 80 | step.getDetectionList().forEach((element) => { 81 | fs.appendFileSync(file_path, "* " + element); 82 | fs.appendFileSync(file_path, LINE_SEP); 83 | }); 84 | } 85 | } else { 86 | fs.appendFileSync(file_path, LINE_SEP); 87 | fs.appendFileSync(file_path, step); 88 | } 89 | }); 90 | logger.info(report_name + " generation complete."); 91 | } 92 | 93 | /** 94 | * Appends header to the table in Summary Report 95 | */ 96 | static appendTableHeader(file_path) { 97 | fs.appendFileSync(file_path, "\r\n"); 98 | fs.appendFileSync(file_path, "| "); 99 | fs.appendFileSync(file_path, "Action Type"); 100 | fs.appendFileSync(file_path, " | "); 101 | fs.appendFileSync(file_path, "Location"); 102 | fs.appendFileSync(file_path, " | "); 103 | fs.appendFileSync(file_path, "Action"); 104 | fs.appendFileSync(file_path, " |"); 105 | fs.appendFileSync(file_path, LINE_SEP); 106 | fs.appendFileSync(file_path, "| ----------- | -------- | ------ |"); 107 | fs.appendFileSync(file_path, LINE_SEP); 108 | } 109 | 110 | /** 111 | * Appends the row entry to the table in Summary Report 112 | * @param conversion_operations 113 | */ 114 | static appendOperation(file_path, conversion_operations) { 115 | conversion_operations.forEach((conversion_operation) => { 116 | if (conversion_operation instanceof ConversionOperation) { 117 | fs.appendFileSync(file_path, "|"); 118 | fs.appendFileSync( 119 | file_path, 120 | " " + conversion_operation.getOperationType() + " " 121 | ); 122 | fs.appendFileSync(file_path, "|"); 123 | fs.appendFileSync( 124 | file_path, 125 | " " + conversion_operation.getOperationLocation() + " " 126 | ); 127 | fs.appendFileSync(file_path, "|"); 128 | fs.appendFileSync( 129 | file_path, 130 | " " + conversion_operation.getOperationAction() + " " 131 | ); 132 | fs.appendFileSync(file_path, "|"); 133 | fs.appendFileSync(file_path, LINE_SEP); 134 | } 135 | }); 136 | } 137 | } 138 | 139 | module.exports = SummaryReportWriter; 140 | -------------------------------------------------------------------------------- /packages/index-converter/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | Unless required by applicable law or agreed to in writing, software distributed under 7 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 8 | OF ANY KIND, either express or implied. See the License for the specific language 9 | governing permissions and limitations under the License. 10 | */ 11 | 12 | const { 13 | constants: common_constants, 14 | SummaryReportWriter, 15 | logger, 16 | } = require("@adobe/aem-cs-source-migration-commons"); 17 | 18 | const indexConverter = require("./src/index-converter.js"); 19 | const ensureDefinitionConverter = require("./src/ensure-definition-converter.js"); 20 | const constants = require("./src/util/constants.js"); 21 | const fs = require("fs"); 22 | const path = require("path"); 23 | 24 | let fileName = path.basename(__filename); 25 | 26 | var IndexConverter = { 27 | /** 28 | * 29 | * @param config yaml object containing info of project to be restructured 30 | * @param basePath root path of project to be restructured 31 | * 32 | * Convert Oak Index Definitions 33 | */ 34 | performIndexConversion: (config, basePath) => { 35 | console.log("Index Conversion Start..."); 36 | logger.info(fileName + ": Index Conversion Start..."); 37 | if (config.aemVersion == null) { 38 | let aemVersionMessage = 39 | "AEM Version is not provided, Please update 'aemVersion' property in yaml file"; 40 | logger.error(fileName + ": " + aemVersionMessage); 41 | console.log(aemVersionMessage); 42 | return; 43 | } 44 | 45 | console.log("Base AEM Version for Reference " + config.aemVersion); 46 | logger.info( 47 | fileName + ": Base AEM Version for Reference " + config.aemVersion 48 | ); 49 | 50 | if ( 51 | config.customOakIndexDirectoryPath == null && 52 | config.ensureIndexDefinitionContentPackageJcrRootPath == null 53 | ) { 54 | let configMessage = 55 | "Both customOakIndexDirectoryPath and ensureIndexDefinitionContentPackageJcrRootPath can not be null. Please provide value for either"; 56 | logger.error(fileName + ": " + configMessage); 57 | console.log(configMessage); 58 | return; 59 | } 60 | 61 | // create a new target index definition folder 62 | fs.mkdirSync(common_constants.TARGET_INDEX_FOLDER, { recursive: true }); 63 | var writer_buffer = []; 64 | writer_buffer.push( 65 | "## AEM as a Cloud Service - Index Conversion Report Update " 66 | ); 67 | logger.info("Index Conversion Report Update "); 68 | writer_buffer.push(constants.LINE_SEPARATOR); 69 | writer_buffer.push( 70 | "Base AEM Version for Reference:\t " + config.aemVersion 71 | ); 72 | writer_buffer.push( 73 | "Custom Oak Index Definition content.xml(s) are placed at below paths :" 74 | ); 75 | writer_buffer.push(config.customOakIndexDirectoryPath); 76 | writer_buffer.push( 77 | config.ensureIndexDefinitionContentPackageJcrRootPath 78 | ); 79 | writer_buffer.push(constants.LINE_SEPARATOR); 80 | 81 | logger.info( 82 | fileName + 83 | ": Custom Oak Index Definition content.xml(s) are placed at '" + 84 | config.customOakIndexDirectoryPath + 85 | "','" + 86 | config.ensureIndexDefinitionContentPackageJcrRootPath + 87 | "'" 88 | ); 89 | // Convert Ensure Definitions 90 | let wasEnsureDefinitionConverted = 91 | ensureDefinitionConverter.performConversion(config, writer_buffer); 92 | if ( 93 | !wasEnsureDefinitionConverted && 94 | config.customOakIndexDirectoryPath == null 95 | ) { 96 | let infoMessage = 97 | "No legit custom indexes are found , can not process further."; 98 | logger.info(fileName + ": " + infoMessage); 99 | console.log(infoMessage); 100 | return; 101 | } 102 | // Convert Index Definitions 103 | let conversionCompleted = indexConverter.performConversion( 104 | config, 105 | basePath, 106 | wasEnsureDefinitionConverted, 107 | writer_buffer 108 | ); 109 | writer_buffer.push( 110 | "Note: For transforming `property` type index into `lucence` type index. Please refer " + 111 | "`http://jackrabbit.apache.org/oak/docs/query/lucene.html`." 112 | ); 113 | let reportMessage = 114 | "Index Converter Report can be found at '" + 115 | path.join( 116 | process.cwd(), 117 | common_constants.TARGET_INDEX_FOLDER, 118 | constants.INDEX_CONVERTER_REPORT 119 | ) + 120 | "'"; 121 | let logFileMessage = 122 | "Index Converter logs can be found at '" + 123 | path.join(process.cwd(), common_constants.LOG_FILE) + 124 | "'"; 125 | let outFilePathMessage = 126 | "Output .content.xml after transformation can be found at '" + 127 | path.join( 128 | process.cwd(), 129 | common_constants.TARGET_INDEX_FOLDER, 130 | constants.OUTPUT_FILE_NAME 131 | ) + 132 | "'"; 133 | let filterXML = 134 | "Updated filter.xml can be found at '" + 135 | path.join( 136 | process.cwd(), 137 | common_constants.TARGET_INDEX_FOLDER, 138 | constants.FILTER_XML_NAME 139 | ) + 140 | "'"; 141 | if (conversionCompleted) { 142 | SummaryReportWriter.writeSummaryReport( 143 | writer_buffer, 144 | common_constants.TARGET_INDEX_FOLDER, 145 | constants.INDEX_CONVERTER_REPORT 146 | ); 147 | 148 | console.log("Index Conversion Completed"); 149 | logger.info(fileName + ": Index Conversion Completed"); 150 | 151 | console.log(reportMessage); 152 | console.log(logFileMessage); 153 | console.log(outFilePathMessage); 154 | 155 | logger.info(fileName + ": " + reportMessage); 156 | logger.info(fileName + ": " + outFilePathMessage); 157 | 158 | if (config.filterXMLPath != null) { 159 | logger.info(fileName + ": " + filterXML); 160 | console.log(filterXML); 161 | } 162 | } 163 | }, 164 | }; 165 | 166 | module.exports = IndexConverter; 167 | -------------------------------------------------------------------------------- /packages/commons/src/util.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under 8 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | OF ANY KIND, either express or implied. See the License for the specific language 10 | governing permissions and limitations under the License. 11 | */ 12 | 13 | const fs = require("fs"); 14 | const fsExtra = require("fs-extra"); 15 | const glob = require("glob"); 16 | const logger = require("./logger"); 17 | const path = require("path"); 18 | 19 | var Util = { 20 | /** 21 | * 22 | * @param String flag command line argument which need to be read 23 | * @return {String} flag value 24 | * 25 | * Grab values from command line input 26 | */ 27 | grab: (flag) => { 28 | let indexAfterFlag = process.argv.indexOf(flag) + 1; 29 | return process.argv[indexAfterFlag]; 30 | }, 31 | 32 | /** 33 | * 34 | * @param String path The path/location where content need to be deleted 35 | * 36 | * Recursively delete a folder and its content 37 | */ 38 | deleteFolderRecursive: (path) => { 39 | if (fs.existsSync(path)) { 40 | fs.readdirSync(path).forEach(function (file) { 41 | var curPath = path + "/" + file; 42 | // if entry is a directory, recursively delete it's content 43 | if (fs.lstatSync(curPath).isDirectory()) { 44 | Util.deleteFolderRecursive(curPath); 45 | } else { 46 | // delete file 47 | fs.unlinkSync(curPath); 48 | } 49 | }); 50 | fs.rmdirSync(path); 51 | } 52 | }, 53 | 54 | /** 55 | * 56 | * @param String filePath path of file whose content need to be read 57 | * @return {Array.} content of an XML file as a array of strings 58 | * 59 | * Async function to get the content of an XML file as a array of strings (lines) 60 | */ 61 | getXMLContent: async (filePath) => { 62 | if (!fs.existsSync(filePath)) { 63 | return []; 64 | } 65 | // read contents of the file and split them by newline 66 | var data = await fs.promises.readFile(filePath, "utf8"); 67 | return data.split(/\r?\n/); 68 | }, 69 | 70 | /** 71 | * 72 | * @param String filePath path of file whose content need to be read 73 | * @return {Array.} content of an XML file as a array of strings 74 | * 75 | * Sync function to get the content of an XML file as a array of strings (lines) 76 | */ 77 | getXMLContentSync: (filePath) => { 78 | if (!fs.existsSync(filePath)) { 79 | return []; 80 | } 81 | // read contents of the file and split them by newline 82 | return fs.readFileSync(filePath, "utf8").split(/\r?\n/); 83 | }, 84 | 85 | /** 86 | * 87 | * @param String filePath path of file where data need to be written 88 | * @param String[] data content to be written of provided file 89 | * 90 | * Async function to write data (a string array) to a file 91 | */ 92 | writeDataToFileAsync: (filePath, data) => { 93 | return new Promise((resolve, reject) => { 94 | const file = fs.createWriteStream(filePath); 95 | data.forEach((line) => { 96 | file.write(line.toString() + "\r\n"); 97 | }); 98 | file.end(); 99 | file.on("finish", () => resolve(true)); 100 | file.on("error", reject); 101 | }); 102 | }, 103 | 104 | /** 105 | * 106 | * @param String filePath path of file where data need to be written 107 | * @param String[] data content to be written of provided file 108 | * @param String errorMsg error msg to log in case of failure/error 109 | * 110 | * Sync function to write data (a string array) to a file 111 | */ 112 | writeDataToFileSync: (filePath, data, errorMsg) => { 113 | var file = fs.createWriteStream(filePath); 114 | file.on("error", function () { 115 | logger.error(errorMsg); 116 | }); 117 | data.forEach((line) => { 118 | file.write(line.toString() + "\r\n"); 119 | }); 120 | file.end(); 121 | }, 122 | 123 | /** 124 | * 125 | * @param String sourcePath path from where file need to be copied 126 | * @param String destinationPath path where file to be copied 127 | * @param String errorMsg error msg to log in case of failure/error 128 | * @param {Array.} ignoreFolders name of folders to ignore 129 | * 130 | * Sync function to write data (a string array) to a file 131 | */ 132 | copyFolderSync: (sourcePath, destinationPath, ignoreFolders = []) => { 133 | // NOTE : In copySync method of fs-extra module, if src is a directory it will copy 134 | // everything inside of this directory, not the entire directory itself!! 135 | // Hence create the required folder structure in the destination 136 | fs.mkdirSync(destinationPath, { recursive: true }); 137 | fsExtra.copySync(sourcePath, destinationPath, { 138 | filter: (folder) => { 139 | return ignoreFolders.indexOf(path.basename(folder)) > -1 140 | ? false 141 | : true; 142 | }, 143 | }); 144 | }, 145 | 146 | /** 147 | * 148 | * @param String fileName name of the file to create if it doesn't exist 149 | * @param String parentPath path where file needs to be created 150 | * Sync function to create a file with empty content 151 | */ 152 | ensureFileExistsSync: (fileName, parentPath) => { 153 | if (!fs.existsSync(path.join(parentPath, fileName))) { 154 | fs.mkdirSync(parentPath, { recursive: true }); 155 | fs.writeFileSync(path.join(parentPath, fileName), ""); 156 | } 157 | }, 158 | 159 | /** 160 | * 161 | * @param String directoryPath path which need to be scanned 162 | * @param String fileExtension file extension which need to be search 163 | * @return {Array.} list of all files 164 | * 165 | * Get all files with given extension under given directory 166 | */ 167 | globGetFilesByExtension(directoryPath, fileExtension) { 168 | let globPattern = path.join(directoryPath + "/**/*" + fileExtension); 169 | return glob.sync(globPattern); 170 | }, 171 | 172 | /** 173 | * 174 | * @param String directoryPath path which need to be scanned 175 | * @param String fileName file name which need to be search 176 | * @return {Array.} list of all files 177 | * 178 | * Get all files with given fileName under given directory 179 | */ 180 | globGetFilesByName(directoryPath, fileName) { 181 | let globPattern = path.join(directoryPath + "/**/" + fileName); 182 | return glob.sync(globPattern); 183 | }, 184 | }; 185 | 186 | module.exports = Util; 187 | --------------------------------------------------------------------------------