├── Jenkinsfile
├── src
├── main
│ ├── resources
│ │ ├── org
│ │ │ └── jenkinsci
│ │ │ │ └── plugins
│ │ │ │ └── all_changes
│ │ │ │ ├── AllChangesPortlet
│ │ │ │ ├── help-name.html
│ │ │ │ ├── help-jenkinsJobName.html
│ │ │ │ ├── help-numChanges.html
│ │ │ │ ├── portlet.jelly
│ │ │ │ └── config.groovy
│ │ │ │ ├── Messages_de.properties
│ │ │ │ ├── Messages.properties
│ │ │ │ ├── Messages_es.properties
│ │ │ │ ├── AllChangesAction
│ │ │ │ ├── index.properties
│ │ │ │ ├── index_de.properties
│ │ │ │ ├── index_es.properties
│ │ │ │ ├── index.groovy
│ │ │ │ └── main.groovy
│ │ │ │ └── AllChangesWorkflowAction
│ │ │ │ ├── index.properties
│ │ │ │ ├── index_de.properties
│ │ │ │ ├── index_es.properties
│ │ │ │ ├── index.groovy
│ │ │ │ └── main.groovy
│ │ └── index.jelly
│ └── java
│ │ └── org
│ │ └── jenkinsci
│ │ └── plugins
│ │ └── all_changes
│ │ ├── Util.java
│ │ ├── ChangesAggregator.java
│ │ ├── AllChanges.java
│ │ ├── AllChangesWorkflow.java
│ │ ├── DependencyChangesAggregator.java
│ │ ├── AllChangesPortlet.java
│ │ ├── AllChangesWorkflowAction.java
│ │ ├── SubProjectChangesAggregator.java
│ │ └── AllChangesAction.java
└── test
│ └── java
│ └── org
│ └── jenkinsci
│ └── plugins
│ └── all_changes
│ └── AllChangesActionTest.java
├── .gitignore
├── README.markdown
└── pom.xml
/Jenkinsfile:
--------------------------------------------------------------------------------
1 | buildPlugin()
2 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/all_changes/AllChangesPortlet/help-name.html:
--------------------------------------------------------------------------------
1 |
2 | Name of the portlet.
3 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/all_changes/AllChangesPortlet/help-jenkinsJobName.html:
--------------------------------------------------------------------------------
1 |
2 | Jenkins Job Name of which the latest changes should be shown.
3 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/all_changes/AllChangesPortlet/help-numChanges.html:
--------------------------------------------------------------------------------
1 |
2 | Number of displayable changes within the portlet (defaults to 10).
3 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/all_changes/Messages_de.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenkinsci/all-changes-plugin/master/src/main/resources/org/jenkinsci/plugins/all_changes/Messages_de.properties
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Mac OS X files
2 | .DS_Store
3 |
4 | # Intellij files
5 | *.iml
6 | .idea/*
7 | classes
8 |
9 | # Maven
10 | target/*
11 | pom.xml.releaseBackup
12 | release.properties
13 |
14 | # Jenkins workplace files
15 | work*
16 |
17 | # Gradle
18 | .gradle
19 | build
20 | libsrc/*
21 |
22 | # Eclipse
23 | /.classpath
24 | /.project
25 | /.settings*
26 | /target/
--------------------------------------------------------------------------------
/README.markdown:
--------------------------------------------------------------------------------
1 | All Changes Plugin
2 | =======================
3 |
4 | Shows all changes which influenced the build.
5 |
6 | Features
7 | --------
8 | - Shows changes by dependent builds (via fingerprinting)
9 | - Shows changes by subprojects added via a BuildStep from the [parameterized-trigger-plugin](https://github.com/jenkinsci/parameterized-trigger-plugin)
10 |
11 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/all_changes/Messages.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2011, Stefan Wolf
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 | #
24 |
25 | AllChanges.allChanges=All Changes
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/all_changes/Messages_es.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2011, Stefan Wolf
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 | #
24 |
25 | AllChanges.allChanges=Todos los cambios
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/all_changes/AllChangesAction/index.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2011, Stefan Wolf
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 | #
24 |
25 | all.changes.title={0} All Changes
26 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/all_changes/AllChangesWorkflowAction/index.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2011, Stefan Wolf
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 | #
24 |
25 | all.changes.title={0} All Changes
26 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/all_changes/AllChangesPortlet/portlet.jelly:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | ${'Job with name '+ it.jenkinsJobName +' is not available.'}
18 |
19 |
20 |
21 | |
22 |
23 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/all_changes/AllChangesAction/index_de.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2011, Stefan Wolf
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 | #
24 |
25 | all.changes.title=Alle \u00c4nderungen in {0}
26 | detail=Details
27 | All\ Changes=Alle \u00c4nderungen
28 | No\ builds.=Keine Builds.
29 | No\ changes\ in\ any\ of\ the\ builds.=Keine \u00c4nderungen in den Builds.
30 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/all_changes/AllChangesAction/index_es.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2011, Stefan Wolf
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 | #
24 |
25 | all.changes.title=Todos los cambios de {0}
26 | All\ Changes=Todos los cambios
27 | No\ builds.=Sin ejecuciones.
28 | detail=detalles
29 | No\ changes\ in\ any\ of\ the\ builds.=No hay nuevos cambios en ninguna ejecuci\u00f3n.
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/all_changes/AllChangesWorkflowAction/index_de.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2011, Stefan Wolf
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 | #
24 |
25 | all.changes.title=Alle \u00c4nderungen in {0}
26 | detail=Details
27 | All\ Changes=Alle \u00c4nderungen
28 | No\ builds.=Keine Builds.
29 | No\ changes\ in\ any\ of\ the\ builds.=Keine \u00c4nderungen in den Builds.
30 |
--------------------------------------------------------------------------------
/src/main/resources/index.jelly:
--------------------------------------------------------------------------------
1 |
24 |
25 |
28 |
29 |
30 | This plugin shows all changes (also from dependent projects, sub-projects, ...) for a project
31 |
32 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/all_changes/AllChangesWorkflowAction/index_es.properties:
--------------------------------------------------------------------------------
1 | #
2 | # The MIT License
3 | #
4 | # Copyright (c) 2011, Stefan Wolf
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 | #
24 |
25 | all.changes.title=Todos los cambios de {0}
26 | All\ Changes=Todos los cambios
27 | No\ builds.=Sin ejecuciones.
28 | detail=detalles
29 | No\ changes\ in\ any\ of\ the\ builds.=No hay nuevos cambios en ninguna ejecuci\u00f3n.
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/all_changes/AllChangesPortlet/config.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2016, Suresh
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package org.jenkinsci.plugins.all_changes.AllChangesPortlet
26 |
27 | f = namespace(lib.FormTagLib)
28 | t = namespace("/lib/hudson")
29 |
30 |
31 | f.entry(field:"name", title: "Name") {
32 | f.textbox()
33 | }
34 |
35 | f.entry(field:"jenkinsJobName", title: "Job Name") {
36 | f.textbox()
37 | }
38 |
39 | f.entry(field:"numChanges", title: "Number of changes to show") {
40 | f.number(default: 10, clazz:"required number")
41 | }
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/all_changes/Util.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2016, Suresh
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.jenkinsci.plugins.all_changes;
25 |
26 | import jenkins.model.Jenkins;
27 |
28 | /**
29 | * Created by suresh on 6/5/2016.
30 | */
31 | public class Util {
32 |
33 | public static Jenkins getInstance() {
34 | Jenkins instance = Jenkins.getInstance();
35 | if (instance == null) {
36 | throw new IllegalStateException("Jenkins has not been started, or was already shut down");
37 | }
38 | return instance;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/all_changes/ChangesAggregator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2011, Stefan Wolf
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package org.jenkinsci.plugins.all_changes;
26 |
27 | import hudson.ExtensionList;
28 | import hudson.ExtensionPoint;
29 | import hudson.model.AbstractBuild;
30 | import jenkins.model.Jenkins;
31 |
32 | import java.util.Collection;
33 |
34 | public abstract class ChangesAggregator implements ExtensionPoint {
35 | public abstract Collection aggregateBuildsWithChanges(AbstractBuild build);
36 |
37 | public static ExtensionList all() {
38 | return Util.getInstance().getExtensionList(ChangesAggregator.class);
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/all_changes/AllChanges.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2011, Stefan Wolf
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package org.jenkinsci.plugins.all_changes;
26 |
27 | import hudson.Extension;
28 | import hudson.model.AbstractProject;
29 | import hudson.model.Action;
30 | import hudson.model.TransientProjectActionFactory;
31 |
32 | import java.util.Collection;
33 | import java.util.Collections;
34 |
35 | /**
36 | * @author wolfs
37 | */
38 | @Extension
39 | public class AllChanges extends TransientProjectActionFactory {
40 | @Override
41 | public Collection extends Action> createFor(AbstractProject target) {
42 | return Collections.singleton(new AllChangesAction(target));
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/all_changes/AllChangesWorkflow.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2017, Suresh
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package org.jenkinsci.plugins.all_changes;
26 |
27 | import hudson.Extension;
28 | import hudson.model.Action;
29 | import jenkins.model.TransientActionFactory;
30 | import org.jenkinsci.plugins.workflow.job.WorkflowJob;
31 |
32 | import java.util.Collection;
33 | import java.util.Collections;
34 |
35 | @Extension
36 | public class AllChangesWorkflow extends TransientActionFactory {
37 |
38 | @Override
39 | public Class type() {
40 | return WorkflowJob.class;
41 | }
42 |
43 | @Override
44 | public Collection extends Action> createFor(WorkflowJob target) {
45 | return Collections.singleton(new AllChangesWorkflowAction(target));
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/all_changes/AllChangesWorkflowAction/index.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2017, Suresh
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package org.jenkinsci.plugins.all_changes.AllChangesWorkflowAction
26 |
27 | import com.google.common.collect.Multimap
28 | import hudson.Functions
29 | import hudson.scm.ChangeLogSet
30 | import org.jenkinsci.plugins.workflow.job.WorkflowRun
31 |
32 | import java.text.DateFormat
33 | import org.jvnet.localizer.LocaleProvider
34 |
35 | f = namespace(lib.FormTagLib)
36 | l = namespace(lib.LayoutTagLib)
37 | t = namespace("/lib/hudson")
38 | st = namespace("jelly:stapler")
39 |
40 | l.layout(title: _("all.changes.title", my.project.name)) {
41 | st.include(page: "sidepanel.jelly", it: my.project)
42 | l.main_panel() {
43 | h1(_("All Changes"))
44 | st.include(page: "main.groovy", it: my)
45 | }
46 | }
47 |
48 |
49 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/all_changes/AllChangesAction/index.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2011, Stefan Wolf
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package org.jenkinsci.plugins.all_changes.AllChangesAction
26 |
27 | import com.google.common.collect.Multimap
28 | import hudson.Functions
29 | import hudson.model.AbstractBuild
30 | import hudson.model.AbstractBuild.DependencyChange
31 | import hudson.scm.ChangeLogSet
32 | import java.text.DateFormat
33 | import org.jvnet.localizer.LocaleProvider
34 |
35 | f = namespace(lib.FormTagLib)
36 | l = namespace(lib.LayoutTagLib)
37 | t = namespace("/lib/hudson")
38 | st = namespace("jelly:stapler")
39 |
40 | l.layout(title: _("all.changes.title", my.project.name)) {
41 | st.include(page: "sidepanel.jelly", it: my.project)
42 | l.main_panel() {
43 | h1(_("All Changes"))
44 | st.include(page: "main.groovy", it: my)
45 | }
46 | }
47 |
48 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/all_changes/DependencyChangesAggregator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2011, Stefan Wolf
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package org.jenkinsci.plugins.all_changes;
26 |
27 | import com.google.common.collect.ImmutableList;
28 | import hudson.Extension;
29 | import hudson.model.AbstractBuild;
30 | import hudson.model.AbstractProject;
31 |
32 | import java.util.Collection;
33 | import java.util.Map;
34 |
35 | /**
36 | * @author wolfs
37 | */
38 | @Extension
39 | public class DependencyChangesAggregator extends ChangesAggregator {
40 | @Override
41 | public Collection aggregateBuildsWithChanges(AbstractBuild build) {
42 | ImmutableList.Builder builder = ImmutableList.builder();
43 | Map depChanges = build.getDependencyChanges((AbstractBuild) build.getPreviousBuild());
44 | for (AbstractBuild.DependencyChange depChange : depChanges.values()) {
45 | builder.addAll(depChange.getBuilds());
46 | }
47 | return builder.build();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/all_changes/AllChangesPortlet.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2016, Suresh
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package org.jenkinsci.plugins.all_changes;
26 |
27 | import com.google.common.collect.ArrayListMultimap;
28 | import com.google.common.collect.HashMultimap;
29 | import com.google.common.collect.ImmutableList;
30 | import com.google.common.collect.Multimap;
31 | import com.google.common.collect.Sets;
32 | import hudson.Extension;
33 | import hudson.model.AbstractBuild;
34 | import hudson.model.AbstractProject;
35 | import hudson.model.Descriptor;
36 | import hudson.plugins.view.dashboard.DashboardPortlet;
37 | import hudson.scm.ChangeLogSet;
38 | import org.jenkinsci.plugins.workflow.job.WorkflowJob;
39 | import org.kohsuke.stapler.DataBoundConstructor;
40 |
41 | import java.util.List;
42 | import java.util.Set;
43 |
44 | /**
45 | * Portlet to calculate all changes for a build
46 | * It uses ChangesAggregators to do so.
47 | *
48 | * @author suresh
49 | */
50 | public class AllChangesPortlet extends DashboardPortlet {
51 |
52 | private final String jenkinsJobName;
53 | private final int numChanges;
54 |
55 | @DataBoundConstructor
56 | public AllChangesPortlet(String name, String jenkinsJobName, int numChanges) {
57 | super(name);
58 | this.jenkinsJobName = jenkinsJobName;
59 | this.numChanges = numChanges;
60 | }
61 |
62 | public String getJenkinsJobName() {
63 | return jenkinsJobName;
64 | }
65 |
66 | public String getJenkinsJobNameForUrl() {
67 | return jenkinsJobName == null ? "" : jenkinsJobName.replace(" ", "%20");
68 | }
69 |
70 | public int getNumChanges() {
71 | return numChanges;
72 | }
73 |
74 | public Object getProjectAction() {
75 | return resolveProject(jenkinsJobName);
76 | }
77 |
78 | private Object resolveProject(String name) {
79 | Object project = Util.getInstance().getItem(name, Util.getInstance(), AbstractProject.class);
80 | if (project == null) {
81 | project = Util.getInstance().getItem(name, Util.getInstance(), WorkflowJob.class);
82 | }
83 | if (project instanceof AbstractProject) {
84 | return new AllChangesAction((AbstractProject) project, this.numChanges);
85 | } else if (project instanceof WorkflowJob) {
86 | return new AllChangesWorkflowAction((WorkflowJob) project, this.numChanges);
87 | }
88 | return null;
89 | }
90 |
91 | @Extension
92 | public static class AllChangesPortletDescriptor extends Descriptor {
93 |
94 | @Override
95 | public String getDisplayName() {
96 | return "All Changes Portlet";
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/all_changes/AllChangesWorkflowAction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2017, Suresh
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package org.jenkinsci.plugins.all_changes;
26 |
27 | import com.google.common.collect.ArrayListMultimap;
28 | import com.google.common.collect.HashMultimap;
29 | import com.google.common.collect.ImmutableList;
30 | import com.google.common.collect.Multimap;
31 | import com.google.common.collect.Sets;
32 | import hudson.model.Action;
33 | import hudson.scm.ChangeLogSet;
34 | import org.jenkinsci.plugins.workflow.job.WorkflowJob;
35 | import org.jenkinsci.plugins.workflow.job.WorkflowRun;
36 |
37 | import java.util.Set;
38 |
39 | public class AllChangesWorkflowAction implements Action {
40 |
41 | private WorkflowJob project;
42 | private int numChanges = 0;
43 |
44 | AllChangesWorkflowAction(WorkflowJob project) {
45 | this.project = project;
46 | }
47 |
48 | AllChangesWorkflowAction(WorkflowJob project, int numChanges) {
49 | this.project = project;
50 | this.numChanges = numChanges;
51 | }
52 |
53 | public String getIconFileName() {
54 | return "notepad.png";
55 | }
56 |
57 | public String getDisplayName() {
58 | return Messages.AllChanges_allChanges();
59 | }
60 |
61 | public String getUrlName() {
62 | return "all-changes";
63 | }
64 |
65 | /**
66 | * Returns all changes which contribute to a build.
67 | *
68 | * @param build
69 | * @return
70 | */
71 | public Multimap getAllChanges(WorkflowRun build) {
72 | Set builds = getContributingBuilds(build);
73 | Multimap changes = ArrayListMultimap.create();
74 | for (WorkflowRun changedBuild : builds) {
75 | for (ChangeLogSet changeLogSet : changedBuild.getChangeSets()) {
76 | ChangeLogSet changeSet = (ChangeLogSet)changeLogSet;
77 | for (ChangeLogSet.Entry entry : changeSet) {
78 | changes.put(entry.getCommitId() + entry.getMsgAnnotated() + entry.getTimestamp(), entry);
79 | }
80 | }
81 | }
82 | Multimap change2Build = HashMultimap.create();
83 | for (String changeKey : changes.keySet()) {
84 | ChangeLogSet.Entry change = changes.get(changeKey).iterator().next();
85 | for (ChangeLogSet.Entry entry : changes.get(changeKey)) {
86 | change2Build.put(change, (WorkflowRun) entry.getParent().getRun());
87 | }
88 | }
89 | return change2Build;
90 | }
91 |
92 | /**
93 | * Uses all ChangesAggregators to calculate the contributing builds
94 | *
95 | * @return all changes which contribute to the given build
96 | */
97 | public Set getContributingBuilds(WorkflowRun build) {
98 | Set builds = Sets.newHashSet();
99 | builds.add(build);
100 | return builds;
101 | }
102 |
103 | public WorkflowJob getProject() {
104 | return project;
105 | }
106 |
107 | public int getNumChanges() {
108 | return numChanges;
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/test/java/org/jenkinsci/plugins/all_changes/AllChangesActionTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2011, Stefan Wolf
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package org.jenkinsci.plugins.all_changes;
26 |
27 | import com.google.common.collect.ImmutableList;
28 | import com.google.common.collect.ImmutableSet;
29 | import com.google.common.collect.Lists;
30 | import hudson.model.AbstractBuild;
31 | import org.junit.Test;
32 |
33 | import java.util.Set;
34 |
35 | import static org.junit.Assert.assertTrue;
36 | import static org.mockito.Mockito.*;
37 |
38 | /**
39 | * @author wolfs
40 | */
41 | public class AllChangesActionTest {
42 |
43 | @Test
44 | public void getContributingBuildsShouldWorkTransitively() throws Exception {
45 | AllChangesAction changesAction = new AllChangesAction(null);
46 | ChangesAggregator aggregatorMock = mock(ChangesAggregator.class);
47 | AbstractBuild build = mock(AbstractBuild.class);
48 | AbstractBuild build2 = mock(AbstractBuild.class);
49 | AbstractBuild build3 = mock(AbstractBuild.class);
50 | when(aggregatorMock.aggregateBuildsWithChanges(build)).thenReturn(ImmutableList.of(build2));
51 | when(aggregatorMock.aggregateBuildsWithChanges(build2)).thenReturn(ImmutableList.of(build3));
52 |
53 | changesAction.aggregators = Lists.newArrayList(aggregatorMock);
54 |
55 | Set foundBuilds = changesAction.getContributingBuilds(build);
56 |
57 | assertTrue(foundBuilds.equals(ImmutableSet.of(build, build2, build3)));
58 | }
59 |
60 | @Test
61 | public void getContributingBuildsShouldWorkHandleCycles() throws Exception {
62 | AllChangesAction changesAction = new AllChangesAction(null);
63 | ChangesAggregator aggregatorMock = mock(ChangesAggregator.class);
64 | AbstractBuild build = mock(AbstractBuild.class);
65 | AbstractBuild build2 = mock(AbstractBuild.class);
66 | AbstractBuild build3 = mock(AbstractBuild.class);
67 | when(aggregatorMock.aggregateBuildsWithChanges(build)).thenReturn(ImmutableList.of(build2));
68 | when(aggregatorMock.aggregateBuildsWithChanges(build2)).thenReturn(ImmutableList.of(build3));
69 | when(aggregatorMock.aggregateBuildsWithChanges(build3)).thenReturn(ImmutableList.of(build));
70 |
71 | changesAction.aggregators = Lists.newArrayList(aggregatorMock);
72 |
73 | Set foundBuilds = changesAction.getContributingBuilds(build);
74 |
75 | assertTrue(foundBuilds.equals(ImmutableSet.of(build, build2, build3)));
76 | }
77 |
78 | @Test
79 | public void getContributingBuildsWorksWithMoreThanOneAggregator() throws Exception {
80 | AllChangesAction changesAction = new AllChangesAction(null);
81 | ChangesAggregator aggregatorMock = mock(ChangesAggregator.class);
82 | ChangesAggregator aggregatorMock2 = mock(ChangesAggregator.class);
83 | AbstractBuild build = mock(AbstractBuild.class);
84 | AbstractBuild build2 = mock(AbstractBuild.class);
85 | AbstractBuild build3 = mock(AbstractBuild.class);
86 | when(aggregatorMock.aggregateBuildsWithChanges(build)).thenReturn(ImmutableList.of(build2));
87 | when(aggregatorMock2.aggregateBuildsWithChanges(build2)).thenReturn(ImmutableList.of(build3));
88 |
89 | changesAction.aggregators = Lists.newArrayList(aggregatorMock, aggregatorMock2);
90 |
91 | Set foundBuilds = changesAction.getContributingBuilds(build);
92 |
93 | assertTrue(foundBuilds.equals(ImmutableSet.of(build, build2, build3)));
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
24 |
25 |
26 | 4.0.0
27 |
28 | org.jenkins-ci.plugins
29 | plugin
30 | 2.5
31 |
32 |
33 |
34 | org.jenkins-ci.plugins
35 | all-changes
36 | 1.6-SNAPSHOT
37 | hpi
38 | All changes plugin
39 | Shows more changes on the project page
40 | http://wiki.jenkins-ci.org/display/JENKINS/All+Changes+Plugin
41 |
42 |
43 | The MIT license
44 | http://www.opensource.org/licenses/mit-license.php
45 | repo
46 |
47 |
48 |
49 |
50 | wolfs
51 | Stefan Wolf
52 |
53 |
54 | pskumar448
55 | Suresh Kumar
56 | pskumar448@gmail.com
57 |
58 |
59 |
60 | 1.625.3
61 | 7
62 | 2.1
63 |
64 |
65 |
66 |
67 | org.jenkins-ci.plugins
68 | parameterized-trigger
69 | 2.30
70 | true
71 |
72 |
73 |
74 | org.jenkins-ci.plugins
75 | dashboard-view
76 | 2.9.9
77 | false
78 |
79 |
80 | org.jenkins-ci.plugins.workflow
81 | workflow-job
82 | 1.14
83 |
84 |
85 | org.mockito
86 | mockito-core
87 | 1.10.19
88 | test
89 |
90 |
91 | org.apache.httpcomponents
92 | httpclient
93 | 4.5.2
94 | test
95 |
96 |
97 |
98 |
100 |
101 |
102 | repo.jenkins-ci.org
103 | https://repo.jenkins-ci.org/public/
104 |
105 |
106 |
107 |
108 |
109 | repo.jenkins-ci.org
110 | https://repo.jenkins-ci.org/public/
111 |
112 |
113 |
114 | scm:git:git://github.com/jenkinsci/all-changes-plugin.git
115 | scm:git:git@github.com:jenkinsci/all-changes-plugin.git
116 | http://github.com/jenkinsci/all-changes-plugin
117 | HEAD
118 |
119 |
120 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/all_changes/AllChangesWorkflowAction/main.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2017, Suresh
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | import com.google.common.collect.Multimap
26 | import hudson.Functions
27 | import hudson.scm.ChangeLogSet
28 | import org.jenkinsci.plugins.workflow.job.WorkflowRun
29 | import org.jvnet.localizer.LocaleProvider
30 |
31 | import java.text.DateFormat
32 |
33 | f = namespace(lib.FormTagLib)
34 | l = namespace(lib.LayoutTagLib)
35 | t = namespace("/lib/hudson")
36 | st = namespace("jelly:stapler")
37 |
38 |
39 | def from = buildNumber(request.getParameter('from'));
40 | def to = buildNumber(request.getParameter('to'));
41 |
42 | def builds = Functions.filter(my.project.buildsAsMap, from, to).values()
43 | if (builds.empty) {
44 | text(_("No builds."))
45 | } else {
46 | showChanges(builds)
47 | }
48 |
49 |
50 | private buildNumber(String build) {
51 | if (build?.isInteger()) {
52 | return build
53 | } else {
54 | def permaLink = my.project.getPermalinks().get(build)
55 | def run = permaLink?.resolve(my.project)
56 | return run?.number?.toString()
57 | }
58 | }
59 |
60 | private showChanges(Collection builds) {
61 | def changedBuildCount = 1;
62 | boolean hadChanges = false;
63 | for (WorkflowRun build in builds) {
64 | Multimap changes = my.getAllChanges(build);
65 | if (changes.empty) {
66 | continue
67 | }
68 | if(changedBuildCount > my.numChanges && my.numChanges != 0)
69 | {
70 | break
71 | }
72 | hadChanges = true
73 | h2() {
74 | a(href: "${my.project.absoluteUrl}/${build.number}/changes",
75 | """${build.displayName} (${
76 | DateFormat.getDateTimeInstance(
77 | DateFormat.MEDIUM,
78 | DateFormat.MEDIUM,
79 | LocaleProvider.locale).format(build.timestamp.time)})""")
80 | }
81 | ul() {
82 | for (entry in changes.keySet()) {
83 | li() {
84 | showEntry(entry, build, changes.get(entry))
85 | }
86 | }
87 | }
88 | changedBuildCount++;
89 | }
90 | if (!hadChanges) {
91 | text(_("No changes in any of the builds."))
92 | }
93 | }
94 |
95 | private def showEntry(entry, WorkflowRun build, Collection builds) {
96 | showChangeSet(entry)
97 | boolean firstDrawn = false
98 | for (WorkflowRun b in builds) {
99 | if (b != build) {
100 | if (!firstDrawn) {
101 | text(" (")
102 | firstDrawn = true
103 | }
104 | else {
105 | text(", ")
106 | }
107 | a(href: "${rootURL}/${b.project.url}") {text(b.project.displayName)}
108 | st.nbsp()
109 | a(href: "${rootURL}/${b.url}") {
110 | text(b.displayName)
111 | }
112 | }
113 | }
114 | if (firstDrawn) {
115 | text(")")
116 | }
117 | }
118 |
119 | private def showChangeSet(ChangeLogSet.Entry c) {
120 | def build = c.parent.run
121 | def browser = c.parent.browser
122 | raw(c.getCommitId())
123 | raw(" » ")
124 | raw(c.msgAnnotated)
125 | raw(" — ")
126 | if (browser?.getChangeSetLink(c)) {
127 | a(href: browser.getChangeSetLink(c), _("detail"))
128 | } else {
129 | a(href: "${build.absoluteUrl}changes", _("detail"))
130 | }
131 | }
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/all_changes/SubProjectChangesAggregator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2011, Stefan Wolf
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package org.jenkinsci.plugins.all_changes;
26 |
27 | import com.google.common.collect.ImmutableList;
28 | import com.google.common.collect.Lists;
29 | import com.google.common.collect.Sets;
30 | import hudson.Extension;
31 | import hudson.Plugin;
32 | import hudson.model.AbstractBuild;
33 | import hudson.model.AbstractProject;
34 | import hudson.model.Cause;
35 | import hudson.model.FreeStyleProject;
36 | import hudson.plugins.parameterizedtrigger.BlockableBuildTriggerConfig;
37 | import hudson.plugins.parameterizedtrigger.TriggerBuilder;
38 | import hudson.tasks.Builder;
39 | import hudson.util.RunList;
40 | import jenkins.model.Jenkins;
41 |
42 | import java.util.Collection;
43 | import java.util.List;
44 | import java.util.Set;
45 |
46 | /**
47 | * @author wolfs
48 | */
49 | @Extension
50 | public class SubProjectChangesAggregator extends ChangesAggregator {
51 | @Override
52 | public Collection aggregateBuildsWithChanges(AbstractBuild build) {
53 | Plugin parameterizedTrigger = Util.getInstance().getPlugin("parameterized-trigger");
54 | if (parameterizedTrigger == null) {
55 | return ImmutableList.of();
56 | }
57 |
58 | AbstractProject project = build.getProject();
59 | Set> subProjects = Sets.newHashSet();
60 | Set builds = Sets.newHashSet();
61 | if (project instanceof FreeStyleProject) {
62 | subProjects.addAll(getSubProjects((FreeStyleProject) project));
63 | builds.addAll(getTriggeredBuilds(build, subProjects));
64 | }
65 |
66 | return builds;
67 | }
68 |
69 | private List getTriggeredBuilds(AbstractBuild build, Collection> subProjects) {
70 | List builds = Lists.newArrayList();
71 | for (AbstractProject, ?> subProject : subProjects) {
72 | RunList extends AbstractBuild, ?>> subBuildsDuringBuild = subProject.getBuilds().byTimestamp(build.getTimeInMillis(), build.getTimeInMillis() + build.getDuration());
73 | for (AbstractBuild, ?> candidate : subBuildsDuringBuild) {
74 | if (isSubBuild(build, candidate)) {
75 | builds.add(candidate);
76 | }
77 | }
78 | }
79 | return builds;
80 | }
81 |
82 | private List> getSubProjects(FreeStyleProject project) {
83 | List> subProjects = Lists.newArrayList();
84 | List builders = project.getBuilders();
85 | for (Builder builder : builders) {
86 | if (builder instanceof TriggerBuilder) {
87 | TriggerBuilder tBuilder = (TriggerBuilder) builder;
88 | for (BlockableBuildTriggerConfig config : tBuilder.getConfigs()) {
89 | for (AbstractProject, ?> abstractProject : config.getProjectList(null)) {
90 | if (config.getBlock() != null) {
91 | subProjects.add(abstractProject);
92 | }
93 | }
94 | }
95 | }
96 | }
97 | return subProjects;
98 | }
99 |
100 | private boolean isSubBuild(AbstractBuild build, AbstractBuild, ?> subBuild) {
101 | List causes = subBuild.getCauses();
102 | for (Cause cause : causes) {
103 | if (cause instanceof Cause.UpstreamCause) {
104 | Cause.UpstreamCause upstreamCause = (Cause.UpstreamCause) cause;
105 | if (upstreamCause.pointsTo(build)) {
106 | return true;
107 | }
108 | }
109 | }
110 | return false;
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/src/main/java/org/jenkinsci/plugins/all_changes/AllChangesAction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2011, Stefan Wolf
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package org.jenkinsci.plugins.all_changes;
26 |
27 | import com.google.common.collect.ArrayListMultimap;
28 | import com.google.common.collect.HashMultimap;
29 | import com.google.common.collect.ImmutableList;
30 | import com.google.common.collect.Multimap;
31 | import com.google.common.collect.Sets;
32 | import hudson.model.AbstractBuild;
33 | import hudson.model.AbstractProject;
34 | import hudson.model.Action;
35 | import hudson.scm.ChangeLogSet;
36 |
37 | import java.util.List;
38 | import java.util.Set;
39 |
40 | /**
41 | * Action to calculate all changes for a build
42 | * It uses ChangesAggregators to to so.
43 | *
44 | * @author wolfs
45 | */
46 | public class AllChangesAction implements Action {
47 |
48 | private AbstractProject, ?> project;
49 | private int numChanges = 0;
50 | transient
51 | List aggregators;
52 |
53 | AllChangesAction(AbstractProject, ?> project) {
54 | this.project = project;
55 | }
56 |
57 | AllChangesAction(AbstractProject, ?> project, int numChanges) {
58 | this.project = project;
59 | this.numChanges = numChanges;
60 | }
61 |
62 | public String getIconFileName() {
63 | return "notepad.png";
64 | }
65 |
66 | public String getDisplayName() {
67 | return Messages.AllChanges_allChanges();
68 | }
69 |
70 | public String getUrlName() {
71 | return "all-changes";
72 | }
73 |
74 | /**
75 | * Returns all changes which contribute to a build.
76 | *
77 | * @param build
78 | * @return
79 | */
80 | public Multimap getAllChanges(AbstractBuild build) {
81 | Set builds = getContributingBuilds(build);
82 | Multimap changes = ArrayListMultimap.create();
83 | for (AbstractBuild changedBuild : builds) {
84 | ChangeLogSet changeSet = changedBuild.getChangeSet();
85 | for (ChangeLogSet.Entry entry : changeSet) {
86 | changes.put(entry.getCommitId() + entry.getMsgAnnotated() + entry.getTimestamp(), entry);
87 | }
88 | }
89 | Multimap change2Build = HashMultimap.create();
90 | for (String changeKey : changes.keySet()) {
91 | ChangeLogSet.Entry change = changes.get(changeKey).iterator().next();
92 | for (ChangeLogSet.Entry entry : changes.get(changeKey)) {
93 | change2Build.put(change, entry.getParent().build);
94 | }
95 | }
96 | return change2Build;
97 | }
98 |
99 | /**
100 | * Uses all ChangesAggregators to calculate the contributing builds
101 | *
102 | * @return all changes which contribute to the given build
103 | */
104 | public Set getContributingBuilds(AbstractBuild build) {
105 | if (aggregators == null) {
106 | aggregators = ImmutableList.copyOf(ChangesAggregator.all());
107 | }
108 | Set builds = Sets.newHashSet();
109 | builds.add(build);
110 | int size = 0;
111 | // Saturate the build Set
112 | do {
113 | size = builds.size();
114 | Set newBuilds = Sets.newHashSet();
115 | for (ChangesAggregator aggregator : aggregators) {
116 | for (AbstractBuild depBuild : builds) {
117 | newBuilds.addAll(aggregator.aggregateBuildsWithChanges(depBuild));
118 | }
119 | }
120 | builds.addAll(newBuilds);
121 | } while (size < builds.size());
122 | return builds;
123 | }
124 |
125 | public AbstractProject, ?> getProject() {
126 | return project;
127 | }
128 |
129 | public int getNumChanges() {
130 | return numChanges;
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/src/main/resources/org/jenkinsci/plugins/all_changes/AllChangesAction/main.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2017, Suresh
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package org.jenkinsci.plugins.all_changes.AllChangesAction
26 |
27 | import com.google.common.collect.Multimap
28 | import hudson.Functions
29 | import hudson.model.AbstractBuild
30 | import hudson.scm.ChangeLogSet
31 | import org.jvnet.localizer.LocaleProvider
32 |
33 | import java.text.DateFormat
34 |
35 | f = namespace(lib.FormTagLib)
36 | l = namespace(lib.LayoutTagLib)
37 | t = namespace("/lib/hudson")
38 | st = namespace("jelly:stapler")
39 |
40 |
41 | def from = buildNumber(request.getParameter('from'));
42 | def to = buildNumber(request.getParameter('to'));
43 |
44 | def builds = Functions.filter(my.project.buildsAsMap, from, to).values()
45 | if (builds.empty) {
46 | text(_("No builds."))
47 | } else {
48 | showChanges(builds)
49 | }
50 |
51 | private buildNumber(String build) {
52 | if (build?.isInteger()) {
53 | return build
54 | } else {
55 | def permaLink = my.project.getPermalinks().get(build)
56 | def run = permaLink?.resolve(my.project)
57 | return run?.number?.toString()
58 | }
59 | }
60 |
61 | private showChanges(Collection builds) {
62 | def changedBuildCount = 1;
63 | boolean hadChanges = false;
64 | for (AbstractBuild build in builds) {
65 | Multimap changes = my.getAllChanges(build);
66 | if (changes.empty) {
67 | continue
68 | }
69 | if(changedBuildCount > my.numChanges && my.numChanges != 0)
70 | {
71 | break
72 | }
73 | hadChanges = true
74 | h2() {
75 | a(href: "${my.project.absoluteUrl}/${build.number}/changes",
76 | """${build.displayName} (${
77 | DateFormat.getDateTimeInstance(
78 | DateFormat.MEDIUM,
79 | DateFormat.MEDIUM,
80 | LocaleProvider.locale).format(build.timestamp.time)})""")
81 | }
82 | ul() {
83 | for (entry in changes.keySet()) {
84 | li() {
85 | showEntry(entry, build, changes.get(entry))
86 | }
87 | }
88 | }
89 | changedBuildCount++;
90 | }
91 | if (!hadChanges) {
92 | text(_("No changes in any of the builds."))
93 | }
94 | }
95 |
96 | private def showEntry(entry, AbstractBuild build, Collection builds) {
97 | showChangeSet(entry)
98 | boolean firstDrawn = false
99 | for (AbstractBuild b in builds) {
100 | if (b != build) {
101 | if (!firstDrawn) {
102 | text(" (")
103 | firstDrawn = true
104 | }
105 | else {
106 | text(", ")
107 | }
108 | a(href: "${rootURL}/${b.project.url}") {text(b.project.displayName)}
109 | st.nbsp()
110 | a(href: "${rootURL}/${b.url}") {
111 | text(b.displayName)
112 | }
113 | }
114 | }
115 | if (firstDrawn) {
116 | text(")")
117 | }
118 | }
119 |
120 | private def showChangeSet(ChangeLogSet.Entry c) {
121 | def build = c.parent.build
122 | def browser = build.project.scm.effectiveBrowser
123 | raw(c.getCommitId())
124 | raw(" » ")
125 | raw(c.msgAnnotated)
126 | raw(" — ")
127 | if (browser?.getChangeSetLink(c)) {
128 | a(href: browser.getChangeSetLink(c), _("detail"))
129 | } else {
130 | a(href: "${build.absoluteUrl}changes", _("detail"))
131 | }
132 | }
133 |
134 | private def showDependencyChanges(AbstractBuild.DependencyChange dep) {
135 | a(href: "${rootURL}/${dep.project.url}") {text(dep.project.displayName)}
136 | st.nbsp()
137 | a(href: "${rootURL}/${dep.from.url}") {
138 | delegate.img(src: "${imagesURL}/16x16/${dep.from.buildStatusUrl}",
139 | alt: "${dep.from.iconColor.description}", height: "16", width: "16")
140 | text(dep.from.displayName)
141 | }
142 |
143 | raw("→") // right arrow
144 | a(href: "${rootURL}/${dep.to.url}") {
145 | delegate.img(src: "${imagesURL}/16x16/${dep.to.buildStatusUrl}",
146 | alt: "${dep.to.iconColor.description}", height: "16", width: "16")
147 | text(dep.to.displayName)
148 | }
149 | }
--------------------------------------------------------------------------------