├── .gitignore
├── images
├── diff.png
├── visualdiff.png
├── screenshot-1.png
└── screenshot-2.png
├── version.xml
├── src
├── main
│ ├── resources
│ │ └── org
│ │ │ └── pentaho
│ │ │ └── di
│ │ │ └── git
│ │ │ └── spoon
│ │ │ ├── images
│ │ │ ├── tag.png
│ │ │ ├── added.png
│ │ │ ├── branch.png
│ │ │ ├── pull.png
│ │ │ ├── push.png
│ │ │ ├── changed.png
│ │ │ ├── removed.png
│ │ │ ├── repository.png
│ │ │ ├── changed.svg
│ │ │ ├── branch.svg
│ │ │ ├── repository.svg
│ │ │ ├── tag.svg
│ │ │ ├── pull.svg
│ │ │ ├── push.svg
│ │ │ ├── removed.svg
│ │ │ └── added.svg
│ │ │ ├── xul
│ │ │ ├── git_spoon_overlays.xul
│ │ │ ├── changed-table.xul
│ │ │ ├── git_revision-table.xul
│ │ │ └── git_perspective.xul
│ │ │ └── messages
│ │ │ ├── messages_en_US.properties
│ │ │ └── messages_ja_JP.properties
│ └── java
│ │ └── org
│ │ └── pentaho
│ │ ├── ui
│ │ └── xul
│ │ │ └── util
│ │ │ └── XulDialogLambdaCallback.java
│ │ └── di
│ │ ├── ui
│ │ └── repository
│ │ │ └── pur
│ │ │ └── repositoryexplorer
│ │ │ └── model
│ │ │ ├── UIRepositoryObjectRevisions.java
│ │ │ └── UIRepositoryObjectRevision.java
│ │ ├── git
│ │ └── spoon
│ │ │ ├── model
│ │ │ ├── UIFile.java
│ │ │ ├── GitRepository.java
│ │ │ ├── IVCS.java
│ │ │ └── VCS.java
│ │ │ ├── GitSpoonPlugin.java
│ │ │ ├── dialog
│ │ │ ├── UsernamePasswordDialog.java
│ │ │ ├── CloneRepositoryDialog.java
│ │ │ ├── DeleteBranchDialog.java
│ │ │ ├── MergeBranchDialog.java
│ │ │ └── EditRepositoryDialog.java
│ │ │ ├── DrawDiffOnJobEntryExtensionPoint.java
│ │ │ ├── DrawDiffOnStepExtensionPoint.java
│ │ │ ├── PdiDiff.java
│ │ │ ├── GitPerspective.java
│ │ │ └── GitSpoonMenuController.java
│ │ └── repository
│ │ └── pur
│ │ └── PurObjectRevision.java
├── assembly
│ └── zip.xml
└── test
│ ├── java
│ └── org
│ │ └── pentaho
│ │ └── di
│ │ └── git
│ │ └── spoon
│ │ ├── model
│ │ ├── GitRepositoryTest.java
│ │ └── SVNTest.java
│ │ ├── GitSpoonMenuControllerTest.java
│ │ └── PdiDiffTest.java
│ └── resources
│ ├── r2.kjb
│ └── r1.kjb
├── .travis.yml
├── OSS_Licenses.md
├── pom.xml
├── CHANGELOG.md
├── LICENSE
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | .classpath
3 | .project
4 | .settings/
5 |
--------------------------------------------------------------------------------
/images/diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/HEAD/images/diff.png
--------------------------------------------------------------------------------
/images/visualdiff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/HEAD/images/visualdiff.png
--------------------------------------------------------------------------------
/images/screenshot-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/HEAD/images/screenshot-1.png
--------------------------------------------------------------------------------
/images/screenshot-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/HEAD/images/screenshot-2.png
--------------------------------------------------------------------------------
/version.xml:
--------------------------------------------------------------------------------
1 |
2 | 1.1.2-SNAPSHOT
3 |
--------------------------------------------------------------------------------
/src/main/resources/org/pentaho/di/git/spoon/images/tag.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/HEAD/src/main/resources/org/pentaho/di/git/spoon/images/tag.png
--------------------------------------------------------------------------------
/src/main/resources/org/pentaho/di/git/spoon/images/added.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/HEAD/src/main/resources/org/pentaho/di/git/spoon/images/added.png
--------------------------------------------------------------------------------
/src/main/resources/org/pentaho/di/git/spoon/images/branch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/HEAD/src/main/resources/org/pentaho/di/git/spoon/images/branch.png
--------------------------------------------------------------------------------
/src/main/resources/org/pentaho/di/git/spoon/images/pull.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/HEAD/src/main/resources/org/pentaho/di/git/spoon/images/pull.png
--------------------------------------------------------------------------------
/src/main/resources/org/pentaho/di/git/spoon/images/push.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/HEAD/src/main/resources/org/pentaho/di/git/spoon/images/push.png
--------------------------------------------------------------------------------
/src/main/resources/org/pentaho/di/git/spoon/images/changed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/HEAD/src/main/resources/org/pentaho/di/git/spoon/images/changed.png
--------------------------------------------------------------------------------
/src/main/resources/org/pentaho/di/git/spoon/images/removed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/HEAD/src/main/resources/org/pentaho/di/git/spoon/images/removed.png
--------------------------------------------------------------------------------
/src/main/resources/org/pentaho/di/git/spoon/images/repository.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HiromuHota/pdi-git-plugin/HEAD/src/main/resources/org/pentaho/di/git/spoon/images/repository.png
--------------------------------------------------------------------------------
/src/main/resources/org/pentaho/di/git/spoon/xul/git_spoon_overlays.xul:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
--------------------------------------------------------------------------------
/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_revision-table.xul:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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/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/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/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/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/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/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/test/java/org/pentaho/di/git/spoon/model/GitRepositoryTest.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.junit.Before;
20 | import org.junit.Test;
21 | import org.junit.runner.RunWith;
22 | import org.mockito.Spy;
23 | import org.mockito.runners.MockitoJUnitRunner;
24 | import org.pentaho.di.core.KettleClientEnvironment;
25 | import org.pentaho.di.core.exception.KettleException;
26 | import org.pentaho.di.core.variables.VariableSpace;
27 | import org.pentaho.di.core.variables.Variables;
28 | import org.pentaho.metastore.api.IMetaStore;
29 | import org.pentaho.metastore.api.exceptions.MetaStoreException;
30 | import org.pentaho.metastore.persist.MetaStoreFactory;
31 | import org.pentaho.metastore.stores.memory.MemoryMetaStore;
32 |
33 | import static org.junit.Assert.assertEquals;
34 | import static org.mockito.Mockito.when;
35 |
36 | @RunWith( MockitoJUnitRunner.class )
37 | public class GitRepositoryTest {
38 |
39 | public static final String NAMESPACE = "testnamespace";
40 | public static final String NAME = "test";
41 | public static final String DESCRIPTION = "test description";
42 | public static final String DIRECTORY = "/tmp/test";
43 |
44 | protected IMetaStore metaStore;
45 |
46 | @Spy
47 | protected GitRepository repo;
48 |
49 | @Before
50 | public void setUp() throws KettleException {
51 | KettleClientEnvironment.init();
52 | metaStore = new MemoryMetaStore();
53 |
54 | repo.setName( NAME );
55 | repo.setDescription( DESCRIPTION );
56 | repo.setDirectory( DIRECTORY );
57 | }
58 |
59 | @Test
60 | public void testSerialisation() throws MetaStoreException {
61 | MetaStoreFactory repoFactory = new MetaStoreFactory( GitRepository.class, metaStore, NAMESPACE );
62 | repoFactory.saveElement( repo );
63 |
64 | GitRepository verify = repoFactory.loadElement( NAME );
65 | assertEquals( NAME, verify.getName() );
66 | assertEquals( DESCRIPTION, verify.getDescription() );
67 | assertEquals( DIRECTORY, verify.getDirectory() );
68 | }
69 |
70 | @Test
71 | public void testVariableSubstitution() {
72 | VariableSpace space = new Variables();
73 | space.initializeVariablesFrom( null );
74 | space.setVariable( "KETTLE_HOME", DIRECTORY );
75 | when( repo.getVariables() ).thenReturn( space );
76 | repo.setDirectory( "${KETTLE_HOME}" );
77 |
78 | assertEquals( DIRECTORY, repo.getPhysicalDirectory() );
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/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/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/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/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/test/java/org/pentaho/di/git/spoon/GitSpoonMenuControllerTest.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.mockito.Mockito.*;
20 |
21 | import org.eclipse.jface.window.Window;
22 | import org.eclipse.jgit.junit.RepositoryTestCase;
23 | import org.junit.Before;
24 | import org.junit.Rule;
25 | import org.junit.Test;
26 | import org.junit.rules.TemporaryFolder;
27 | import org.junit.runner.RunWith;
28 | import org.mockito.Mock;
29 | import org.mockito.runners.MockitoJUnitRunner;
30 | import org.mockito.Spy;
31 | import org.pentaho.di.git.spoon.dialog.CloneRepositoryDialog;
32 | import org.pentaho.di.git.spoon.dialog.UsernamePasswordDialog;
33 | import org.pentaho.di.git.spoon.model.GitRepository;
34 | import org.pentaho.di.git.spoon.model.UIGit;
35 |
36 | @RunWith( MockitoJUnitRunner.class )
37 | public class GitSpoonMenuControllerTest extends RepositoryTestCase {
38 |
39 | @Spy
40 | private GitSpoonMenuController controller;
41 | @Mock
42 | private CloneRepositoryDialog cloneRepositoryDialog;
43 | @Mock
44 | private UsernamePasswordDialog usernamePasswordDialog;
45 | @Mock
46 | private GitRepository repo;
47 | @Mock
48 | private GitController gitController;
49 | @Mock
50 | private UIGit git;
51 |
52 | @Rule
53 | public TemporaryFolder dstFolder = new TemporaryFolder();
54 |
55 | @Before
56 | public void setUp() throws Exception {
57 | super.setUp();
58 | controller.setGitController( gitController );
59 | doReturn( cloneRepositoryDialog ).when( controller ).getCloneRepositoryDialog( any( GitRepository.class ) );
60 | doReturn( usernamePasswordDialog ).when( controller ).getUsernamePasswordDialog();
61 | doReturn( null ).when( controller ).getShell();
62 | doReturn( git ).when( controller ).getVCS( any( GitRepository.class ) );
63 | doNothing().when( controller ).saveRepository( any( GitRepository.class ) );
64 | doNothing().when( controller ).showMessageBox( anyString(), anyString() );
65 | }
66 |
67 | @Test
68 | public void testShouldNotCloneOnCancel() throws Exception {
69 | when( cloneRepositoryDialog.open() ).thenReturn( Window.CANCEL );
70 |
71 | controller.cloneRepo();
72 |
73 | verify( cloneRepositoryDialog, never() ).getDirectory();
74 | }
75 |
76 | @Test
77 | public void testCloneShouldSucceed() throws Exception {
78 | when( cloneRepositoryDialog.open() ).thenReturn( Window.OK );
79 | when( cloneRepositoryDialog.getURL() ).thenReturn( db.getDirectory().getPath() );
80 | when( cloneRepositoryDialog.getGitRepository() ).thenReturn( repo );
81 | when( repo.getPhysicalDirectory() ).thenReturn( dstFolder.getRoot().getPath() );
82 | doReturn( true ).when( git ).cloneRepo( anyString(), anyString() );
83 |
84 | controller.cloneRepo();
85 |
86 | verify( controller ).showMessageBox( eq( "Success" ), anyString() );
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/test/java/org/pentaho/di/git/spoon/PdiDiffTest.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.junit.Assert.*;
20 | import static org.pentaho.di.git.spoon.PdiDiff.*;
21 |
22 | import java.io.File;
23 | import java.io.FileInputStream;
24 | import java.io.InputStream;
25 |
26 | import org.junit.Before;
27 | import org.junit.Test;
28 | import org.pentaho.di.core.KettleClientEnvironment;
29 | import org.pentaho.di.core.KettleEnvironment;
30 | import org.pentaho.di.core.exception.KettleException;
31 | import org.pentaho.di.job.JobMeta;
32 | import org.pentaho.di.trans.TransMeta;
33 |
34 | public class PdiDiffTest {
35 |
36 | @Before
37 | public void setUp() throws KettleException {
38 | KettleClientEnvironment.getInstance().setClient( KettleClientEnvironment.ClientType.CARTE );
39 | KettleEnvironment.init();
40 | }
41 |
42 | @Test
43 | public void diffTransTest() throws Exception {
44 | File file = new File( "src/test/resources/r1.ktr" );
45 | InputStream xmlStream = new FileInputStream( file );
46 | TransMeta transMeta = new TransMeta( xmlStream, null, true, null, null );
47 | transMeta.sortSteps();
48 |
49 | File file2 = new File( "src/test/resources/r2.ktr" );
50 | InputStream xmlStream2 = new FileInputStream( file2 );
51 | TransMeta transMeta2 = new TransMeta( xmlStream2, null, true, null, null );
52 | transMeta2.sortSteps();
53 |
54 | transMeta = compareSteps( transMeta, transMeta2, true );
55 | transMeta2 = compareSteps( transMeta2, transMeta, false );
56 | assertEquals( UNCHANGED, transMeta.getStep( 0 ).getAttribute( ATTR_GIT, ATTR_STATUS ) );
57 | assertEquals( CHANGED, transMeta.getStep( 1 ).getAttribute( ATTR_GIT, ATTR_STATUS ) );
58 | assertEquals( REMOVED, transMeta.getStep( 2 ).getAttribute( ATTR_GIT, ATTR_STATUS ) );
59 | assertEquals( ADDED, transMeta2.getStep( 2 ).getAttribute( ATTR_GIT, ATTR_STATUS ) );
60 | }
61 |
62 | @Test
63 | public void diffJobEntryTest() throws Exception {
64 | File file = new File( "src/test/resources/r1.kjb" );
65 | InputStream xmlStream = new FileInputStream( file );
66 | JobMeta jobMeta = new JobMeta( xmlStream, null, null );
67 |
68 | File file2 = new File( "src/test/resources/r2.kjb" );
69 | InputStream xmlStream2 = new FileInputStream( file2 );
70 | JobMeta jobMeta2 = new JobMeta( xmlStream2, null, null );
71 |
72 | jobMeta = compareJobEntries( jobMeta, jobMeta2, true );
73 | jobMeta2 = compareJobEntries( jobMeta2, jobMeta, false );
74 | assertEquals( CHANGED, jobMeta.getJobEntry( 0 ).getAttribute( ATTR_GIT, ATTR_STATUS ) );
75 | assertEquals( UNCHANGED, jobMeta.getJobEntry( 1 ).getAttribute( ATTR_GIT, ATTR_STATUS ) );
76 | assertEquals( REMOVED, jobMeta.getJobEntry( 2 ).getAttribute( ATTR_GIT, ATTR_STATUS ) );
77 | assertEquals( ADDED, jobMeta2.getJobEntry( 2 ).getAttribute( ATTR_GIT, ATTR_STATUS ) );
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/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/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/resources/org/pentaho/di/git/spoon/images/changed.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
55 |
58 |
65 |
71 |
78 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/src/main/resources/org/pentaho/di/git/spoon/images/branch.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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/main/resources/org/pentaho/di/git/spoon/images/repository.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/main/resources/org/pentaho/di/git/spoon/images/tag.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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/resources/org/pentaho/di/git/spoon/images/pull.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/src/main/resources/org/pentaho/di/git/spoon/images/push.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/main/resources/org/pentaho/di/git/spoon/images/removed.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/main/resources/org/pentaho/di/git/spoon/images/added.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/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/test/java/org/pentaho/di/git/spoon/model/SVNTest.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 static org.junit.Assert.*;
20 | import static org.mockito.Mockito.*;
21 |
22 | import java.io.File;
23 | import java.io.InputStream;
24 | import java.io.StringWriter;
25 | import java.util.List;
26 |
27 | import org.apache.commons.io.FileUtils;
28 | import org.apache.commons.io.IOUtils;
29 | import org.apache.subversion.javahl.ISVNRepos;
30 | import org.apache.subversion.javahl.SVNRepos;
31 | import org.eclipse.jgit.diff.DiffEntry.ChangeType;
32 | import org.eclipse.jgit.lib.Constants;
33 | import org.junit.After;
34 | import org.junit.Before;
35 | import org.junit.Test;
36 | import org.pentaho.di.i18n.BaseMessages;
37 | import org.pentaho.di.ui.repository.pur.repositoryexplorer.model.UIRepositoryObjectRevisions;
38 |
39 | public class SVNTest {
40 | private VCS vcs;
41 | private ISVNRepos admin;
42 | private File rootServer;
43 | private File rootClient;
44 | private String diff;
45 |
46 | @Before
47 | public void setUp() throws Exception {
48 | // Set up a central remote repository
49 | rootServer = File.createTempFile( "svn_test_", "_server" );
50 | rootServer.delete();
51 | rootServer.mkdirs();
52 | admin = new SVNRepos();
53 | admin.create( rootServer, true, false, null, ISVNRepos.FSFS );
54 |
55 | rootClient = File.createTempFile( "svn_test_", "_client" );
56 | rootClient.delete();
57 | vcs = spy( new SVN() );
58 | doNothing().when( vcs ).showMessageBox( anyString(), anyString() );
59 | vcs.cloneRepo( rootClient.getPath(), "file://" + rootServer.getPath() );
60 | vcs.openRepo( rootClient.getPath() );
61 | }
62 |
63 | @After
64 | public void tearDown() throws Exception {
65 | admin.dispose();
66 | FileUtils.deleteDirectory( rootServer );
67 | FileUtils.deleteDirectory( rootClient );
68 | }
69 |
70 | @Test
71 | public void testCommit() throws Exception {
72 | UIRepositoryObjectRevisions revisions = vcs.getRevisions();
73 | File file = new File( rootClient.getPath(), "test.txt" );
74 | FileUtils.write( file, "Hello World" );
75 | diff = vcs.diff( IVCS.INDEX, IVCS.WORKINGTREE, "test.txt" );
76 | assertEquals( "Unversioned", diff );
77 |
78 | vcs.add( "test.txt" );
79 | diff = vcs.diff( Constants.HEAD, IVCS.INDEX, "test.txt" );
80 | assertTrue( diff.contains( "nonexistent" ) );
81 | assertEquals( vcs.getRevisions().size(), revisions.size() + 1 );
82 | revisions = vcs.getRevisions();
83 | assertEquals( VCS.WORKINGTREE, revisions.get( 0 ).getName() );
84 |
85 | vcs.resetPath( "test.txt" );
86 | vcs.add( "test.txt" );
87 |
88 | vcs.commit( "user", "message" );
89 | vcs.pull();
90 | assertEquals( revisions.size(), vcs.getRevisions().size() );
91 | revisions = vcs.getRevisions();
92 | assertEquals( "1", revisions.get( 0 ).getName() );
93 | assertEquals( "message", vcs.getCommitMessage( "1" ) );
94 |
95 | List files = vcs.getStagedFiles( "0", "1" );
96 | assertEquals( "test.txt", files.get( 0 ).getName() );
97 |
98 | InputStream inputStream = vcs.open( "test.txt", "1" );
99 | StringWriter writer = new StringWriter();
100 | IOUtils.copy( inputStream, writer, "UTF-8" );
101 | assertEquals( "Hello World", writer.toString() );
102 |
103 | inputStream = vcs.open( "test.txt", Constants.HEAD );
104 | writer = new StringWriter();
105 | IOUtils.copy( inputStream, writer, "UTF-8" );
106 | assertEquals( "Hello World", writer.toString() );
107 |
108 | inputStream = vcs.open( "test.txt", IVCS.WORKINGTREE );
109 | writer = new StringWriter();
110 | IOUtils.copy( inputStream, writer, "UTF-8" );
111 | assertEquals( "Hello World", writer.toString() );
112 |
113 | diff = vcs.diff( "0", "1", "test.txt" );
114 | assertTrue( diff.contains( "+Hello World" ) );
115 |
116 | // Test Update to a past commit
117 | File file2 = new File( rootClient.getPath(), "test2.txt" );
118 | FileUtils.write( file2, "Hello World" );
119 | vcs.add( "test2.txt" );
120 | vcs.commit( "user", "message2" );
121 | vcs.pull();
122 | assertEquals( "2", vcs.getRevisions().get( 0 ).getName() );
123 | vcs.checkout( "1" );
124 | assertEquals( "1", vcs.getRevisions().get( 0 ).getName() );
125 |
126 | // Test rm
127 | vcs.pull();
128 | file.delete();
129 | vcs.rm( "test.txt" );
130 | vcs.commit( "user", "Removed test.txt" );
131 | files = vcs.getStagedFiles( "2", "3" );
132 | assertEquals( "test.txt", files.get( 0 ).getName() );
133 |
134 | // Test revert
135 | file2.delete();
136 | assertFalse( file2.exists() );
137 | vcs.revertPath( file2.getName() );
138 | assertTrue( file2.exists() );
139 | }
140 |
141 | @Test
142 | public void testPull() throws Exception {
143 | vcs.pull();
144 | }
145 |
146 | @Test
147 | public void testGetRemote() {
148 | String remote = vcs.getRemote();
149 | assertNotNull( remote );
150 | }
151 |
152 | @Test
153 | public void testGetUnStagedFiles() throws Exception {
154 | List files;
155 | // Create a new file
156 | File file = new File( rootClient.getPath(), "test.txt" );
157 | FileUtils.write( file, "Hello World" );
158 |
159 | File dir = new File( rootClient.getPath(), "folder" );
160 | dir.mkdir();
161 |
162 | // New file should be listed in the list of unstaged files
163 | files = vcs.getUnstagedFiles();
164 | assertTrue( files.stream().anyMatch( f -> f.getName().equals( "test.txt" ) && f.getChangeType() == ChangeType.ADD ) );
165 | assertTrue( files.stream().anyMatch( f -> f.getName().equals( "folder" ) && f.getChangeType() == ChangeType.ADD ) );
166 |
167 | // First commit
168 | vcs.add( "test.txt" );
169 | vcs.commit( "user", "message" );
170 |
171 | // Test if delete files are listed in the list of staged files
172 | file.delete();
173 | files = vcs.getUnstagedFiles();
174 | assertTrue( files.stream().anyMatch( f -> f.getName().equals( "test.txt" ) && f.getChangeType() == ChangeType.DELETE ) );
175 | }
176 |
177 | @Test
178 | public void testCreateDeleteBranchTag() throws Exception {
179 | vcs.createBranch( "trunk" );
180 | vcs.checkoutBranch( "trunk" );
181 | assertEquals( "trunk", vcs.getBranch() );
182 |
183 | vcs.createBranch( "branches/branch1" );
184 | assertTrue( vcs.getBranches().contains( "branches/branch1" ) );
185 |
186 | vcs.deleteBranch( "branches/branch1", false );
187 | assertFalse( vcs.getBranches().contains( "branches/branch1" ) );
188 |
189 | vcs.createTag( "tags/tag1" );
190 | assertTrue( vcs.getTags().contains( "tags/tag1" ) );
191 |
192 | vcs.deleteTag( "tags/tag1" );
193 | assertFalse( vcs.getTags().contains( "tags/tag1" ) );
194 |
195 | // Create a new file
196 | File file = new File( rootClient.getPath(), "test.txt" );
197 | FileUtils.write( file, "Hello World" );
198 | vcs.add( "test.txt" );
199 | vcs.createBranch( "branches/branch2" );
200 | vcs.createTag( "tags/tag2" );
201 | verify( vcs, times( 2 ) ).showMessageBox( anyString(), anyString() );
202 | assertFalse( vcs.getBranches().contains( "branches/branch2" ) );
203 | assertFalse( vcs.getTags().contains( "tags/tag2" ) );
204 | }
205 |
206 | @Test
207 | public void testInvalidRepoShouldInvokeError() throws Exception {
208 | vcs.getBranch();
209 | verify( vcs, never() ).showMessageBox( BaseMessages.getString( vcs.PKG, "Dialog.Error"),
210 | BaseMessages.getString( vcs.PKG, "SVN.InvalidRepository" ) );
211 |
212 | FileUtils.deleteDirectory( rootClient );
213 | vcs.getBranch();
214 | verify( vcs ).showMessageBox( BaseMessages.getString( vcs.PKG, "Dialog.Error"),
215 | BaseMessages.getString( vcs.PKG, "SVN.InvalidRepository" ) );
216 | }
217 | }
218 |
--------------------------------------------------------------------------------
/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