├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── OSS_Licenses.md ├── README.md ├── images ├── diff.png ├── screenshot-1.png ├── screenshot-2.png └── visualdiff.png ├── pom.xml ├── src ├── assembly │ └── zip.xml ├── main │ ├── java │ │ └── org │ │ │ └── pentaho │ │ │ ├── di │ │ │ ├── git │ │ │ │ └── spoon │ │ │ │ │ ├── DrawDiffOnJobEntryExtensionPoint.java │ │ │ │ │ ├── DrawDiffOnStepExtensionPoint.java │ │ │ │ │ ├── GitController.java │ │ │ │ │ ├── GitPerspective.java │ │ │ │ │ ├── GitSpoonMenuController.java │ │ │ │ │ ├── GitSpoonPlugin.java │ │ │ │ │ ├── PdiDiff.java │ │ │ │ │ ├── dialog │ │ │ │ │ ├── CloneRepositoryDialog.java │ │ │ │ │ ├── DeleteBranchDialog.java │ │ │ │ │ ├── EditRepositoryDialog.java │ │ │ │ │ ├── MergeBranchDialog.java │ │ │ │ │ └── UsernamePasswordDialog.java │ │ │ │ │ └── model │ │ │ │ │ ├── GitRepository.java │ │ │ │ │ ├── IVCS.java │ │ │ │ │ ├── SVN.java │ │ │ │ │ ├── UIFile.java │ │ │ │ │ ├── UIGit.java │ │ │ │ │ └── VCS.java │ │ │ ├── repository │ │ │ │ └── pur │ │ │ │ │ └── PurObjectRevision.java │ │ │ └── ui │ │ │ │ └── repository │ │ │ │ └── pur │ │ │ │ └── repositoryexplorer │ │ │ │ └── model │ │ │ │ ├── UIRepositoryObjectRevision.java │ │ │ │ └── UIRepositoryObjectRevisions.java │ │ │ └── ui │ │ │ └── xul │ │ │ └── util │ │ │ └── XulDialogLambdaCallback.java │ └── resources │ │ └── org │ │ └── pentaho │ │ └── di │ │ └── git │ │ └── spoon │ │ ├── images │ │ ├── added.png │ │ ├── added.svg │ │ ├── branch.png │ │ ├── branch.svg │ │ ├── changed.png │ │ ├── changed.svg │ │ ├── pull.png │ │ ├── pull.svg │ │ ├── push.png │ │ ├── push.svg │ │ ├── removed.png │ │ ├── removed.svg │ │ ├── repository.png │ │ ├── repository.svg │ │ ├── tag.png │ │ └── tag.svg │ │ ├── messages │ │ ├── messages_en_US.properties │ │ └── messages_ja_JP.properties │ │ └── xul │ │ ├── changed-table.xul │ │ ├── git_perspective.xul │ │ ├── git_revision-table.xul │ │ └── git_spoon_overlays.xul └── test │ ├── java │ └── org │ │ └── pentaho │ │ └── di │ │ └── git │ │ └── spoon │ │ ├── GitControllerTest.java │ │ ├── GitSpoonMenuControllerTest.java │ │ ├── PdiDiffTest.java │ │ └── model │ │ ├── GitRepositoryTest.java │ │ ├── SVNTest.java │ │ └── UIGitTest.java │ └── resources │ ├── r1.kjb │ ├── r1.ktr │ ├── r2.kjb │ └── r2.ktr └── version.xml /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | .classpath 3 | .project 4 | .settings/ 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | branches: 2 | except: 3 | - nightly 4 | language: java 5 | dist: xenial 6 | jdk: openjdk8 7 | cache: 8 | directories: 9 | - "$HOME/.m2" 10 | before_install: 11 | - sudo apt-get install libsvn-java 12 | before_script: 13 | - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/jni 14 | before_deploy: 15 | - git config --local user.name "Hiromu Hota" 16 | - git config --local user.email "hiromu.hota@hal.hitachi.com" 17 | - export TRAVIS_TAG=nightly 18 | - git tag $TRAVIS_TAG --force 19 | - git push -f https://${GITHUB_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git $TRAVIS_TAG 20 | deploy: 21 | provider: releases 22 | api_key: $GITHUB_TOKEN 23 | file_glob: true 24 | file: target/pdi-git-plugin-*-jar-with-dependencies.zip 25 | skip_cleanup: true 26 | on: 27 | branch: master 28 | name: nightly 29 | body: Auto-build of $TRAVIS_BRANCH ($TRAVIS_COMMIT) by Travis CI on $(date +'%F %T %Z'). 30 | prerelease: true 31 | overwrite: true 32 | tag_name: $TRAVIS_TAG 33 | target_commitish: $TRAVIS_COMMIT 34 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## 1.1.1 - 2020-04-06 4 | ### Security 5 | - [Git] Update JGit to 5.1.13 6 | - [Git] Update Apache HTTPClient 7 | 8 | ## 1.1.0 - 2019-11-27 9 | ### Added 10 | - [Common][#26] Allow other plugins to open a repository by name 11 | - [Common][#27] Allow other plugins to get a list of defined git repositories 12 | - [Common][#23] Allow variables in directory (currently system properties only) 13 | 14 | ### Security 15 | - [Git] Update JGit to 4.11.9 16 | - [Git] Update Apache HTTPClient 17 | 18 | ## 1.0.2 - 2018-12-19 19 | ### Changed 20 | - [Git] Allow pull,merge,rollback even when untracked files exist but no uncommited change 21 | 22 | ### Fixed 23 | - [Git][#20] Use DiffFormatter, which does not detect renames. 24 | - [Common] Rephrase "Dirty working-tree" message and internationalized it 25 | - [Common][#24] Make the repository settings dialog resizable and remember the last position/size (thanks @mattcasters) 26 | 27 | ## 1.0.1 - 2018-04-04 28 | ### Fixed 29 | - [Git] Prevent from making a commit with no files 30 | - [SVN] Fix null pointer exception when invalid SVN repository selected 31 | - [Common][#18] Abort commit when empty commit message 32 | 33 | ## 1.0.0 - 2017-11-11 34 | ### Added 35 | - [SVN] Subversion support 36 | - [Common] "Rollback to here" command to a context menu that rollbacks the working tree (copy) to a previous commit (revision), but does not make a commit. 37 | - [Common] Staging one of conflicted versions (e.g., mine,rXX,rYY in SVN; ours and theris in Git) accepts that version 38 | - [Common] Visual diff between conflicted versions 39 | 40 | ### Changed 41 | - [Git] No need to unstage to discard changes 42 | - [Git] When Pull results in conflicts, do not reset hard (stay in a conflicted state). When conflicts occur, ours and theirs versions are created in the same directory (e.g., test.ktr -> test.ktr.ours and test.ktr.theirs) 43 | - [Common] Rename "Git Project" to "Project" b/c it now supports SVN 44 | 45 | ### Fixed 46 | - Fix a bug that deleted files cannot be staged for a commit 47 | 48 | ## 0.7.3 - 2017-10-17 49 | ### Fixed 50 | - The layout of CloneRepositoryDialog 51 | - Ignore parse error when typing an url 52 | - A bug that a remote branch cannot be checked-out 53 | - A bug that deleting a branch deletes a tag with the same name 54 | 55 | ## 0.7.2 - 2017-09-28 56 | ### Fixed 57 | - Fix a typo bug that tries to push instead of pull when the cached credential does not get authenticated 58 | 59 | ## 0.7.1 - 2017-09-25 60 | ### Fixed 61 | - Fix the bug that visual diff does not work when WORKINGTREE or HEAD is compared 62 | 63 | ## 0.7.0 - 2017-09-19 64 | ### Added 65 | - Tagging feature 66 | - Menuitems to push specific branch/tag 67 | - A context menuitem "Reset to this commit" 68 | 69 | ### Changed 70 | - To avoid accidental loss of work, abort merge/pull if one or more tabs have unsaved changes 71 | - Do not merge (and pull) when the working tree is dirty 72 | 73 | ## 0.6.1 - 2017-09-05 74 | ### Added 75 | - Ask to add a repository when no repository 76 | - Restore Stage/Unstage menuitems in the context menu 77 | - Show a error msg when trying to open/visualdiff a non-Kettle file 78 | 79 | ### Changed 80 | - Switching to Git perspective does not trigger refresh, added refresh button for that 81 | - Cache one pair of username and password (cleared when Spoon terminates) 82 | 83 | ### Removed 84 | - Do not show texual diff upon selecting a revision 85 | 86 | ## 0.6.0 - 2017-08-30 87 | ### Changed 88 | - Diff can now be between arbitrary two commits 89 | - The two tables for unstaged and staged was merged into one table for changed files 90 | - The list of changed files of past commits can now be shown 91 | - An icon is attached to each changed file, representing ADDED, CHANGED, or REMOVED 92 | - Texual/visual diff of past commits can now be obtained 93 | 94 | ## 0.5.1 - 2017-08-22 95 | ### Added 96 | - Add version.xml and OSS_Licenses.md to the assemply zip 97 | 98 | ### Changed 99 | - Save the repository information to metastore after cloneRepoWithUsernamePassword 100 | 101 | ### Fixed 102 | - Show a confirmation dialog (after adding/deleting a repository) 103 | - Prevent the texual diff from getting garbled (e.g., when Japanese) 104 | 105 | ## 0.5.0 - 2017-08-04 106 | ### Added 107 | - A concept of "Git Repository" is introduced. No longer need to open a Kettle file in order to open the corresponding Git repository. 108 | 109 | ### Changed 110 | - Move **Tools > Git** in the menu to the top toolbar in Git perspective 111 | 112 | ## 0.4.1 - 2017-07-20 113 | ### Fixed 114 | - Fix an issue that visual diff of Kettle files in sub-directories is not shown 115 | 116 | ## 0.4.0 - 2017-07-13 117 | ### Added 118 | - "Discard changes in working tree" to the context menu 119 | - setAccelerator for "Data Integration" menu (CTRL+D) 120 | - Visual diff 121 | 122 | ### Fixed 123 | - Improve messages (e.g., "null" -> empty string) 124 | 125 | ## 0.3.2 - 2017-06-22 126 | ### Fixed 127 | - Use Apache HTTP Client instead of Sun HTTP client. This fixes the communication with a remote repository via HTTP(S) in EE. 128 | 129 | ## 0.3.1 - 2017-06-13 130 | ### Added 131 | - Japanese translation 132 | - Users can clone a remote repository (from the menu Tools > Git) 133 | - Users can checkout a particular commit (thru a context menu on a commit) 134 | - Users can create / delete a branch 135 | - Users can merge a branch into the current one 136 | 137 | ## 0.3.0 - 2017-06-05 138 | ### Added 139 | - Users can switch between branches 140 | 141 | ## 0.2.2 - 2017-06-04 142 | ### Added 143 | - Pull/push with username and password 144 | 145 | ## 0.2.1 - 2017-05-31 146 | ### Changed 147 | - Do not show diff when WIP (work-in-progress) is selected for the sake of performance 148 | - Remove the dependency on pdi-pur-plugin and copy the required classes 149 | 150 | ## 0.2.0 - 2017-05-28 151 | 152 | ### Added 153 | - Show diff 154 | - Support VFS (local) 155 | 156 | ## 0.1.0 - 2017-05-17 157 | 158 | ### Added 159 | - Show directory, branch, remote (origin) 160 | - Show commits 161 | - Show unstaged changes and untracked files 162 | - Show staged changes 163 | - Users can edit the directory 164 | - Users can edit the remote (origin only) 165 | - Users can edit the commit message 166 | - Users can edit the author name 167 | - Users can initialize a git repository when not exists 168 | - Users can stage and unstage files 169 | - Users can commit 170 | - Users can pull 171 | - Users can push 172 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2017 Hitachi America, Ltd., R&D. 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /OSS_Licenses.md: -------------------------------------------------------------------------------- 1 | This is the list of OSS that pdi-git-plugin depends upon. 2 | 3 | | Component | Version | Home Page | License In Effect | 4 | |-----------|---------|-----------|-------------------| 5 | | JGit | 5.1.13.202002110435-r | https://eclipse.org/jgit/ | [Eclipse Distribution License - v 1.0](https://www.eclipse.org/org/documents/edl-v10.php) | 6 | | JGit Apache Httpclient Based HTTP Support | 5.1.13.202002110435-r | https://eclipse.org/jgit/ | [Eclipse Distribution License - v 1.0](https://www.eclipse.org/org/documents/edl-v10.php) | 7 | | Apache HttpCore | 4.4.13 | https://hc.apache.org/ | [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) | 8 | | Apache HttpClient | 4.5.12 | https://hc.apache.org/ | [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) | 9 | | Apache Subversion JavaHL | 1.9.4 | http://subclipse.tigris.org/wiki/JavaHL | [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) | 10 | | SVNClientAdapter | 1.9.4-2 | http://subclipse.tigris.org/svnClientAdapter.html | [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) | 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | This plugin allows you to manage versions of local Kettle files without leaving Spoon. 4 | In addition to Git, Subversion is also supported. 5 | 6 | # How to install 7 | 8 | ## 1. PDI Plugin 9 | 10 | ``` 11 | $ cd data-integration/plugins 12 | $ unzip pdi-git-plugin-X.X.X-jar-with-dependencies.zip 13 | ``` 14 | 15 | To uninstall, just remove the `pdi-git-plugin` folder. 16 | 17 | ## 2. Native SVN libraries (skip if Subversion is not used) 18 | 19 | ### Windows 20 | 21 | 1. Download SlikSVN from [here](https://sliksvn.com/download/) and install it 22 | 2. Copy `C:\Program Files\SlikSvn\bin\libsvnjavahl-1.dll` to `libswt\win64` (64-bit) or to `libswt\win32` (32-bit) 23 | 24 | ### Mac OS X 25 | 26 | ``` 27 | brew install subversion --with-java 28 | sudo ln -s /usr/local/lib/libsvnjavahl-1.dylib $JAVA_HOME/jre/lib/ 29 | ``` 30 | 31 | or follow instructions in [here](http://subclipse.stage.tigris.org/wiki/JavaHL). 32 | 33 | ### Linux (Debian/Ubuntu) 34 | 35 | ``` 36 | $ sudo apt-get install libsvn-java 37 | ``` 38 | 39 | Append `/usr/lib/x86_64-linux-gnu/jni/` to `LIBPATH` in `spoon.sh` as follows: 40 | 41 | ``` 42 | LIBPATH=$LIBPATH:/usr/lib/x86_64-linux-gnu/jni/ 43 | export LIBPATH 44 | ``` 45 | 46 | Important: For example in Ubuntu 14.04, the version of libsvn-java will be 1.8.8 by default, but it should be 1.9.X. 47 | Ubuntu 16.04 (Xenial) gives you 1.9.3 by default. 48 | See [here](https://tecadmin.net/install-subversion-1-9-on-ubuntu/) how to install 1.9.X to Ubuntu 14.04. 49 | 50 | # How to use 51 | 52 | The Git plugin is provided as a perspective (See [Using Perspectives](https://help.pentaho.com/Documentation/7.1/0L0/0Y0/020)). 53 | **View > Perspectives > Git** takes you to the Git perspective. 54 | 55 | ## Project 56 | 57 | When you switch to the Git perspective, you will be asked to choose a Project out of a list to open. 58 | To add a Project to the list, go to 59 | 60 | **Project > Add**. 61 | 62 | ### Config 63 | 64 | **Config** allows you to configure the opened Project. 65 | Currently, a remote repository named "origin" can be set. 66 | 67 | ## Commit history 68 | 69 | The commit history is listed in reverse chronological order. 70 | Selecting one of the commits shows a list of changed files in that particular commit. 71 | If there are any changes in the working tree, WORKINGTREE is added to the top of the list, where you can see those changes. 72 | Right-click menu on a commit differs between Git and Subversion. 73 | 74 | ### Git 75 | 76 | - **Checkout**: checkout a previous commit (`git checkout `). **Branch > Checkout** to undo this operation. 77 | - **Rollback**: rollback to a previous commit (`git revert --no-commit HEAD..`). **Discard changes** to undo this operation. 78 | - **Reset**: reset HEAD to a previous commit (`git reset --mixed `). 79 | 80 | ### Subversion 81 | 82 | - **Update**: update to a previous revision (`svn update -r )`. **Update** to undo this operation. 83 | - **Rollback**: rollback to a previous commit (`svn merge -r BASE:`). **Discard changes** to undo this operation. 84 | 85 | Use **Checkout/Update** to see how the contents looked like at that commit with the commit history intact. 86 | Use **Rollback** to rollback all the changes. A new commit can be made to persist the rollback. 87 | 88 | ## Working with files 89 | 90 | If you have changed files but WORKINGTREE is not listed, push **Refresh** to reflect the changes in the Git perspective. 91 | Make sure no commit other than WORKINGTREE is selected in the commit history. 92 | Stage changed files by checking the checkbox on the left side of each file, write a good commit message, change the author name if necessary, and finally Commit. 93 | 94 | ### Diff 95 | 96 | Diff information can be obtained texually and visually. 97 | In order to get the right diff you want to see, it is important to understand the followings: 98 | 99 | - When only one commit is selected, the diff will be between the selected commit and its first parent commit. 100 | - When multiple commits are selected, the diff will be between the newest commit and the oldest commit (out of the selected commits). 101 | - When no commit is selected, it is assumed that WORKINGTREE is selected. 102 | 103 | Examples: 104 | 105 | - Only WORKINGTREE is selected: (1) 106 | - Only 456def is selected: (2) 107 | - WORKINGTREE and 456def are selected: (3) 108 | - 123abc and 789ghi are selected: (4) 109 | 110 | You can also see the diff of a specific changed file by selecting one of them, but special rules applie when WORKINGTREE is selected. 111 | 112 | - If only WORKINGTREE is selected AND the selected file is not staged: (5) 113 | - If only WORKINGTREE is selected AND the selected file is staged: (6) 114 | - If another commit is also selected: the diff will be between WORKINGTREE and that another commit 115 | 116 | 117 | 118 | A texual diff will be displayed in the bottom left corner. 119 | Visual diff can be displayed by right-clicking on a changed file, then choose **Visual diff**. 120 | This opens up two tabs in the Data Integration perspective: 121 | one tab shows the difference you see when looking from one commit to another commit, and the other tab shows the other way around. 122 | 123 | The difference is represented by the small icon superimposed on the top-right corner on the steps/job entries like the image below: 124 | 125 | 126 | 127 | Each icon means as follows: 128 | 129 | - : Added 130 | - : Changed 131 | - : Removed 132 | 133 | Note that even just a x-y location change of step/job entry is recognized as a changed one. 134 | 135 | ### Resolve conflicts 136 | 137 | Conflicts happen when merging on a Git repository or when updating on a Subversion repository, but it is difficult to resolve. 138 | Even a very simple conflict like below could be a problem because Spoon won't open such an ill-formed file and editing a Kettle file in a text editor might fail to conform with the Kettle file format. 139 | Instead of resolving conflicts line-by-line, this plugin allows you to resolve them by accepting one out of conflicted versions. 140 | 141 | ``` 142 | 143 | ++<<<<<<< HEAD 144 | + 320 145 | + 32 146 | ++======= 147 | + 416 148 | + 80 149 | ++>>>>>>> d003036e19537739415b7a7c0e6ded6238050189 150 | Y 151 | 152 | ``` 153 | 154 | When a Kettle file, say `hoge.ktr`, has conflicts, this plugin creates a file for each version. 155 | For a Git repository, `hoge.ktr.ours` and `hoge.ktr.theirs` are created. 156 | For a Subversion repository, `hoge.ktr.mine`, `hoge.ktr.rXX`, and `hoge.ktr.rYY` are created. 157 | To accept your desired version, **Stage** the corresponding file (e.g., `hoge.ktr.ours`), then make a commit. 158 | To abort, **Discard changes** of the conflicted file (e.g., `hoge.ktr`) and (Git-only) **Reset** to the latest commit. 159 | 160 | ## Remote 161 | 162 | **Pull** and **Push** allows you to sync between the opened, local repository and the remote one. 163 | **Pull** and **Push** are equivalent of `git pull` and `git push`, respectively. 164 | Thus, the remote `origin` is the source of Pull and the target of Push unless configured otherwise. 165 | If an error (e.g., merge conflict) happens, the operation will be just cancelled. 166 | 167 | These commands, however, behave differently depending on how `origin` and branches are configured. 168 | Here is an example `.git/config` (see [here](https://git-scm.com/docs/git-config) for more details): 169 | 170 | ``` 171 | [branch "master"] 172 | mergeoptions = --no-ff 173 | [remote "origin"] 174 | url = git@example.com:hiromu/testrepo.git 175 | fetch = +refs/heads/*:refs/remotes/origin/* 176 | pushurl = git@example.com:hiromu/testrepo.git 177 | pushurl = git@example.com:hiromu/testrepo2.git 178 | ``` 179 | 180 | With this example config, **Pull** uses the non fast-forward mode instead of the default fast-forward mode when merging into `master`, **Push** pushes the current branch to two remotes. 181 | 182 | ### Subversion 183 | 184 | **Push** is disabled because making a commit always pushes changes to the remote repository. 185 | Instead of **Pull**, **Update** is used because of the Subversion terminology. 186 | 187 | ## Branches 188 | 189 | **Branch** has branch operations: **Checkout** switches between branches, **Create / Delete** can create / delete a branch, **Merge** can merge a branch into the current one, **Push** can push a specific branch. 190 | 191 | Switching to a remote branch, say `origin/feature`, gets you in a detached HEAD state. 192 | Use **Branch > Create** to create a local branch, say `feature`, then you will get out of the state. 193 | Collectively, they are equivalent of `git checkout origin/feature` then `git checkout -b feature`. 194 | 195 | ### Subversion 196 | 197 | The typical repository layout is trunk/branches/tags, but currently this plugin has no assumption on the layout. 198 | Thus, the list of branches includes any directories in the repository. 199 | For example, the list may include `/trunk` and `/tags/tag1`. 200 | 201 | ## Tags 202 | 203 | **Tag** has tagging operations similar to 204 | **Branch** except **Merge** is not available. 205 | 206 | ## FAQ 207 | 208 | ### When pushing, I get an "UnknownHostKey" error 209 | 210 | This happens when connecting to the remote repository via SSH. 211 | Please add the host to `~/.ssh/known_hosts` in "ssh-rsa" format instead of "ecdsa-sha2-nistp256" format. 212 | 213 | ### The remote host has been added, but I still get an "UnknownHostKey" error 214 | 215 | This could happen for example when the remote host is Gerrit. 216 | The remote host will be added by executing `$ ssh -p 29418 hiromu@localhost` 217 | 218 | ``` 219 | [localhost]:29418 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAFgEc3BqPijHvVs5KoXLLoBaYtBlW8c8v+wpHEPpKObAF0lSG2qt764zFUE1eRlb/thq8RdNxHQ8l+i4VLTlR8= 220 | ``` 221 | 222 | However, JSch (Java library for SSH and used in the Git plugin) prefers **ssh-rsa** over **ecdsa-sha2-nistp256**. Hence, add the remote host like below. 223 | 224 | ``` 225 | [localhost]:29418 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDVoiADWyjer2MRMZYAl1Ws/0zj9VyqMgYQxgNL+xcFGz4cO4AZIaL5L6TlNaU5bOF3WeCFgDLMrMioUoWS/0yLE5Q9mXwE2/5V3fEKDgMfuO+xvEGoh/xZb0GqhCeioG63+clqrXM8DvYfqzMmUg8ksPejEYeQpSrTkg0S5RE9AEB/+qvNnipye7M+9Nutr2lSE+GRhRfFNITCXLIAN6ukoKis+xVZgCMXFSnS41PlhQ/mLNJdA1bMxjm1/58iJsdF44iD+cuM/mFvLoAnXeAbOkkj8jyM136vAvO45M5c+a6Z8k4X7Q/CxsZ2IowWfUshg0jsjerzANUPCaoP9VJX 226 | ``` 227 | 228 | ### When behind proxy 229 | 230 | Define *System Properties* (not environment variables) like below in spoon.sh 231 | 232 | ``` 233 | OPT="$OPT -Dhttp.proxyHost=localhost -Dhttp.proxyPort=3128 -Dhttps.proxyHost=localhost -Dhttps.proxyPort=3128" 234 | ``` 235 | 236 | or in Spoon.bat 237 | 238 | ``` 239 | set OPT=%OPT% "-Dhttp.proxyHost=10.0.2.2" "-Dhttp.proxyPort=3128" "-Dhttps.proxyHost=10.0.2.2" "-Dhttps.proxyPort=3128" 240 | ``` 241 | 242 | The host and port should be replaced according to your proxy server. 243 | 244 | ### I got "407 Proxy Authentication Required" error 245 | 246 | Proxy Authentication is currently not supported. 247 | 248 | ### When I checkedout a remote branch, say *origin/develop*, I ended up being in a HEAD detached state. How can I create a local branch? 249 | 250 | Please create a branch called *develop*, then you will be out of the HEAD detached state. 251 | 252 | ### Auth fail when using publickey authentication 253 | 254 | When an error happens during clone/pull/push, please check the followings: 255 | 256 | - A private key is placed at `~/.ssh/` and the file name is either `identity`, `id_rsa`, or `id_dsa`. 257 | - The private key was created without a passphrase. 258 | - The corresponding public key is registered at the remote repository. 259 | - As of 0.1.54, JSch only supports DSA, RSA, and ECDSA-256. ECDSA-384 and ECDSA-521 do not work (fixed in 0.1.55) and Ed25519 is not supported. 260 | 261 | # How to compile 262 | 263 | ``` 264 | mvn clean package 265 | ``` 266 | 267 | You may need to include the directory that has the native SVN libraries like below. 268 | 269 | ``` 270 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/jni 271 | mvn clean package 272 | ``` 273 | -------------------------------------------------------------------------------- /images/diff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/ae96274fbda0c1874f1a393adeba87499a5b272d/images/diff.png -------------------------------------------------------------------------------- /images/screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/ae96274fbda0c1874f1a393adeba87499a5b272d/images/screenshot-1.png -------------------------------------------------------------------------------- /images/screenshot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/ae96274fbda0c1874f1a393adeba87499a5b272d/images/screenshot-2.png -------------------------------------------------------------------------------- /images/visualdiff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/ae96274fbda0c1874f1a393adeba87499a5b272d/images/visualdiff.png -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | pentaho-kettle 6 | pdi-git-plugin 7 | 1.1.2-SNAPSHOT 8 | jar 9 | 10 | pdi-git-plugin 11 | http://maven.apache.org 12 | 13 | 14 | 15 | 16 | maven-compiler-plugin 17 | 3.1 18 | 19 | 1.8 20 | 1.8 21 | 22 | 23 | 24 | maven-assembly-plugin 25 | 2.5.3 26 | 27 | src/assembly/zip.xml 28 | 29 | 30 | 31 | create-archive 32 | package 33 | 34 | single 35 | 36 | 37 | 38 | 39 | 40 | org.jacoco 41 | jacoco-maven-plugin 42 | 0.7.9 43 | 44 | ${basedir}/target/coverage-reports/jacoco-unit.exec 45 | ${basedir}/target/coverage-reports/jacoco-unit.exec 46 | 47 | 48 | 49 | jacoco-initialize 50 | 51 | prepare-agent 52 | 53 | 54 | 55 | jacoco-site 56 | package 57 | 58 | report 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | pentaho-kettle 69 | kettle-ui-swt 70 | ${dependency.kettle.revision} 71 | provided 72 | 73 | 74 | com.googlecode.json-simple 75 | json-simple 76 | 1.1.1 77 | provided 78 | 79 | 80 | org.eclipse.jgit 81 | org.eclipse.jgit 82 | ${dependency.jgit.revision} 83 | 84 | 85 | org.eclipse.jgit 86 | org.eclipse.jgit.http.apache 87 | ${dependency.jgit.revision} 88 | 89 | 90 | org.tigris.svnclientadapter 91 | adapter-base 92 | 1.9.4-2 93 | 94 | 95 | org.tigris.svnclientadapter 96 | adapter-javahl 97 | 1.9.4-2 98 | 99 | 100 | org.apache.subversion 101 | javahl 102 | 1.9.4 103 | 104 | 105 | org.apache.httpcomponents 106 | httpclient 107 | 4.5.12 108 | 109 | 110 | org.apache.httpcomponents 111 | httpcore 112 | 4.4.13 113 | 114 | 115 | commons-io 116 | commons-io 117 | 2.2 118 | provided 119 | 120 | 121 | junit 122 | junit 123 | 4.13.1 124 | test 125 | 126 | 127 | org.eclipse.jgit 128 | org.eclipse.jgit.junit 129 | ${dependency.jgit.revision} 130 | test 131 | 132 | 133 | org.mockito 134 | mockito-all 135 | 1.9.5 136 | test 137 | 138 | 139 | 140 | 7.1.0.0-12 141 | 7.1.0.0-12 142 | 5.1.13.202002110435-r 143 | 144 | 145 | 146 | Pentaho Public Release Repo 147 | http://nexus.pentaho.org/content/groups/omni 148 | 149 | 150 | bintray-maven 151 | https://dl.bintray.com/subclipse/maven 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /src/assembly/zip.xml: -------------------------------------------------------------------------------- 1 | 5 | jar-with-dependencies 6 | 7 | zip 8 | 9 | false 10 | 11 | 12 | ${basedir} 13 | ${project.name} 14 | 15 | version.xml 16 | OSS_Licenses.md 17 | 18 | 19 | 20 | ${project.build.directory} 21 | ${project.name} 22 | 23 | *.jar 24 | version.xml 25 | 26 | 27 | 28 | 29 | 30 | ${project.name}/lib 31 | false 32 | false 33 | runtime 34 | false 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/main/java/org/pentaho/di/git/spoon/DrawDiffOnJobEntryExtensionPoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hitachi America, Ltd., R&D. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.pentaho.di.git.spoon; 18 | 19 | import static org.pentaho.di.git.spoon.PdiDiff.*; 20 | 21 | import org.pentaho.di.core.exception.KettleException; 22 | import org.pentaho.di.core.extension.ExtensionPoint; 23 | import org.pentaho.di.core.extension.ExtensionPointInterface; 24 | import org.pentaho.di.core.gui.BasePainter; 25 | import org.pentaho.di.core.gui.GCInterface; 26 | import org.pentaho.di.core.gui.Point; 27 | import org.pentaho.di.core.logging.LogChannelInterface; 28 | import org.pentaho.di.job.JobMeta; 29 | import org.pentaho.di.job.JobPainter; 30 | import org.pentaho.di.ui.core.ConstUI; 31 | import org.pentaho.di.ui.core.PropsUI; 32 | 33 | @ExtensionPoint( 34 | id = "DrawDiffOnJobEntryExtensionPoint", 35 | description = "Draws a marker on top of a job entry if it has some change", 36 | extensionPointId = "JobPainterEnd" ) 37 | public class DrawDiffOnJobEntryExtensionPoint implements ExtensionPointInterface { 38 | 39 | @Override 40 | public void callExtensionPoint( LogChannelInterface log, Object object ) throws KettleException { 41 | if ( !( object instanceof JobPainter ) ) { 42 | return; 43 | } 44 | JobPainter painter = (JobPainter) object; 45 | Point offset = painter.getOffset(); 46 | GCInterface gc = painter.getGc(); 47 | JobMeta jobMeta = painter.getJobMeta(); 48 | jobMeta.getJobCopies().stream().filter( je -> je.getAttribute( ATTR_GIT, ATTR_STATUS ) != null ) 49 | .forEach( je -> { 50 | if ( jobMeta.getJobversion() == null ? false : jobMeta.getJobversion().startsWith( "git" ) ) { 51 | String status = je.getAttribute( ATTR_GIT, ATTR_STATUS ); 52 | Point n = je.getLocation(); 53 | String location = "org/pentaho/di/git/spoon/images/"; 54 | if ( status.equals( REMOVED ) ) { 55 | location += "removed.svg"; 56 | } else if ( status.equals( CHANGED ) ) { 57 | location += "changed.svg"; 58 | } else if ( status.equals( ADDED ) ) { 59 | location += "added.svg"; 60 | } else { // Unchanged 61 | return; 62 | } 63 | int iconsize = ConstUI.ICON_SIZE; 64 | try { 65 | iconsize = PropsUI.getInstance().getIconSize(); 66 | } catch ( Exception e ) { 67 | // Exception when accessed from Carte 68 | } 69 | gc.drawImage( location, getClass().getClassLoader(), ( n.x + iconsize + offset.x ) - ( BasePainter.MINI_ICON_SIZE / 2 ), n.y + offset.y - ( BasePainter.MINI_ICON_SIZE / 2 ) ); 70 | } else { 71 | je.getAttributesMap().remove( ATTR_GIT ); 72 | } 73 | } ); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/org/pentaho/di/git/spoon/DrawDiffOnStepExtensionPoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hitachi America, Ltd., R&D. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.pentaho.di.git.spoon; 18 | 19 | import static org.pentaho.di.git.spoon.PdiDiff.*; 20 | 21 | import org.pentaho.di.core.exception.KettleException; 22 | import org.pentaho.di.core.extension.ExtensionPoint; 23 | import org.pentaho.di.core.extension.ExtensionPointInterface; 24 | import org.pentaho.di.core.gui.GCInterface; 25 | import org.pentaho.di.core.gui.Point; 26 | import org.pentaho.di.core.gui.BasePainter; 27 | import org.pentaho.di.core.logging.LogChannelInterface; 28 | import org.pentaho.di.trans.TransMeta; 29 | import org.pentaho.di.trans.TransPainter; 30 | import org.pentaho.di.ui.core.ConstUI; 31 | import org.pentaho.di.ui.core.PropsUI; 32 | 33 | @ExtensionPoint( 34 | id = "DrawDiffOnTransExtensionPoint", 35 | description = "Draws a marker on top of a step if it has some change", 36 | extensionPointId = "TransPainterEnd" ) 37 | public class DrawDiffOnStepExtensionPoint implements ExtensionPointInterface { 38 | 39 | @Override 40 | public void callExtensionPoint( LogChannelInterface log, Object object ) throws KettleException { 41 | if ( !( object instanceof TransPainter ) ) { 42 | return; 43 | } 44 | TransPainter painter = (TransPainter) object; 45 | Point offset = painter.getOffset(); 46 | GCInterface gc = painter.getGc(); 47 | TransMeta transMeta = painter.getTransMeta(); 48 | transMeta.getSteps().stream().filter( step -> step.getAttribute( ATTR_GIT, ATTR_STATUS ) != null ) 49 | .forEach( step -> { 50 | if ( transMeta.getTransversion() == null ? false : transMeta.getTransversion().startsWith( "git" ) ) { 51 | String status = step.getAttribute( ATTR_GIT, ATTR_STATUS ); 52 | Point n = step.getLocation(); 53 | String location = "org/pentaho/di/git/spoon/images/"; 54 | if ( status.equals( REMOVED ) ) { 55 | location += "removed.svg"; 56 | } else if ( status.equals( CHANGED ) ) { 57 | location += "changed.svg"; 58 | } else if ( status.equals( ADDED ) ) { 59 | location += "added.svg"; 60 | } else { // Unchanged 61 | return; 62 | } 63 | int iconsize = ConstUI.ICON_SIZE; 64 | try { 65 | iconsize = PropsUI.getInstance().getIconSize(); 66 | } catch ( Exception e ) { 67 | // Exception when accessed from Carte 68 | } 69 | gc.drawImage( location, getClass().getClassLoader(), ( n.x + iconsize + offset.x ) - ( BasePainter.MINI_ICON_SIZE / 2 ), n.y + offset.y - ( BasePainter.MINI_ICON_SIZE / 2 ) ); 70 | } else { 71 | step.getAttributesMap().remove( ATTR_GIT ); 72 | } 73 | } ); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/org/pentaho/di/git/spoon/GitPerspective.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hitachi America, Ltd., R&D. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.pentaho.di.git.spoon; 18 | 19 | import java.io.InputStream; 20 | import java.util.List; 21 | import java.util.Locale; 22 | import java.util.ResourceBundle; 23 | import java.util.stream.Stream; 24 | 25 | import org.eclipse.jface.action.ActionContributionItem; 26 | import org.eclipse.jface.action.MenuManager; 27 | import org.eclipse.swt.SWT; 28 | import org.eclipse.swt.SWTException; 29 | import org.eclipse.swt.widgets.Composite; 30 | import org.pentaho.di.core.EngineMetaInterface; 31 | import org.pentaho.di.i18n.BaseMessages; 32 | import org.pentaho.di.ui.spoon.Spoon; 33 | import org.pentaho.di.ui.spoon.SpoonPerspectiveImageProvider; 34 | import org.pentaho.di.ui.spoon.SpoonPerspectiveListener; 35 | import org.pentaho.di.ui.spoon.XulSpoonResourceBundle; 36 | import org.pentaho.di.ui.xul.KettleXulLoader; 37 | import org.pentaho.metastore.api.exceptions.MetaStoreException; 38 | import org.pentaho.ui.xul.XulDomContainer; 39 | import org.pentaho.ui.xul.XulException; 40 | import org.pentaho.ui.xul.XulOverlay; 41 | import org.pentaho.ui.xul.XulRunner; 42 | import org.pentaho.ui.xul.components.XulConfirmBox; 43 | import org.pentaho.ui.xul.containers.XulMenupopup; 44 | import org.pentaho.ui.xul.containers.XulVbox; 45 | import org.pentaho.ui.xul.impl.XulEventHandler; 46 | import org.pentaho.ui.xul.swt.SwtXulRunner; 47 | import org.pentaho.ui.xul.swt.tags.SwtDeck; 48 | import org.pentaho.ui.xul.util.XulDialogCallback.Status; 49 | import org.pentaho.ui.xul.util.XulDialogLambdaCallback; 50 | 51 | public class GitPerspective implements SpoonPerspectiveImageProvider { 52 | 53 | private static Class PKG = GitPerspective.class; 54 | private ResourceBundle resourceBundle = new XulSpoonResourceBundle( PKG ); 55 | 56 | final String PERSPECTIVE_ID = "010-git"; //$NON-NLS-1$ 57 | final String PERSPECTIVE_NAME = "gitPerspective"; //$NON-NLS-1$ 58 | 59 | private XulDomContainer container; 60 | private GitController controller; 61 | private GitSpoonMenuController gitSpoonMenuController; 62 | private XulVbox box; 63 | 64 | public GitPerspective() throws XulException { 65 | // Loading Xul Document 66 | KettleXulLoader loader = new KettleXulLoader(); 67 | loader.registerClassLoader( getClass().getClassLoader() ); 68 | container = loader.loadXul( "org/pentaho/di/git/spoon/xul/git_perspective.xul", resourceBundle ); 69 | 70 | // Adding Event Handlers 71 | controller = new GitController(); 72 | gitSpoonMenuController = new GitSpoonMenuController(); 73 | gitSpoonMenuController.setGitController( controller ); 74 | container.addEventHandler( controller ); 75 | container.addEventHandler( gitSpoonMenuController ); 76 | 77 | final XulRunner runner = new SwtXulRunner(); 78 | runner.addContainer( container ); 79 | runner.initialize(); //calls any onload events 80 | 81 | /* 82 | * To make compatible with webSpoon 83 | * Create a temporary parent for the UI and then call layout(). 84 | * A different parent will be assigned to the UI in SpoonPerspectiveManager.PerspectiveManager.performInit(). 85 | */ 86 | SwtDeck deck = (SwtDeck) Spoon.getInstance().getXulDomContainer().getDocumentRoot().getElementById( "canvas-deck" ); 87 | box = deck.createVBoxCard(); 88 | getUI().setParent( (Composite) box.getManagedObject() ); 89 | getUI().layout(); 90 | 91 | /** 92 | * Hack: setAccelerator 'CTRL(CMD) + D' to "Data Integration" menu 93 | */ 94 | int mask = 'D'; 95 | if ( System.getProperty( "KETTLE_CONTEXT_PATH" ) == null ) { // Spoon 96 | boolean isMac = System.getProperty( "os.name" ).toLowerCase().indexOf( "mac" ) >= 0; 97 | mask += isMac ? SWT.COMMAND : SWT.CTRL; 98 | } else { // webSpoon 99 | mask += SWT.CTRL; 100 | } 101 | int keyCode = mask; 102 | XulMenupopup menuPopup = (XulMenupopup) Spoon.getInstance().getXulDomContainer().getDocumentRoot().getElementById( "view-perspectives-popup" ); 103 | MenuManager menuMgr = (MenuManager) menuPopup.getManagedObject(); 104 | Stream.of( menuMgr.getItems() ) 105 | .map( menu -> ( (ActionContributionItem) menu ).getAction() ) 106 | .filter( action -> action.getText().equals( "Data Integration" ) ).findFirst().ifPresent( action -> { 107 | action.setAccelerator( keyCode ); 108 | } ); 109 | } 110 | 111 | @Override 112 | public String getId() { 113 | return PERSPECTIVE_ID; 114 | } 115 | 116 | public String getName() { 117 | return PERSPECTIVE_NAME; 118 | } 119 | 120 | @Override 121 | public Composite getUI() { 122 | return (Composite) container.getDocumentRoot().getRootElement().getFirstChild().getManagedObject(); 123 | } 124 | 125 | @Override 126 | public String getDisplayName( Locale l ) { 127 | return BaseMessages.getString( PKG, "Git.Perspective.perspectiveName" ); 128 | } 129 | 130 | @Override 131 | public InputStream getPerspectiveIcon() { 132 | // TODO Auto-generated method stub 133 | return null; 134 | } 135 | 136 | @Override 137 | public void setActive( boolean active ) { 138 | try { // Dispose the temporary parent 139 | ( (Composite) box.getManagedObject() ).dispose(); 140 | } catch ( SWTException e ) { 141 | // To nothing 142 | } 143 | if ( active ) { 144 | if ( !controller.isOpen() ) { 145 | try { 146 | if ( gitSpoonMenuController.isRepoEmpty() ) { 147 | XulConfirmBox confirmBox = (XulConfirmBox) container.getDocumentRoot().createElement( "confirmbox" ); 148 | confirmBox.setTitle( "No repository" ); 149 | confirmBox.setMessage( "Add a new one?" ); 150 | confirmBox.setAcceptLabel( BaseMessages.getString( PKG, "Dialog.Ok" ) ); 151 | confirmBox.setCancelLabel( BaseMessages.getString( PKG, "Dialog.Cancel" ) ); 152 | confirmBox.addDialogCallback( (XulDialogLambdaCallback) ( sender, returnCode, retVal ) -> { 153 | if ( returnCode == Status.ACCEPT ) { 154 | try { 155 | gitSpoonMenuController.addRepo(); 156 | } catch ( Exception e ) { 157 | e.printStackTrace(); 158 | } 159 | } 160 | } ); 161 | confirmBox.open(); 162 | } else { 163 | gitSpoonMenuController.openRepo(); 164 | } 165 | } catch ( Exception e ) { 166 | e.printStackTrace(); 167 | } 168 | } 169 | } 170 | } 171 | 172 | @Override 173 | public List getOverlays() { 174 | // TODO Auto-generated method stub 175 | return null; 176 | } 177 | 178 | @Override 179 | public List getEventHandlers() { 180 | // TODO Auto-generated method stub 181 | return null; 182 | } 183 | 184 | @Override 185 | public void addPerspectiveListener( SpoonPerspectiveListener listener ) { 186 | // TODO Auto-generated method stub 187 | 188 | } 189 | 190 | @Override 191 | public EngineMetaInterface getActiveMeta() { 192 | // TODO Auto-generated method stub 193 | return null; 194 | } 195 | 196 | @Override 197 | public String getPerspectiveIconPath() { 198 | // TODO Auto-generated method stub 199 | return null; 200 | } 201 | 202 | public GitController getController() { 203 | return this.controller; 204 | } 205 | 206 | /** 207 | * This method is made as convenience for other plugins so that they can directly open a repository 208 | * by simply getting a hold of the main plugin class. 209 | * 210 | * @param repositoryName 211 | */ 212 | public void openRepository( String repositoryName ) throws MetaStoreException { 213 | gitSpoonMenuController.openRepo( repositoryName ); 214 | } 215 | 216 | /** 217 | * This method is made as convenience for other plugins so that they see which GitSpoon repositories are defined. 218 | * 219 | * @return The list of git repository names 220 | * @throws MetaStoreException 221 | */ 222 | public List getRepoNames() throws MetaStoreException { 223 | return gitSpoonMenuController.getRepoNames(); 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /src/main/java/org/pentaho/di/git/spoon/GitSpoonMenuController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hitachi America, Ltd., R&D. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.pentaho.di.git.spoon; 18 | 19 | import java.io.File; 20 | import java.util.Collections; 21 | import java.util.List; 22 | 23 | import org.eclipse.jface.window.Window; 24 | import org.eclipse.swt.widgets.Shell; 25 | import org.pentaho.di.git.spoon.dialog.CloneRepositoryDialog; 26 | import org.pentaho.di.git.spoon.dialog.EditRepositoryDialog; 27 | import org.pentaho.di.git.spoon.dialog.UsernamePasswordDialog; 28 | import org.pentaho.di.git.spoon.model.GitRepository; 29 | import org.pentaho.di.git.spoon.model.IVCS; 30 | import org.pentaho.di.git.spoon.model.SVN; 31 | import org.pentaho.di.git.spoon.model.UIGit; 32 | import org.pentaho.di.i18n.BaseMessages; 33 | import org.pentaho.di.ui.core.dialog.EnterSelectionDialog; 34 | import org.pentaho.di.ui.core.dialog.ErrorDialog; 35 | import org.pentaho.di.ui.spoon.ISpoonMenuController; 36 | import org.pentaho.di.ui.spoon.Spoon; 37 | import org.pentaho.metastore.api.IMetaStore; 38 | import org.pentaho.metastore.api.exceptions.MetaStoreException; 39 | import org.pentaho.metastore.persist.MetaStoreFactory; 40 | import org.pentaho.metastore.util.PentahoDefaults; 41 | import org.pentaho.ui.xul.XulException; 42 | import org.pentaho.ui.xul.components.XulConfirmBox; 43 | import org.pentaho.ui.xul.components.XulMessageBox; 44 | import org.pentaho.ui.xul.dom.Document; 45 | import org.pentaho.ui.xul.impl.AbstractXulEventHandler; 46 | import org.pentaho.ui.xul.util.XulDialogCallback.Status; 47 | import org.pentaho.ui.xul.util.XulDialogLambdaCallback; 48 | 49 | import com.google.common.annotations.VisibleForTesting; 50 | 51 | public class GitSpoonMenuController extends AbstractXulEventHandler implements ISpoonMenuController { 52 | 53 | private static final Class PKG = GitController.class; 54 | 55 | private GitController gitController; 56 | 57 | public void setGitController( GitController gitController ) { 58 | this.gitController = gitController; 59 | } 60 | 61 | public void openRepo() { 62 | MetaStoreFactory repoFactory = getRepoFactory(); 63 | 64 | try { 65 | List names = repoFactory.getElementNames(); 66 | Collections.sort( names ); 67 | EnterSelectionDialog esd = new EnterSelectionDialog( getShell(), names.toArray( new String[names.size()] ), "Select Repository", "Select the repository to open..." ); 68 | String name = esd.open(); 69 | 70 | if ( name == null ) { 71 | return; 72 | } 73 | 74 | openRepo( name ); 75 | } catch ( Exception e ) { 76 | new ErrorDialog( Spoon.getInstance().getShell(), "Error", "Error opening Git Reposisory", e ); 77 | } 78 | } 79 | 80 | /** 81 | * Open a repository with a given name. 82 | * Convenience method so we can call this method from other places/plugins. 83 | * 84 | * @param repositoryName The name of the repository to open 85 | * @throws MetaStoreException 86 | */ 87 | public void openRepo( String repositoryName ) throws MetaStoreException { 88 | MetaStoreFactory repoFactory = getRepoFactory(); 89 | GitRepository repo = repoFactory.loadElement( repositoryName ); 90 | gitController.openGit( repo ); 91 | } 92 | 93 | /** 94 | * Allow other plugins to see which Git repositories are defined. 95 | * @return A list of Git Reposisoty names 96 | * @throws MetaStoreException 97 | */ 98 | public List getRepoNames() throws MetaStoreException { 99 | MetaStoreFactory repoFactory = getRepoFactory(); 100 | return repoFactory.getElementNames(); 101 | } 102 | 103 | public Boolean isRepoEmpty() throws MetaStoreException { 104 | return getRepoFactory().getElementNames().isEmpty(); 105 | } 106 | 107 | @Override 108 | public void updateMenu( Document doc ) { 109 | } 110 | 111 | @Override 112 | public String getName() { 113 | return "gitSpoonMenuController"; 114 | } 115 | 116 | public void addRepo() throws MetaStoreException, XulException { 117 | MetaStoreFactory repoFactory = getRepoFactory(); 118 | EditRepositoryDialog dialog = new EditRepositoryDialog( getShell(), null ); 119 | if ( dialog.open() == Window.OK ) { 120 | GitRepository repo = dialog.getGitRepository(); 121 | repoFactory.saveElement( repo ); 122 | 123 | XulConfirmBox confirmBox = (XulConfirmBox) document.createElement( "confirmbox" ); 124 | confirmBox.setTitle( "Success" ); 125 | confirmBox.setMessage( "Open now?" ); 126 | confirmBox.setAcceptLabel( BaseMessages.getString( PKG, "Dialog.Ok" ) ); 127 | confirmBox.setCancelLabel( BaseMessages.getString( PKG, "Dialog.Cancel" ) ); 128 | confirmBox.addDialogCallback( (XulDialogLambdaCallback) ( sender, returnCode, retVal ) -> { 129 | if ( returnCode == Status.ACCEPT ) { 130 | gitController.openGit( repo ); 131 | } 132 | } ); 133 | confirmBox.open(); 134 | } 135 | } 136 | 137 | public void removeRepo() throws MetaStoreException { 138 | MetaStoreFactory repoFactory = getRepoFactory(); 139 | 140 | List names = repoFactory.getElementNames(); 141 | Collections.sort( names ); 142 | EnterSelectionDialog esd = new EnterSelectionDialog( getShell(), names.toArray( new String[names.size()] ), "Select Repository", "Select the repository to remove..." ); 143 | String name = esd.open(); 144 | 145 | if ( name != null ) { 146 | repoFactory.deleteElement( name ); 147 | showMessageBox( "Success", "Success" ); 148 | } 149 | } 150 | 151 | public void editRepo() throws MetaStoreException { 152 | MetaStoreFactory repoFactory = getRepoFactory(); 153 | 154 | List names = repoFactory.getElementNames(); 155 | Collections.sort( names ); 156 | EnterSelectionDialog esd = new EnterSelectionDialog( getShell(), names.toArray( new String[names.size()] ), "Select Repository", "Select the repository to edit..." ); 157 | String name = esd.open(); 158 | 159 | if ( name == null ) { 160 | return; 161 | } 162 | GitRepository repo = repoFactory.loadElement( name ); 163 | EditRepositoryDialog dialog = new EditRepositoryDialog( getShell(), repo ); 164 | if ( dialog.open() == Window.OK ) { 165 | repoFactory.saveElement( dialog.getGitRepository() ); 166 | } 167 | } 168 | 169 | public void cloneRepo() { 170 | CloneRepositoryDialog dialog = getCloneRepositoryDialog( null ); 171 | if ( dialog.open() == Window.OK ) { 172 | GitRepository repo = dialog.getGitRepository(); 173 | // Check if the parent directory exists 174 | if ( !new File( repo.getPhysicalDirectory() ).exists() ) { 175 | showMessageBox( "Error", repo.getPhysicalDirectory() + " does not exist" ); 176 | return; 177 | } 178 | String url = dialog.getURL(); 179 | // This is the directory to clone to. 180 | String directory = repo.getPhysicalDirectory() + File.separator + dialog.getCloneAs(); 181 | IVCS vcs = getVCS( repo ); 182 | vcs.setShell( getShell() ); 183 | if ( vcs.cloneRepo( directory, url ) ) { 184 | showMessageBox( "Success", "Success" ); 185 | // Update the repo's directory 186 | repo.setDirectory( directory ); 187 | saveRepository( repo ); 188 | gitController.openGit( repo ); 189 | } 190 | } 191 | } 192 | 193 | @VisibleForTesting 194 | void showMessageBox( String title, String message ) { 195 | try { 196 | XulMessageBox messageBox = (XulMessageBox) document.createElement( "messagebox" ); 197 | messageBox.setTitle( title ); 198 | messageBox.setMessage( message ); 199 | messageBox.open(); 200 | } catch ( XulException e ) { 201 | e.printStackTrace(); 202 | } 203 | } 204 | 205 | @VisibleForTesting 206 | CloneRepositoryDialog getCloneRepositoryDialog( GitRepository repo ) { 207 | return new CloneRepositoryDialog( getShell(), repo ); 208 | } 209 | 210 | @VisibleForTesting 211 | UsernamePasswordDialog getUsernamePasswordDialog() { 212 | return new UsernamePasswordDialog( getShell() ); 213 | } 214 | 215 | @VisibleForTesting 216 | void saveRepository( GitRepository repo ) { 217 | MetaStoreFactory repoFactory = getRepoFactory(); 218 | try { 219 | repoFactory.saveElement( repo ); 220 | } catch ( MetaStoreException e ) { 221 | e.printStackTrace(); 222 | } 223 | } 224 | 225 | Shell getShell() { 226 | return Spoon.getInstance().getShell(); 227 | } 228 | 229 | private MetaStoreFactory getRepoFactory() { 230 | IMetaStore metaStore = Spoon.getInstance().getMetaStore(); 231 | return new MetaStoreFactory( GitRepository.class, metaStore, PentahoDefaults.NAMESPACE ); 232 | } 233 | 234 | @VisibleForTesting 235 | IVCS getVCS( GitRepository repo ) { 236 | if ( repo.getType() == null || repo.getType().equals( IVCS.GIT ) ) { 237 | return new UIGit(); 238 | } else { 239 | return new SVN(); 240 | } 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /src/main/java/org/pentaho/di/git/spoon/GitSpoonPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hitachi America, Ltd., R&D. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.pentaho.di.git.spoon; 18 | 19 | import java.util.ResourceBundle; 20 | 21 | import org.pentaho.di.ui.spoon.SpoonLifecycleListener; 22 | import org.pentaho.di.ui.spoon.SpoonPerspective; 23 | import org.pentaho.di.ui.spoon.SpoonPlugin; 24 | import org.pentaho.di.ui.spoon.SpoonPluginCategories; 25 | import org.pentaho.di.ui.spoon.SpoonPluginInterface; 26 | import org.pentaho.di.ui.spoon.XulSpoonResourceBundle; 27 | import org.pentaho.ui.xul.XulDomContainer; 28 | import org.pentaho.ui.xul.XulException; 29 | 30 | @SpoonPlugin( id = "GitSpoonPlugin", image = "" ) 31 | @SpoonPluginCategories( { "spoon" } ) 32 | public class GitSpoonPlugin implements SpoonPluginInterface, SpoonLifecycleListener { 33 | 34 | private static final Class PKG = GitSpoonPlugin.class; 35 | private ResourceBundle resourceBundle = new XulSpoonResourceBundle( PKG ); 36 | 37 | private GitPerspective perspective; 38 | 39 | public GitSpoonPlugin() throws XulException { 40 | this.perspective = new GitPerspective(); 41 | } 42 | 43 | @Override 44 | public void onEvent( SpoonLifeCycleEvent evt ) { 45 | // TODO Auto-generated method stub 46 | } 47 | 48 | @Override 49 | public void applyToContainer( String category, XulDomContainer container ) throws XulException { 50 | container.registerClassLoader( getClass().getClassLoader() ); 51 | if ( category.equals( "spoon" ) ) { 52 | container.loadOverlay( "org/pentaho/di/git/spoon/xul/git_spoon_overlays.xul", resourceBundle ); 53 | } 54 | } 55 | 56 | @Override 57 | public SpoonLifecycleListener getLifecycleListener() { 58 | // TODO Auto-generated method stub 59 | return this; 60 | } 61 | 62 | @Override 63 | public SpoonPerspective getPerspective() { 64 | return perspective; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/org/pentaho/di/git/spoon/PdiDiff.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hitachi America, Ltd., R&D. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.pentaho.di.git.spoon; 18 | 19 | import java.util.Map; 20 | import java.util.Optional; 21 | 22 | import org.pentaho.di.core.exception.KettleException; 23 | import org.pentaho.di.job.JobMeta; 24 | import org.pentaho.di.job.entry.JobEntryCopy; 25 | import org.pentaho.di.trans.TransMeta; 26 | import org.pentaho.di.trans.step.StepMeta; 27 | 28 | public class PdiDiff { 29 | public static String ATTR_GIT = "Git"; 30 | public static String ATTR_STATUS = "Status"; 31 | 32 | public static String UNCHANGED = "UNCHANGED"; 33 | public static String CHANGED = "CHANGED"; 34 | public static String REMOVED = "REMOVED"; 35 | public static String ADDED = "ADDED"; 36 | 37 | public static TransMeta compareSteps( TransMeta transMeta1, TransMeta transMeta2, boolean isForward ) { 38 | transMeta1.getSteps().forEach( step -> { 39 | Optional step2 = transMeta2.getSteps().stream() 40 | .filter( obj -> step.getName().equals( obj.getName() ) ).findFirst(); 41 | String status = null; 42 | if ( step2.isPresent() ) { 43 | Map tmp = null, tmp2 = null; 44 | try { 45 | // AttributeMap("Git") cannot affect the XML comparison 46 | tmp = step.getAttributesMap().remove( ATTR_GIT ); 47 | tmp2 = step2.get().getAttributesMap().remove( ATTR_GIT ); 48 | if ( step.getXML().equals( step2.get().getXML() ) ) { 49 | status = UNCHANGED; 50 | } else { 51 | status = CHANGED; 52 | } 53 | } catch ( KettleException e ) { 54 | e.printStackTrace(); 55 | } finally { 56 | step.setAttributes( ATTR_GIT, tmp ); 57 | step2.get().setAttributes( ATTR_GIT, tmp2 ); 58 | } 59 | } else { 60 | if ( isForward ) { 61 | status = REMOVED; 62 | } else { 63 | status = ADDED; 64 | } 65 | } 66 | step.setAttribute( ATTR_GIT, ATTR_STATUS, status.toString() ); 67 | } ); 68 | return transMeta1; 69 | } 70 | 71 | public static JobMeta compareJobEntries( JobMeta jobMeta1, JobMeta jobMeta2, boolean isForward ) { 72 | jobMeta1.getJobCopies().forEach( je -> { 73 | Optional je2 = jobMeta2.getJobCopies().stream() 74 | .filter( obj -> je.getName().equals( obj.getName() ) ).findFirst(); 75 | String status = null; 76 | if ( je2.isPresent() ) { 77 | Map tmp = null, tmp2 = null; 78 | // AttributeMap("Git") cannot affect the XML comparison 79 | tmp = je.getAttributesMap().remove( ATTR_GIT ); 80 | tmp2 = je2.get().getAttributesMap().remove( ATTR_GIT ); 81 | if ( je.getXML().equals( je2.get().getXML() ) ) { 82 | status = UNCHANGED; 83 | } else { 84 | status = CHANGED; 85 | } 86 | je.setAttributes( ATTR_GIT, tmp ); 87 | je2.get().setAttributes( ATTR_GIT, tmp2 ); 88 | } else { 89 | if ( isForward ) { 90 | status = REMOVED; 91 | } else { 92 | status = ADDED; 93 | } 94 | } 95 | je.setAttribute( ATTR_GIT, ATTR_STATUS, status.toString() ); 96 | } ); 97 | return jobMeta1; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/org/pentaho/di/git/spoon/dialog/CloneRepositoryDialog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hitachi America, Ltd., R&D. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.pentaho.di.git.spoon.dialog; 18 | 19 | import java.io.File; 20 | import java.net.URISyntaxException; 21 | 22 | import org.eclipse.jgit.transport.URIish; 23 | import org.eclipse.swt.SWT; 24 | import org.eclipse.swt.layout.GridData; 25 | import org.eclipse.swt.layout.GridLayout; 26 | import org.eclipse.swt.widgets.Composite; 27 | import org.eclipse.swt.widgets.Control; 28 | import org.eclipse.swt.widgets.Label; 29 | import org.eclipse.swt.widgets.Shell; 30 | import org.eclipse.swt.widgets.Text; 31 | import org.pentaho.di.git.spoon.model.GitRepository; 32 | 33 | public class CloneRepositoryDialog extends EditRepositoryDialog { 34 | 35 | private Text urlText; 36 | private String url; 37 | private Text cloneAsText; 38 | private String cloneAs; 39 | 40 | public CloneRepositoryDialog( Shell parentShell, GitRepository repo ) { 41 | super( parentShell, repo ); 42 | APPLICATION_NAME = "Clone Repository"; 43 | } 44 | 45 | @Override 46 | protected Control createDialogArea( Composite parent ) { 47 | Composite comp = (Composite) super.createDialogArea( parent ); 48 | 49 | GridLayout layout = (GridLayout) comp.getLayout(); 50 | layout.numColumns = 3; 51 | 52 | Label urlLabel = new Label( comp, SWT.RIGHT ); 53 | urlLabel.setText( "Source URL: " ); 54 | urlLabel.setLayoutData( new GridData( GridData.END, GridData.CENTER, false, false ) ); 55 | urlText = new Text( comp, SWT.SINGLE | SWT.BORDER ); 56 | urlText.setLayoutData( new GridData( GridData.FILL, GridData.CENTER, true, false, 2, 1 ) ); 57 | 58 | Label cloneAsLabel = new Label( comp, SWT.RIGHT ); 59 | cloneAsLabel.setText( "Clone As: " ); 60 | cloneAsLabel.setLayoutData( new GridData( GridData.END, GridData.CENTER, false, false ) ); 61 | cloneAsText = new Text( comp, SWT.SINGLE | SWT.BORDER ); 62 | cloneAsText.setLayoutData( new GridData( GridData.FILL, GridData.CENTER, true, false, 2, 1 ) ); 63 | 64 | urlText.addModifyListener( event -> { 65 | String url = ( (Text) event.widget ).getText(); 66 | URIish uri; 67 | try { 68 | uri = new URIish( url ); 69 | cloneAsText.setText( uri.getHumanishName() ); 70 | } catch ( URISyntaxException e ) { 71 | // e.printStackTrace(); 72 | } 73 | } ); 74 | 75 | return comp; 76 | } 77 | 78 | @Override 79 | protected void okPressed() { 80 | url = urlText.getText(); 81 | cloneAs = cloneAsText.getText(); 82 | super.okPressed(); 83 | } 84 | 85 | public String getURL() { 86 | return url; 87 | } 88 | 89 | public String getCloneAs() { 90 | return cloneAs; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/org/pentaho/di/git/spoon/dialog/DeleteBranchDialog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hitachi America, Ltd., R&D. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.pentaho.di.git.spoon.dialog; 18 | 19 | import java.util.List; 20 | 21 | import org.eclipse.jface.dialogs.Dialog; 22 | import org.eclipse.swt.SWT; 23 | import org.eclipse.swt.custom.CCombo; 24 | import org.eclipse.swt.events.SelectionAdapter; 25 | import org.eclipse.swt.events.SelectionEvent; 26 | import org.eclipse.swt.layout.GridData; 27 | import org.eclipse.swt.layout.GridLayout; 28 | import org.eclipse.swt.widgets.Button; 29 | import org.eclipse.swt.widgets.Composite; 30 | import org.eclipse.swt.widgets.Control; 31 | import org.eclipse.swt.widgets.Label; 32 | import org.eclipse.swt.widgets.Shell; 33 | import org.pentaho.di.git.spoon.GitController; 34 | import org.pentaho.di.i18n.BaseMessages; 35 | 36 | public class DeleteBranchDialog extends Dialog { 37 | 38 | private static final Class PKG = GitController.class; 39 | 40 | private CCombo comboBranch; 41 | private String selectedBranch; 42 | private boolean isForce; 43 | private List branches; 44 | 45 | public DeleteBranchDialog( Shell parentShell ) { 46 | super( parentShell ); 47 | } 48 | 49 | @Override 50 | protected Control createDialogArea( Composite parent ) { 51 | Composite comp = (Composite) super.createDialogArea( parent ); 52 | 53 | GridLayout layout = (GridLayout) comp.getLayout(); 54 | layout.numColumns = 2; 55 | 56 | Label branchLabel = new Label( comp, SWT.RIGHT ); 57 | branchLabel.setText( BaseMessages.getString( PKG, "Git.Dialog.Branch.Delete.Message" ) ); 58 | comboBranch = new CCombo( comp, SWT.DROP_DOWN ); 59 | comboBranch.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) ); 60 | comboBranch.addSelectionListener( new SelectionAdapter() { 61 | @Override 62 | public void widgetSelected( SelectionEvent e ) { 63 | selectedBranch = ( (CCombo) e.getSource() ).getText(); 64 | } 65 | } ); 66 | branches.forEach( branch -> comboBranch.add( branch ) ); 67 | 68 | Label forceLabel = new Label( comp, SWT.RIGHT ); 69 | forceLabel.setText( BaseMessages.getString( PKG, "Git.Dialog.Force" ) ); 70 | Button forceButton = new Button( comp, SWT.CHECK ); 71 | forceButton.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) ); 72 | forceButton.addSelectionListener( new SelectionAdapter() { 73 | @Override 74 | public void widgetSelected( SelectionEvent e ) { 75 | isForce = ( (Button) e.getSource() ).getSelection(); 76 | } 77 | } ); 78 | forceButton.setSelection( false ); 79 | 80 | return comp; 81 | } 82 | 83 | public void setBranches( List branches ) { 84 | this.branches = branches; 85 | } 86 | 87 | public String getSelectedBranch() { 88 | return selectedBranch; 89 | } 90 | 91 | public boolean isForce() { 92 | return isForce; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/org/pentaho/di/git/spoon/dialog/EditRepositoryDialog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hitachi America, Ltd., R&D. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.pentaho.di.git.spoon.dialog; 18 | 19 | 20 | import org.eclipse.jface.dialogs.Dialog; 21 | import org.eclipse.swt.SWT; 22 | import org.eclipse.swt.events.SelectionAdapter; 23 | import org.eclipse.swt.events.SelectionEvent; 24 | import org.eclipse.swt.graphics.Point; 25 | import org.eclipse.swt.layout.GridData; 26 | import org.eclipse.swt.layout.GridLayout; 27 | import org.eclipse.swt.widgets.Button; 28 | import org.eclipse.swt.widgets.Combo; 29 | import org.eclipse.swt.widgets.Composite; 30 | import org.eclipse.swt.widgets.Control; 31 | import org.eclipse.swt.widgets.DirectoryDialog; 32 | import org.eclipse.swt.widgets.Label; 33 | import org.eclipse.swt.widgets.Shell; 34 | import org.eclipse.swt.widgets.Text; 35 | import org.pentaho.di.core.Const; 36 | import org.pentaho.di.core.variables.VariableSpace; 37 | import org.pentaho.di.core.variables.Variables; 38 | import org.pentaho.di.git.spoon.model.GitRepository; 39 | import org.pentaho.di.git.spoon.model.IVCS; 40 | import org.pentaho.di.ui.core.PropsUI; 41 | import org.pentaho.di.ui.core.gui.WindowProperty; 42 | import org.pentaho.di.ui.core.widget.TextVar; 43 | 44 | public class EditRepositoryDialog extends Dialog { 45 | 46 | private Text nameText; 47 | private Text descText; 48 | private TextVar directoryText; 49 | private String directory; 50 | private Combo typeCombo; 51 | 52 | protected PropsUI props; 53 | protected GitRepository repo; 54 | protected VariableSpace space; 55 | protected static String APPLICATION_NAME; 56 | 57 | /** 58 | * A dialog to edit repository settings. 59 | * @param parentShell 60 | * @param repo a repository to edit. Can be null to create a new one. 61 | */ 62 | public EditRepositoryDialog( Shell parentShell, GitRepository repo ) { 63 | super( parentShell ); 64 | if ( repo != null ) { 65 | this.repo = repo; 66 | } else { 67 | this.repo = new GitRepository(); 68 | } 69 | props = PropsUI.getInstance(); 70 | APPLICATION_NAME = "Edit Repository"; 71 | 72 | space = new Variables(); 73 | space.initializeVariablesFrom( null ); // system vars only 74 | } 75 | 76 | @Override 77 | public int open() { 78 | // Create shell and contents 79 | setShellStyle( SWT.DIALOG_TRIM | SWT.RESIZE ); 80 | create(); 81 | 82 | // Post-configure shell like the title and size 83 | Shell shell = getShell(); 84 | shell.setText( APPLICATION_NAME ); 85 | WindowProperty winprop = props.getScreen( shell.getText() ); 86 | if ( winprop != null ) { 87 | winprop.setShell( shell ); 88 | } 89 | return super.open(); 90 | } 91 | 92 | @Override 93 | protected Control createDialogArea( Composite parent ) { 94 | Composite comp = (Composite) super.createDialogArea( parent ); 95 | 96 | GridLayout layout = (GridLayout) comp.getLayout(); 97 | layout.numColumns = 3; 98 | 99 | Label nameLabel = new Label( comp, SWT.RIGHT ); 100 | nameLabel.setText( "Name: " ); 101 | nameLabel.setLayoutData( new GridData( GridData.END, GridData.CENTER, false, false ) ); 102 | nameText = new Text( comp, SWT.SINGLE | SWT.BORDER ); 103 | nameText.setText( Const.NVL( repo.getName(), "" ) ); 104 | nameText.setLayoutData( new GridData( GridData.FILL, GridData.CENTER, true, false, 2, 1 ) ); 105 | 106 | Label descLabel = new Label( comp, SWT.RIGHT ); 107 | descLabel.setText( "Description: " ); 108 | descLabel.setLayoutData( new GridData( GridData.END, GridData.CENTER, false, false ) ); 109 | descText = new Text( comp, SWT.SINGLE | SWT.BORDER ); 110 | descText.setLayoutData( new GridData( GridData.FILL, GridData.CENTER, true, false, 2, 1 ) ); 111 | descText.setText( Const.NVL( repo.getDescription(), "" ) ); 112 | 113 | Label directoryLabel = new Label( comp, SWT.RIGHT ); 114 | directoryLabel.setText( "Directory: " ); 115 | directoryLabel.setLayoutData( new GridData( GridData.END, GridData.CENTER, false, false ) ); 116 | directoryText = new TextVar( space, comp, SWT.SINGLE | SWT.BORDER ); 117 | directoryText.setLayoutData( new GridData( GridData.FILL, GridData.CENTER, true, false ) ); 118 | directoryText.setText( Const.NVL( repo.getDirectory(), "" ) ); 119 | 120 | Button directoryButton = new Button( comp, SWT.PUSH ); 121 | directoryButton.setText( "Browse" ); 122 | directoryButton.addSelectionListener( new SelectionAdapter() { 123 | @Override 124 | public void widgetSelected( SelectionEvent e ) { 125 | DirectoryDialog dialog = new DirectoryDialog( getShell(), SWT.OPEN ); 126 | if ( dialog.open() != null ) { 127 | directoryText.setText( dialog.getFilterPath() ); 128 | } 129 | } 130 | } ); 131 | 132 | Label typeLabel = new Label( comp, SWT.RIGHT ); 133 | typeLabel.setText( "Type: " ); 134 | typeLabel.setLayoutData( new GridData( GridData.END, GridData.CENTER, false, false ) ); 135 | typeCombo = new Combo( comp, SWT.READ_ONLY ); 136 | typeCombo.setItems( IVCS.GIT, IVCS.SVN ); 137 | if ( repo.getType() != null ) { 138 | if ( repo.getType().equals( IVCS.GIT ) ) { 139 | typeCombo.select( 0 ); 140 | } else { 141 | typeCombo.select( 1 ); 142 | } 143 | } 144 | typeCombo.setLayoutData( new GridData( GridData.FILL, GridData.CENTER, true, false, 2, 1 ) ); 145 | return comp; 146 | } 147 | 148 | @Override 149 | protected void okPressed() { 150 | repo.setName( nameText.getText() ); 151 | repo.setDescription( descText.getText() ); 152 | repo.setDirectory( directoryText.getText() ); 153 | repo.setType( typeCombo.getText() ); 154 | directory = directoryText.getText(); 155 | super.okPressed(); 156 | } 157 | 158 | @Override 159 | public Point getInitialSize() { 160 | Point point = super.getInitialSize(); 161 | return new Point( 500, point.y ); 162 | } 163 | 164 | public String getDirectory() { 165 | return directory; 166 | } 167 | 168 | public GitRepository getGitRepository() { return repo; } 169 | 170 | @Override 171 | public boolean close() { 172 | props.setScreen( new WindowProperty( getShell() ) ); 173 | return super.close(); 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /src/main/java/org/pentaho/di/git/spoon/dialog/MergeBranchDialog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hitachi America, Ltd., R&D. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.pentaho.di.git.spoon.dialog; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | 22 | import org.eclipse.jface.dialogs.Dialog; 23 | import org.eclipse.jgit.merge.MergeStrategy; 24 | import org.eclipse.swt.SWT; 25 | import org.eclipse.swt.custom.CCombo; 26 | import org.eclipse.swt.events.SelectionAdapter; 27 | import org.eclipse.swt.events.SelectionEvent; 28 | import org.eclipse.swt.layout.GridData; 29 | import org.eclipse.swt.layout.GridLayout; 30 | import org.eclipse.swt.widgets.Composite; 31 | import org.eclipse.swt.widgets.Control; 32 | import org.eclipse.swt.widgets.Label; 33 | import org.eclipse.swt.widgets.Shell; 34 | import org.pentaho.di.git.spoon.GitController; 35 | import org.pentaho.di.i18n.BaseMessages; 36 | 37 | public class MergeBranchDialog extends Dialog { 38 | 39 | private static final Class PKG = GitController.class; 40 | private static final List listMergeStrategy = new ArrayList(); 41 | static { 42 | listMergeStrategy.add( MergeStrategy.RECURSIVE.getName() ); 43 | listMergeStrategy.add( MergeStrategy.OURS.getName() ); 44 | listMergeStrategy.add( MergeStrategy.THEIRS.getName() ); 45 | } 46 | 47 | private CCombo comboBranch; 48 | private String selectedBranch; 49 | private List branches; 50 | private CCombo comboMergeStrategy; 51 | private String selectedMergeStrategy; 52 | 53 | public MergeBranchDialog( Shell parentShell ) { 54 | super( parentShell ); 55 | } 56 | 57 | @Override 58 | protected Control createDialogArea( Composite parent ) { 59 | Composite comp = (Composite) super.createDialogArea( parent ); 60 | 61 | GridLayout layout = (GridLayout) comp.getLayout(); 62 | layout.numColumns = 2; 63 | 64 | Label branchLabel = new Label( comp, SWT.RIGHT ); 65 | branchLabel.setText( BaseMessages.getString( PKG, "Git.Dialog.Branch.Merge.Message" ) ); 66 | comboBranch = new CCombo( comp, SWT.DROP_DOWN ); 67 | comboBranch.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) ); 68 | comboBranch.addSelectionListener( new SelectionAdapter() { 69 | @Override 70 | public void widgetSelected( SelectionEvent e ) { 71 | selectedBranch = ( (CCombo) e.getSource() ).getText(); 72 | } 73 | } ); 74 | branches.forEach( branch -> comboBranch.add( branch ) ); 75 | 76 | Label strategyLabel = new Label( comp, SWT.RIGHT ); 77 | strategyLabel.setText( BaseMessages.getString( PKG, "Git.Dialog.Branch.Merge.MergeStrategy" ) ); 78 | comboMergeStrategy = new CCombo( comp, SWT.DROP_DOWN ); 79 | comboMergeStrategy.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) ); 80 | listMergeStrategy.forEach( mergeStrategy -> comboMergeStrategy.add( mergeStrategy ) ); 81 | comboMergeStrategy.select( 0 ); 82 | selectedMergeStrategy = listMergeStrategy.get( 0 ); 83 | comboMergeStrategy.addSelectionListener( new SelectionAdapter() { 84 | @Override 85 | public void widgetSelected( SelectionEvent e ) { 86 | selectedMergeStrategy = ( (CCombo) e.getSource() ).getText(); 87 | } 88 | } ); 89 | 90 | return comp; 91 | } 92 | 93 | public void setBranches( List branches ) { 94 | this.branches = branches; 95 | } 96 | 97 | public String getSelectedBranch() { 98 | return selectedBranch; 99 | } 100 | 101 | public String getSelectedMergeStrategy() { 102 | return selectedMergeStrategy; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/org/pentaho/di/git/spoon/dialog/UsernamePasswordDialog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hitachi America, Ltd., R&D. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.pentaho.di.git.spoon.dialog; 18 | 19 | import org.eclipse.jface.dialogs.Dialog; 20 | import org.eclipse.swt.SWT; 21 | import org.eclipse.swt.layout.GridData; 22 | import org.eclipse.swt.layout.GridLayout; 23 | import org.eclipse.swt.widgets.Composite; 24 | import org.eclipse.swt.widgets.Control; 25 | import org.eclipse.swt.widgets.Label; 26 | import org.eclipse.swt.widgets.Shell; 27 | import org.eclipse.swt.widgets.Text; 28 | 29 | public class UsernamePasswordDialog extends Dialog { 30 | 31 | private Text usernameText; 32 | private Text passwordText; 33 | private String username; 34 | private String password; 35 | 36 | public UsernamePasswordDialog( Shell parentShell ) { 37 | super( parentShell ); 38 | } 39 | 40 | @Override 41 | protected Control createDialogArea( Composite parent ) { 42 | Composite comp = (Composite) super.createDialogArea( parent ); 43 | 44 | GridLayout layout = (GridLayout) comp.getLayout(); 45 | layout.numColumns = 2; 46 | 47 | Label usernameLabel = new Label( comp, SWT.RIGHT ); 48 | usernameLabel.setText( "Username: " ); 49 | usernameText = new Text( comp, SWT.SINGLE | SWT.BORDER ); 50 | usernameText.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) ); 51 | 52 | Label passwordLabel = new Label( comp, SWT.RIGHT ); 53 | passwordLabel.setText( "Password: " ); 54 | passwordText = new Text( comp, SWT.SINGLE | SWT.BORDER | SWT.PASSWORD ); 55 | passwordText.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) ); 56 | 57 | return comp; 58 | } 59 | 60 | @Override 61 | protected void okPressed() { 62 | username = usernameText.getText(); 63 | password = passwordText.getText(); 64 | super.okPressed(); 65 | } 66 | 67 | public String getUsername() { 68 | return username; 69 | } 70 | 71 | public String getPassword() { 72 | return password; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/org/pentaho/di/git/spoon/model/GitRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hitachi America, Ltd., R&D. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.pentaho.di.git.spoon.model; 18 | 19 | import com.google.common.annotations.VisibleForTesting; 20 | import org.pentaho.di.core.variables.VariableSpace; 21 | import org.pentaho.di.core.variables.Variables; 22 | import org.pentaho.metastore.persist.MetaStoreAttribute; 23 | import org.pentaho.metastore.persist.MetaStoreElementType; 24 | 25 | @MetaStoreElementType( 26 | name = "Git Repository", 27 | description = "This defines a Git repository" ) 28 | public class GitRepository { 29 | 30 | @MetaStoreAttribute( key = "name" ) 31 | private String name; 32 | 33 | public String getName() { 34 | return name; 35 | } 36 | 37 | public void setName( String name ) { 38 | this.name = name; 39 | } 40 | 41 | @MetaStoreAttribute( key = "description" ) 42 | private String description; 43 | 44 | public String getDescription() { 45 | return description; 46 | } 47 | 48 | public void setDescription( String description ) { 49 | this.description = description; 50 | } 51 | 52 | @MetaStoreAttribute( key = "directory" ) 53 | private String directory; 54 | 55 | /** 56 | * Get a directory path that can contain variables. 57 | * @return directory path 58 | */ 59 | public String getDirectory() { 60 | return directory; 61 | } 62 | 63 | public void setDirectory( String directory ) { 64 | this.directory = directory; 65 | } 66 | 67 | @MetaStoreAttribute( key = "type" ) 68 | private String type; 69 | 70 | public String getType() { 71 | return type; 72 | } 73 | 74 | public void setType( String type ) { 75 | this.type = type; 76 | } 77 | 78 | /** 79 | * Get a directory path in the current environment. 80 | * Unlike {@link #getDirectory()}, all variables are resolved. 81 | * @return directory path 82 | */ 83 | public String getPhysicalDirectory() { 84 | VariableSpace space = getVariables(); 85 | return space.environmentSubstitute( directory ); 86 | } 87 | 88 | @VisibleForTesting 89 | VariableSpace getVariables() { 90 | VariableSpace space = new Variables(); 91 | space.initializeVariablesFrom( null ); 92 | return space; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/org/pentaho/di/git/spoon/model/IVCS.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hitachi America, Ltd., R&D. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.pentaho.di.git.spoon.model; 18 | 19 | import java.io.InputStream; 20 | import java.util.List; 21 | 22 | import org.eclipse.swt.widgets.Shell; 23 | import org.pentaho.di.ui.repository.pur.repositoryexplorer.model.UIRepositoryObjectRevisions; 24 | 25 | public interface IVCS { 26 | 27 | String WORKINGTREE = "WORKINGTREE"; 28 | String INDEX = "INDEX"; 29 | String GIT = "Git"; 30 | String SVN = "SVN"; 31 | String TYPE_TAG = "tag"; 32 | String TYPE_BRANCH = "branch"; 33 | String TYPE_REMOTE = "remote"; 34 | String TYPE_COMMIT = "commit"; 35 | 36 | /** 37 | * Get the name of implementation (e.g., Git, SVN) 38 | * @return 39 | */ 40 | String getType(); 41 | 42 | String getDirectory(); 43 | 44 | /** 45 | * If the repository is clean and not dirty. 46 | * @return 47 | */ 48 | boolean isClean(); 49 | 50 | /** 51 | * Get the author name for a commit 52 | * @param commitId 53 | * @return 54 | * @throws Exception 55 | */ 56 | String getAuthorName( String commitId ); 57 | 58 | String getCommitMessage( String commitId ); 59 | 60 | /** 61 | * Get SHA-1 commit Id 62 | * @param revstr: (e.g., HEAD, SHA-1) 63 | * @return 64 | * @throws Exception 65 | */ 66 | String getCommitId( String revstr ); 67 | 68 | /** 69 | * Get SHA-1 commit Id 70 | * @param revstr: (e.g., HEAD, SHA-1) 71 | * @return 72 | * @throws Exception 73 | */ 74 | String getParentCommitId( String revstr ); 75 | 76 | /** 77 | * Get an expanded name from shortened name (e.g., master -> refs/heads/master) 78 | * @param name (e.g., master) 79 | * @param type 80 | * @return 81 | * @throws Exception 82 | */ 83 | String getExpandedName( String name, String type ); 84 | 85 | String getShortenedName( String name, String type ); 86 | 87 | /** 88 | * Get the current branch 89 | * @return Current branch 90 | */ 91 | String getBranch(); 92 | 93 | /** 94 | * Get a list of local branches 95 | * @return 96 | */ 97 | List getLocalBranches(); 98 | 99 | /** 100 | * Get a list of all (local + remote) branches 101 | * @return 102 | */ 103 | List getBranches(); 104 | 105 | String getRemote(); 106 | 107 | void addRemote( String s ); 108 | 109 | void removeRemote(); 110 | 111 | boolean hasRemote(); 112 | 113 | boolean commit( String authorName, String message ); 114 | 115 | UIRepositoryObjectRevisions getRevisions(); 116 | 117 | void setCredential( String username, String password ); 118 | 119 | /** 120 | * Get the list of unstaged files 121 | * @return 122 | */ 123 | List getUnstagedFiles(); 124 | 125 | /** 126 | * Get the list of staged files 127 | * @return 128 | */ 129 | List getStagedFiles(); 130 | 131 | /** 132 | * Get the list of changed files between two commits 133 | * @param oldCommitId 134 | * @param newCommitId 135 | * @return 136 | */ 137 | List getStagedFiles( String oldCommitId, String newCommitId ); 138 | 139 | // TODO should be renamed as canCommit() 140 | boolean hasStagedFiles(); 141 | 142 | void initRepo( String baseDirectory ) throws Exception; 143 | 144 | void openRepo( String baseDirectory ) throws Exception; 145 | 146 | void closeRepo(); 147 | 148 | void add( String filepattern ); 149 | 150 | void rm( String filepattern ); 151 | 152 | void reset( String name ); 153 | 154 | /** 155 | * Reset a file to HEAD 156 | * @param path of the file 157 | * @throws Exception 158 | */ 159 | void resetPath( String path ); 160 | 161 | /** 162 | * Equivalent of git fetch; git merge --ff 163 | * 164 | * @return true on success 165 | * @throws Exception 166 | * @see Git documentation about Pull 167 | */ 168 | boolean pull(); 169 | 170 | boolean push(); 171 | 172 | boolean push( String type ); 173 | 174 | String diff( String oldCommitId, String newCommitId ) throws Exception; 175 | 176 | String diff( String oldCommitId, String newCommitId, String file ); 177 | 178 | InputStream open( String file, String commitId ); 179 | 180 | /** 181 | * Checkout a commit 182 | * @param name 183 | */ 184 | void checkout( String name ); 185 | 186 | void checkoutBranch( String name ); 187 | 188 | void checkoutTag( String name ); 189 | 190 | /** 191 | * Revert a file to the last commited state 192 | * @param path 193 | */ 194 | void revertPath( String path ); 195 | 196 | boolean createBranch( String value ); 197 | 198 | boolean deleteBranch( String name, boolean force ); 199 | 200 | List getTags(); 201 | 202 | boolean createTag( String name ); 203 | 204 | boolean deleteTag( String name ); 205 | 206 | void setShell( Shell shell ); 207 | 208 | boolean merge(); 209 | 210 | boolean cloneRepo( String directory, String url ); 211 | 212 | boolean rollback( String name ); 213 | } 214 | -------------------------------------------------------------------------------- /src/main/java/org/pentaho/di/git/spoon/model/UIFile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hitachi America, Ltd., R&D. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.pentaho.di.git.spoon.model; 18 | 19 | import org.eclipse.jgit.diff.DiffEntry.ChangeType; 20 | import org.pentaho.ui.xul.XulEventSourceAdapter; 21 | 22 | public class UIFile extends XulEventSourceAdapter { 23 | 24 | private String name; 25 | private ChangeType changeType; 26 | private Boolean isStaged = false; 27 | 28 | @Deprecated 29 | public UIFile( String name, ChangeType changeType ) { 30 | this.name = name; 31 | this.changeType = changeType; 32 | } 33 | 34 | public UIFile( String name, ChangeType changeType, Boolean isStaged ) { 35 | this.name = name; 36 | this.changeType = changeType; 37 | this.isStaged = isStaged; 38 | } 39 | 40 | public String getName() { 41 | return name; 42 | } 43 | 44 | public void setName( String name ) { 45 | this.name = name; 46 | } 47 | 48 | public ChangeType getChangeType() { 49 | return changeType; 50 | } 51 | 52 | public void setChangeType( ChangeType changeType ) { 53 | this.changeType = changeType; 54 | } 55 | 56 | public String getImage() { 57 | final String location = "org/pentaho/di/git/spoon/images/"; 58 | switch ( changeType ) { 59 | case ADD: 60 | case COPY: 61 | return location + "added.svg"; 62 | case MODIFY: 63 | case RENAME: 64 | return location + "changed.svg"; 65 | case DELETE: 66 | return location + "removed.svg"; 67 | default: 68 | return ""; 69 | } 70 | } 71 | 72 | public Boolean getIsStaged() { 73 | return isStaged; 74 | } 75 | 76 | public void setIsStaged( Boolean isStaged ) { 77 | this.isStaged = isStaged; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/org/pentaho/di/git/spoon/model/VCS.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hitachi America, Ltd., R&D. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.pentaho.di.git.spoon.model; 18 | 19 | import java.io.InputStream; 20 | import java.util.List; 21 | 22 | import org.eclipse.jface.window.Window; 23 | import org.eclipse.swt.SWT; 24 | import org.eclipse.swt.widgets.MessageBox; 25 | import org.eclipse.swt.widgets.Shell; 26 | import org.pentaho.di.git.spoon.GitController; 27 | import org.pentaho.di.git.spoon.dialog.UsernamePasswordDialog; 28 | import org.pentaho.di.i18n.BaseMessages; 29 | import org.pentaho.di.ui.repository.pur.repositoryexplorer.model.UIRepositoryObjectRevisions; 30 | 31 | import com.google.common.annotations.VisibleForTesting; 32 | 33 | public class VCS implements IVCS { 34 | 35 | protected static final Class PKG = GitController.class; 36 | protected Shell shell; 37 | protected String directory; 38 | 39 | @VisibleForTesting 40 | void showMessageBox( String title, String message ) { 41 | MessageBox messageBox = new MessageBox( shell, SWT.OK ); 42 | messageBox.setText( title ); 43 | messageBox.setMessage( message == null ? "" : message ); 44 | messageBox.open(); 45 | } 46 | 47 | /** 48 | * Prompt the user to set username and password 49 | * @return true on success 50 | */ 51 | protected boolean promptUsernamePassword() { 52 | UsernamePasswordDialog dialog = new UsernamePasswordDialog( shell ); 53 | if ( dialog.open() == Window.OK ) { 54 | String username = dialog.getUsername(); 55 | String password = dialog.getPassword(); 56 | setCredential( username, password ); 57 | return true; 58 | } 59 | return false; 60 | } 61 | 62 | @Override 63 | public String getDirectory() { 64 | return directory; 65 | } 66 | 67 | @Override 68 | public boolean isClean() { 69 | return false; 70 | } 71 | 72 | @Override 73 | public String getAuthorName( String commitId ) { 74 | return null; 75 | } 76 | 77 | @Override 78 | public String getCommitMessage( String commitId ) { 79 | return null; 80 | } 81 | 82 | @Override 83 | public String getCommitId( String revstr ) { 84 | return null; 85 | } 86 | 87 | @Override 88 | public String getParentCommitId( String revstr ) { 89 | return null; 90 | } 91 | 92 | @Override 93 | public String getExpandedName( String name, String type ) { 94 | return name; 95 | } 96 | 97 | @Override 98 | public String getShortenedName( String name, String type ) { 99 | return name; 100 | } 101 | 102 | @Override 103 | public String getBranch() { 104 | // TODO Auto-generated method stub 105 | return null; 106 | } 107 | 108 | @Override 109 | public List getLocalBranches() { 110 | // TODO Auto-generated method stub 111 | return null; 112 | } 113 | 114 | @Override 115 | public List getBranches() { 116 | // TODO Auto-generated method stub 117 | return null; 118 | } 119 | 120 | @Override 121 | public String getRemote() { 122 | // TODO Auto-generated method stub 123 | return null; 124 | } 125 | 126 | @Override 127 | public void addRemote(String s) { 128 | // TODO Auto-generated method stub 129 | 130 | } 131 | 132 | @Override 133 | public void removeRemote() { 134 | // TODO Auto-generated method stub 135 | 136 | } 137 | 138 | @Override 139 | public boolean hasRemote() { 140 | // TODO Auto-generated method stub 141 | return false; 142 | } 143 | 144 | @Override 145 | public boolean commit( String authorName, String message ) { 146 | return false; 147 | } 148 | 149 | @Override 150 | public UIRepositoryObjectRevisions getRevisions() { 151 | // TODO Auto-generated method stub 152 | return null; 153 | } 154 | 155 | @Override 156 | public void setCredential(String username, String password) { 157 | // TODO Auto-generated method stub 158 | 159 | } 160 | 161 | @Override 162 | public List getUnstagedFiles() { 163 | // TODO Auto-generated method stub 164 | return null; 165 | } 166 | 167 | @Override 168 | public List getStagedFiles() { 169 | // TODO Auto-generated method stub 170 | return null; 171 | } 172 | 173 | @Override 174 | public List getStagedFiles(String oldCommitId, String newCommitId) { 175 | // TODO Auto-generated method stub 176 | return null; 177 | } 178 | 179 | @Override 180 | public boolean hasStagedFiles() { 181 | // TODO Auto-generated method stub 182 | return false; 183 | } 184 | 185 | @Override 186 | public void initRepo(String baseDirectory) throws Exception { 187 | // TODO Auto-generated method stub 188 | 189 | } 190 | 191 | @Override 192 | public void openRepo(String baseDirectory) throws Exception { 193 | // TODO Auto-generated method stub 194 | 195 | } 196 | 197 | @Override 198 | public void closeRepo() { 199 | // TODO Auto-generated method stub 200 | 201 | } 202 | 203 | @Override 204 | public void add( String filepattern ) { 205 | } 206 | 207 | @Override 208 | public void rm( String filepattern ) { 209 | } 210 | 211 | @Override 212 | public void reset( String name ) { 213 | showMessageBox( BaseMessages.getString( PKG, "Dialog.Error" ), "Not supported (yet)" ); 214 | } 215 | 216 | @Override 217 | public void resetPath( String path ) { 218 | } 219 | 220 | @Override 221 | public boolean pull() { 222 | showMessageBox( BaseMessages.getString( PKG, "Dialog.Error" ), "Not supported (yet)" ); 223 | return false; 224 | } 225 | 226 | @Override 227 | public boolean push() { 228 | showMessageBox( BaseMessages.getString( PKG, "Dialog.Error" ), "Not supported (yet)" ); 229 | return false; 230 | } 231 | 232 | @Override 233 | public boolean push( String type ) { 234 | showMessageBox( BaseMessages.getString( PKG, "Dialog.Error" ), "Not supported (yet)" ); 235 | return false; 236 | } 237 | 238 | @Override 239 | public String diff(String oldCommitId, String newCommitId) throws Exception { 240 | // TODO Auto-generated method stub 241 | return null; 242 | } 243 | 244 | @Override 245 | public String diff(String oldCommitId, String newCommitId, String file) { 246 | // TODO Auto-generated method stub 247 | return null; 248 | } 249 | 250 | @Override 251 | public InputStream open(String file, String commitId) { 252 | return null; 253 | } 254 | 255 | @Override 256 | public void checkout( String name ) { 257 | showMessageBox( BaseMessages.getString( PKG, "Dialog.Error" ), "Not supported (yet)" ); 258 | } 259 | 260 | @Override 261 | public void revertPath(String path) { 262 | // TODO Auto-generated method stub 263 | 264 | } 265 | 266 | @Override 267 | public boolean createBranch( String value ) { 268 | showMessageBox( BaseMessages.getString( PKG, "Dialog.Error" ), "Not supported (yet)" ); 269 | return false; 270 | } 271 | 272 | @Override 273 | public boolean deleteBranch( String name, boolean force ) { 274 | showMessageBox( BaseMessages.getString( PKG, "Dialog.Error" ), "Not supported (yet)" ); 275 | return false; 276 | } 277 | 278 | @Override 279 | public List getTags() { 280 | return null; 281 | } 282 | 283 | @Override 284 | public boolean createTag( String name ) { 285 | showMessageBox( BaseMessages.getString( PKG, "Dialog.Error" ), "Not supported (yet)" ); 286 | return false; 287 | } 288 | 289 | @Override 290 | public boolean deleteTag( String name ) { 291 | showMessageBox( BaseMessages.getString( PKG, "Dialog.Error" ), "Not supported (yet)" ); 292 | return false; 293 | } 294 | 295 | @Override 296 | public void setShell( Shell shell ) { 297 | this.shell = shell; 298 | } 299 | 300 | @Override 301 | public boolean merge() { 302 | showMessageBox( BaseMessages.getString( PKG, "Dialog.Error" ), "Not supported (yet)" ); 303 | return false; 304 | } 305 | 306 | @Override 307 | public boolean cloneRepo( String directory, String url ) { 308 | return false; 309 | } 310 | 311 | @Override 312 | public String getType() { 313 | return null; 314 | } 315 | 316 | @Override 317 | public void checkoutBranch( String name ) { 318 | } 319 | 320 | @Override 321 | public void checkoutTag( String name ) { 322 | } 323 | 324 | @Override 325 | public boolean rollback( String name ) { 326 | showMessageBox( BaseMessages.getString( PKG, "Dialog.Error" ), "Not supported (yet)" ); 327 | return false; 328 | } 329 | 330 | } 331 | -------------------------------------------------------------------------------- /src/main/java/org/pentaho/di/repository/pur/PurObjectRevision.java: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright 2010 - 2017 Hitachi Vantara. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package org.pentaho.di.repository.pur; 18 | 19 | import java.io.Serializable; 20 | import java.util.Date; 21 | 22 | import org.pentaho.di.repository.ObjectRevision; 23 | 24 | import javax.xml.bind.annotation.XmlAccessType; 25 | import javax.xml.bind.annotation.XmlAccessorType; 26 | import javax.xml.bind.annotation.XmlElement; 27 | import javax.xml.bind.annotation.XmlRootElement; 28 | import javax.xml.bind.annotation.XmlType; 29 | 30 | @XmlRootElement( name = "revision" ) 31 | @XmlAccessorType( XmlAccessType.FIELD ) 32 | @XmlType( name = "", propOrder = { "versionId", "creationDate", "login", "comment" } ) 33 | public class PurObjectRevision implements ObjectRevision, java.io.Serializable { 34 | 35 | private static final long serialVersionUID = -7857510728831225268L; /* EESOURCE: UPDATE SERIALVERUID */ 36 | 37 | // ~ Static fields/initializers ====================================================================================== 38 | 39 | // ~ Instance fields ================================================================================================= 40 | 41 | private String comment; 42 | 43 | private Date creationDate; 44 | 45 | private String login; 46 | 47 | @XmlElement( type = String.class ) 48 | private Serializable versionId; 49 | 50 | // ~ Constructors ==================================================================================================== 51 | 52 | public PurObjectRevision() { 53 | super(); 54 | this.versionId = null; 55 | this.login = null; 56 | // defensive copy 57 | this.creationDate = ( creationDate != null ? new Date( creationDate.getTime() ) : null ); 58 | this.comment = null; 59 | } 60 | 61 | public PurObjectRevision( final Serializable versionId, final String login, final Date creationDate, 62 | final String comment ) { 63 | super(); 64 | this.versionId = versionId; 65 | this.login = login; 66 | // defensive copy 67 | this.creationDate = ( creationDate != null ? new Date( creationDate.getTime() ) : null ); 68 | this.comment = comment; 69 | } 70 | 71 | // ~ Methods ========================================================================================================= 72 | 73 | public String getComment() { 74 | return comment; 75 | } 76 | 77 | public Date getCreationDate() { 78 | // defensive copy 79 | return creationDate != null ? new Date( creationDate.getTime() ) : null; 80 | } 81 | 82 | public String getLogin() { 83 | return login; 84 | } 85 | 86 | public String getName() { 87 | return versionId != null ? versionId.toString() : null; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/org/pentaho/di/ui/repository/pur/repositoryexplorer/model/UIRepositoryObjectRevision.java: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright 2010 - 2017 Hitachi Vantara. All rights reserved. 3 | * Copyright 2017 Hitachi America, Ltd., R&D. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | package org.pentaho.di.ui.repository.pur.repositoryexplorer.model; 19 | 20 | import java.text.SimpleDateFormat; 21 | import java.util.Date; 22 | 23 | import org.pentaho.di.repository.ObjectRevision; 24 | import org.pentaho.ui.xul.XulEventSourceAdapter; 25 | 26 | public class UIRepositoryObjectRevision extends XulEventSourceAdapter implements java.io.Serializable { 27 | 28 | private static final long serialVersionUID = 302159542242909806L; /* EESOURCE: UPDATE SERIALVERUID */ 29 | 30 | protected ObjectRevision obj; 31 | 32 | public UIRepositoryObjectRevision() { 33 | super(); 34 | } 35 | 36 | public UIRepositoryObjectRevision( ObjectRevision obj ) { 37 | super(); 38 | this.obj = obj; 39 | } 40 | 41 | public String getName() { 42 | return obj.getName(); 43 | } 44 | 45 | public String getComment() { 46 | return obj.getComment(); 47 | } 48 | 49 | public Date getCreationDate() { 50 | return obj.getCreationDate(); 51 | } 52 | 53 | public String getFormatCreationDate() { 54 | Date date = getCreationDate(); 55 | String str = null; 56 | if ( date != null ) { 57 | SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssZ" ); 58 | str = sdf.format( date ); 59 | } 60 | return str; 61 | } 62 | 63 | public String getLogin() { 64 | return obj.getLogin(); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/org/pentaho/di/ui/repository/pur/repositoryexplorer/model/UIRepositoryObjectRevisions.java: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright 2010 - 2017 Hitachi Vantara. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package org.pentaho.di.ui.repository.pur.repositoryexplorer.model; 18 | 19 | import java.util.List; 20 | 21 | import org.pentaho.ui.xul.util.AbstractModelNode; 22 | 23 | public class UIRepositoryObjectRevisions extends AbstractModelNode implements 24 | java.io.Serializable { 25 | 26 | private static final long serialVersionUID = -5243106180726024567L; /* EESOURCE: UPDATE SERIALVERUID */ 27 | 28 | public UIRepositoryObjectRevisions() { 29 | } 30 | 31 | public UIRepositoryObjectRevisions( List revisions ) { 32 | super( revisions ); 33 | } 34 | 35 | @Override 36 | protected void fireCollectionChanged() { 37 | this.changeSupport.firePropertyChange( "children", null, this ); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/org/pentaho/ui/xul/util/XulDialogLambdaCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hitachi America, Ltd., R&D. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.pentaho.ui.xul.util; 18 | 19 | import org.pentaho.ui.xul.XulComponent; 20 | 21 | public interface XulDialogLambdaCallback extends XulDialogCallback { 22 | @Override 23 | default void onError( XulComponent sender, Throwable t ) { } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/images/added.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/ae96274fbda0c1874f1a393adeba87499a5b272d/src/main/resources/org/pentaho/di/git/spoon/images/added.png -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/images/added.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | image/svg+xml -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/images/branch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/ae96274fbda0c1874f1a393adeba87499a5b272d/src/main/resources/org/pentaho/di/git/spoon/images/branch.png -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/images/branch.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/images/changed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/ae96274fbda0c1874f1a393adeba87499a5b272d/src/main/resources/org/pentaho/di/git/spoon/images/changed.png -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/images/changed.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/images/pull.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/ae96274fbda0c1874f1a393adeba87499a5b272d/src/main/resources/org/pentaho/di/git/spoon/images/pull.png -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/images/pull.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/images/push.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/ae96274fbda0c1874f1a393adeba87499a5b272d/src/main/resources/org/pentaho/di/git/spoon/images/push.png -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/images/push.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/images/removed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/ae96274fbda0c1874f1a393adeba87499a5b272d/src/main/resources/org/pentaho/di/git/spoon/images/removed.png -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/images/removed.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | image/svg+xml -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/images/repository.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/ae96274fbda0c1874f1a393adeba87499a5b272d/src/main/resources/org/pentaho/di/git/spoon/images/repository.png -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/images/repository.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/images/tag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/ae96274fbda0c1874f1a393adeba87499a5b272d/src/main/resources/org/pentaho/di/git/spoon/images/tag.png -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/images/tag.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/messages/messages_en_US.properties: -------------------------------------------------------------------------------- 1 | Git.Perspective.perspectiveName=Git 2 | 3 | Dialog.Cancel=Cancel 4 | Dialog.Error=Error 5 | Dialog.Ok=OK 6 | Dialog.Success=Success 7 | 8 | Git.Checkout=Checkout 9 | SVN.Checkout=Switch 10 | Git.Config=Config 11 | Git.Repository=Project 12 | Git.Directory=Directory 13 | Git.Pull=Pull 14 | SVN.Pull=Update 15 | Git.Push=Push 16 | Git.Commit=Commit 17 | Git.CommitMessage=Commit Message 18 | Git.Branch=Branch 19 | Git.Tag=Tag 20 | Git.Create=Create 21 | Git.Delete=Delete 22 | Git.Merge=Merge 23 | SVN.Merge=Merge (Reintegrate) 24 | Git.Author=Author 25 | Git.Remote=Remote 26 | Git.Open=Open 27 | Git.Add=Add 28 | Git.Edit=Edit 29 | Git.Remove=Remove 30 | Git.Clone=Clone 31 | Git.StagedChanges=Staged changes 32 | Git.UnstagedChangesAndUntrackedFiles=Unstaged changes and Untracked files 33 | Git.ChangedFiles=Changed files 34 | Git.Refresh=Refresh 35 | 36 | Git.ContextMenu.AddToIndex=Stage 37 | Git.ContextMenu.RemoveFromIndex=Unstage 38 | Git.ContextMenu.Checkout=Checkout 39 | SVN.ContextMenu.Checkout=Update 40 | Git.ContextMenu.Reset=Reset 41 | Git.ContextMenu.Rollback=Rollback 42 | Git.ContextMenu.Discard=Discard changes 43 | Git.ContextMenu.Open=Open 44 | Git.ContextMenu.VisualDiff=Visual diff 45 | 46 | Git.ToolTip.Branch=Create or delete a branch 47 | Git.ToolTip.Merge=Merge a branch to the current one 48 | 49 | Git.Dialog.Branch.Create.Title=Create a branch 50 | Git.Dialog.Branch.Create.Message=Branch to be created 51 | Git.Dialog.Branch.Delete.Message=Branch to be deleted 52 | Git.Dialog.Branch.Merge.Message=Branch to be merged to the current branch 53 | Git.Dialog.Branch.Merge.MergeStrategy=Merge strategy 54 | Git.Dialog.Tag.Create.Title=Create a tag 55 | Git.Dialog.Tag.Create.Message=Tag to be created 56 | Git.Dialog.Force=Force? 57 | Git.Dialog.UncommittedChanges.Message=There are uncommitted changes 58 | 59 | SVN.InvalidRepository=The directory you selected does not contain a Subversion repository. Try Project / Clone to get a remote repository locally. -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/messages/messages_ja_JP.properties: -------------------------------------------------------------------------------- 1 | Git.Perspective.perspectiveName=Git 2 | 3 | Dialog.Cancel=Cancel 4 | Dialog.Error=\u30A8\u30E9\u30FC 5 | Dialog.Ok=OK 6 | Dialog.Success=\u6210\u529F 7 | 8 | Git.Checkout=\u30C1\u30A7\u30C3\u30AF\u30A2\u30A6\u30C8 9 | Git.Config=\u8A2D\u5B9A 10 | Git.Repository=\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8 11 | Git.Directory=\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA 12 | Git.Pull=\u30D7\u30EB 13 | SVN.Pull=\u66F4\u65B0 14 | Git.Push=\u30D7\u30C3\u30B7\u30E5 15 | Git.Commit=\u30B3\u30DF\u30C3\u30C8 16 | Git.CommitMessage=\u30B3\u30DF\u30C3\u30C8\u30E1\u30C3\u30BB\u30FC\u30B8 17 | Git.Branch=\u30D6\u30E9\u30F3\u30C1 18 | Git.Tag=\u30BF\u30B0 19 | Git.Create=\u4F5C\u6210 20 | Git.Delete=\u524A\u9664 21 | Git.Merge=\u30DE\u30FC\u30B8 22 | Git.Author=\u4F5C\u8005 23 | Git.Remote=\u30EA\u30E2\u30FC\u30C8 24 | Git.Open=\u958B\u304F 25 | Git.Add=\u8FFD\u52A0 26 | Git.Edit=\u7DE8\u96C6 27 | Git.Remove=\u9664\u53BB 28 | Git.Clone=\u30AF\u30ED\u30FC\u30F3 29 | Git.StagedChanges=\u30B9\u30C6\u30FC\u30B8\u6E08\u307F\u306E\u5909\u66F4 30 | Git.UnstagedChangesAndUntrackedFiles=\u30B9\u30C6\u30FC\u30B8\u6E08\u307F\u3067\u306A\u3044\u5909\u66F4\u3068\u672A\u8FFD\u8DE1\u30D5\u30A1\u30A4\u30EB 31 | Git.ChangedFiles=\u5909\u66F4\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB 32 | Git.Refresh=\u66F4\u65B0 33 | 34 | Git.ContextMenu.AddToIndex=\u30B9\u30C6\u30FC\u30B8 35 | Git.ContextMenu.RemoveFromIndex=\u30A2\u30F3\u30B9\u30C6\u30FC\u30B8 36 | Git.ContextMenu.Checkout=\u30C1\u30A7\u30C3\u30AF\u30A2\u30A6\u30C8 37 | Git.ContextMenu.Reset=\u30EA\u30BB\u30C3\u30C8 38 | Git.ContextMenu.Discard=\u5909\u66F4\u3092\u7834\u68C4 39 | Git.ContextMenu.Open=\u958B\u304F 40 | Git.ContextMenu.VisualDiff=\u8996\u899A\u7684\u5DEE\u5206 41 | 42 | Git.ToolTip.Branch=\u30D6\u30E9\u30F3\u30C1\u3092\u4F5C\u6210\u53C8\u306F\u524A\u9664 43 | Git.ToolTip.Merge=\u73FE\u30D6\u30E9\u30F3\u30C1\u306B\u30DE\u30FC\u30B8 44 | 45 | Git.Dialog.Branch.Create.Title=\u30D6\u30E9\u30F3\u30C1\u306E\u4F5C\u6210 46 | Git.Dialog.Branch.Create.Message=\u4F5C\u6210\u3059\u308B\u30D6\u30E9\u30F3\u30C1 47 | Git.Dialog.Branch.Delete.Message=\u524A\u9664\u3059\u308B\u30D6\u30E9\u30F3\u30C1 48 | Git.Dialog.Branch.Merge.Message=\u73FE\u30D6\u30E9\u30F3\u30C1\u306B\u30DE\u30FC\u30B8\u3059\u308B\u30D6\u30E9\u30F3\u30C1 49 | Git.Dialog.Branch.Merge.MergeStrategy=\u30DE\u30FC\u30B8\u6226\u7565 50 | Git.Dialog.Force=\u5F37\u5236\uFF1F 51 | Git.Dialog.UncommittedChanges.Message=\u30B3\u30DF\u30C3\u30C8\u3057\u3066\u3044\u306A\u3044\u5909\u66F4\u304C\u3042\u308A\u307E\u3059 -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/xul/changed-table.xul: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/main/resources/org/pentaho/di/git/spoon/xul/git_perspective.xul: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |