tetra 0.40.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. data/.gitignore +27 -0
  2. data/.rubocop.yml +14 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +28 -0
  5. data/MOTIVATION.md +27 -0
  6. data/README.md +106 -0
  7. data/Rakefile +9 -0
  8. data/SPECIAL_CASES.md +130 -0
  9. data/bin/tetra +29 -0
  10. data/integration-tests/commons.sh +55 -0
  11. data/lib/template/gitignore +2 -0
  12. data/lib/template/kit.spec +64 -0
  13. data/lib/template/kit/CONTENTS +8 -0
  14. data/lib/template/kit/jars/CONTENTS +1 -0
  15. data/lib/template/kit/m2/settings.xml +10 -0
  16. data/lib/template/output/CONTENTS +3 -0
  17. data/lib/template/package.spec +65 -0
  18. data/lib/template/src/CONTENTS +6 -0
  19. data/lib/tetra.rb +63 -0
  20. data/lib/tetra/ant_runner.rb +27 -0
  21. data/lib/tetra/archiver.rb +95 -0
  22. data/lib/tetra/commands/ant.rb +23 -0
  23. data/lib/tetra/commands/base.rb +89 -0
  24. data/lib/tetra/commands/download_maven_source_jars.rb +29 -0
  25. data/lib/tetra/commands/dry_run.rb +17 -0
  26. data/lib/tetra/commands/finish.rb +22 -0
  27. data/lib/tetra/commands/generate_all.rb +38 -0
  28. data/lib/tetra/commands/generate_kit_archive.rb +18 -0
  29. data/lib/tetra/commands/generate_kit_spec.rb +16 -0
  30. data/lib/tetra/commands/generate_package_archive.rb +19 -0
  31. data/lib/tetra/commands/generate_package_script.rb +21 -0
  32. data/lib/tetra/commands/generate_package_spec.rb +22 -0
  33. data/lib/tetra/commands/get_pom.rb +33 -0
  34. data/lib/tetra/commands/get_source.rb +30 -0
  35. data/lib/tetra/commands/init.rb +15 -0
  36. data/lib/tetra/commands/list_kit_missing_sources.rb +21 -0
  37. data/lib/tetra/commands/move_jars_to_kit.rb +18 -0
  38. data/lib/tetra/commands/mvn.rb +23 -0
  39. data/lib/tetra/git.rb +140 -0
  40. data/lib/tetra/kit_checker.rb +104 -0
  41. data/lib/tetra/kit_runner.rb +43 -0
  42. data/lib/tetra/kit_spec_adapter.rb +28 -0
  43. data/lib/tetra/logger.rb +28 -0
  44. data/lib/tetra/main.rb +102 -0
  45. data/lib/tetra/maven_runner.rb +47 -0
  46. data/lib/tetra/maven_website.rb +59 -0
  47. data/lib/tetra/package_spec_adapter.rb +59 -0
  48. data/lib/tetra/pom.rb +55 -0
  49. data/lib/tetra/pom_getter.rb +104 -0
  50. data/lib/tetra/project.rb +245 -0
  51. data/lib/tetra/script_generator.rb +57 -0
  52. data/lib/tetra/source_getter.rb +41 -0
  53. data/lib/tetra/spec_generator.rb +60 -0
  54. data/lib/tetra/template_manager.rb +33 -0
  55. data/lib/tetra/version.rb +6 -0
  56. data/lib/tetra/version_matcher.rb +90 -0
  57. data/spec/data/ant-super-simple-code/build.xml +133 -0
  58. data/spec/data/ant-super-simple-code/build/HW.class +0 -0
  59. data/spec/data/ant-super-simple-code/build/mypackage/HW.class +0 -0
  60. data/spec/data/ant-super-simple-code/dist/antsimple-20130618.jar +0 -0
  61. data/spec/data/ant-super-simple-code/lib/junit-4.11.jar +0 -0
  62. data/spec/data/ant-super-simple-code/lib/log4j-1.2.13.jar +0 -0
  63. data/spec/data/ant-super-simple-code/src/mypackage/HW.java +15 -0
  64. data/spec/data/antlr/antlr-2.7.2.jar +0 -0
  65. data/spec/data/antlr/pom.xml +6 -0
  66. data/spec/data/commons-logging/commons-logging-1.1.1.jar +0 -0
  67. data/spec/data/commons-logging/parent_pom.xml +420 -0
  68. data/spec/data/commons-logging/pom.xml +504 -0
  69. data/spec/data/nailgun/nailgun-0.7.1.jar +0 -0
  70. data/spec/data/nailgun/pom.xml +153 -0
  71. data/spec/data/struts-apps/pom.xml +228 -0
  72. data/spec/data/tomcat/pom.xml +33 -0
  73. data/spec/lib/ant_runner_spec.rb +45 -0
  74. data/spec/lib/archiver_spec.rb +106 -0
  75. data/spec/lib/git_spec.rb +105 -0
  76. data/spec/lib/kit_checker_spec.rb +119 -0
  77. data/spec/lib/maven_runner_spec.rb +68 -0
  78. data/spec/lib/maven_website_spec.rb +56 -0
  79. data/spec/lib/pom_getter_spec.rb +36 -0
  80. data/spec/lib/pom_spec.rb +69 -0
  81. data/spec/lib/project_spec.rb +254 -0
  82. data/spec/lib/script_generator_spec.rb +67 -0
  83. data/spec/lib/source_getter_spec.rb +36 -0
  84. data/spec/lib/spec_generator_spec.rb +130 -0
  85. data/spec/lib/template_manager_spec.rb +54 -0
  86. data/spec/lib/version_matcher_spec.rb +64 -0
  87. data/spec/spec_helper.rb +37 -0
  88. data/spec/support/kit_runner_examples.rb +15 -0
  89. data/tetra.gemspec +31 -0
  90. data/utils/delete_nonet_user.sh +8 -0
  91. data/utils/setup_nonet_user.sh +8 -0
  92. metadata +267 -0
@@ -0,0 +1,8 @@
1
+ This directory contains all binary files needed to build a tetra project's
2
+ packages.
3
+
4
+ These files should only be used during build and should not be installed
5
+ on users' systems.
6
+
7
+ Some generally useful configuration files are also placed here (eg.
8
+ m2/settings.xml for Maven builds).
@@ -0,0 +1 @@
1
+ This directory contains jars moved here from source archives.
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <!--
4
+ | This is the configuration file used by default by `tetra mvn`.
5
+ | Feel free to add settings here if any are needed for tetra dry runs.
6
+ |-->
7
+ <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
8
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9
+ xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
10
+ </settings>
@@ -0,0 +1,3 @@
1
+ tetra will save all output files it generates (specs, archives, etc.) here.
2
+
3
+ Feel free to use this directory as an OBS project root.
@@ -0,0 +1,65 @@
1
+ #
2
+ # spec file for "<%= name %>"
3
+ #
4
+ # Copyright (c) <%= Time.now.year %> <%= Etc.getlogin %>
5
+ #
6
+ # All modifications and additions to the file contributed by third parties
7
+ # remain the property of their copyright owners, unless otherwise agreed
8
+ # upon. The license for this file, and modifications and additions to the
9
+ # file, is the same license as for the pristine package itself (unless the
10
+ # license for the pristine package is not an Open Source License, in which
11
+ # case the license is the MIT License). An "Open Source License" is a
12
+ # license that conforms to the Open Source Definition (Version 1.9)
13
+ # published by the Open Source Initiative.
14
+
15
+ # Please submit bugfixes or comments via http://bugs.opensuse.org/
16
+ #
17
+
18
+ Name: <%= name %>
19
+ Version: <%= version %>
20
+ Release: 1
21
+ License: <%= license %>
22
+ Summary: <%= summary %>
23
+ Url: <%= url %>
24
+ Group: Development/Libraries/Java
25
+ Source0: %{name}.tar.xz
26
+ Source1: build.sh
27
+ BuildRoot: %{_tmppath}/%{name}-%{version}-build
28
+ BuildRequires: xz
29
+ BuildRequires: java-devel
30
+ BuildRequires: <%= project_name %>-kit >= <%= project_version %>
31
+ BuildArch: noarch
32
+ Provides: mvn(<%= group_id %>:<%= artifact_id %>) == <%= version %>
33
+ Requires: java
34
+ <% runtime_dependency_ids.each do |dependency_id| %>
35
+ Requires: mvn(<%= dependency_id[0] %>:<%= dependency_id[1] %>) <% if dependency_id[3] != nil %>==<%= dependency_id[3] %><% end %>
36
+ <% end %>
37
+
38
+ %description
39
+ <%=
40
+ description
41
+ %>
42
+
43
+ %prep
44
+ %setup -q -c -n src/<%= name %>
45
+ cp -f %{SOURCE1} .
46
+ cp -Rf %{_datadir}/tetra/<%= project_name %>-kit ../../kit
47
+
48
+ %build
49
+ cd ../../
50
+ sh src/<%= name %>/build.sh
51
+
52
+ %install
53
+ export NO_BRP_CHECK_BYTECODE_VERSION=true
54
+ mkdir -p %{buildroot}%{_javadir}
55
+ <% outputs.each do |output| %>
56
+ cp -a <%= output %> %{buildroot}%{_javadir}/<%= File.basename(output) %>
57
+ <% end %>
58
+
59
+ %files
60
+ %defattr(-,root,root)
61
+ <% outputs.each do |output| %>
62
+ %{_javadir}/<%= File.basename(output) %>
63
+ <% end %>
64
+
65
+ %changelog
@@ -0,0 +1,6 @@
1
+ For each package you want to create, you should create a subdirectory here
2
+ named after the package name itself.
3
+
4
+ In that directory, place all the source files "verbatim" (as checked out from
5
+ the original source repository, ideally in a different subdirectory)
6
+ plus any additional files you might need for the build.
@@ -0,0 +1,63 @@
1
+ # encoding: UTF-8
2
+
3
+ # ruby standard library
4
+ require "digest/sha1"
5
+ require "English"
6
+ require "erb"
7
+ require "find"
8
+ require "forwardable"
9
+ require "logger"
10
+ require "open-uri"
11
+ require "pathname"
12
+ require "singleton"
13
+ require "text"
14
+
15
+ # third party libraries
16
+ require "clamp"
17
+ require "json"
18
+ require "nokogiri"
19
+ require "rest_client"
20
+ require "zip"
21
+
22
+ # internal, backend
23
+ require "tetra/version"
24
+ require "tetra/logger"
25
+ require "tetra/template_manager"
26
+ require "tetra/git"
27
+ require "tetra/script_generator"
28
+ require "tetra/project"
29
+ require "tetra/pom"
30
+ require "tetra/version_matcher"
31
+ require "tetra/maven_website"
32
+ require "tetra/pom_getter"
33
+ require "tetra/source_getter"
34
+ require "tetra/kit_runner"
35
+ require "tetra/ant_runner"
36
+ require "tetra/maven_runner"
37
+ require "tetra/kit_spec_adapter"
38
+ require "tetra/package_spec_adapter"
39
+ require "tetra/spec_generator"
40
+ require "tetra/archiver"
41
+ require "tetra/kit_checker"
42
+
43
+ # internal, UI
44
+ require "tetra/commands/base"
45
+
46
+ require "tetra/commands/ant"
47
+ require "tetra/commands/download_maven_source_jars"
48
+ require "tetra/commands/dry_run"
49
+ require "tetra/commands/finish"
50
+ require "tetra/commands/generate_all"
51
+ require "tetra/commands/generate_kit_archive"
52
+ require "tetra/commands/generate_kit_spec"
53
+ require "tetra/commands/generate_package_archive"
54
+ require "tetra/commands/generate_package_script"
55
+ require "tetra/commands/generate_package_spec"
56
+ require "tetra/commands/get_pom"
57
+ require "tetra/commands/get_source"
58
+ require "tetra/commands/init"
59
+ require "tetra/commands/list_kit_missing_sources"
60
+ require "tetra/commands/move_jars_to_kit"
61
+ require "tetra/commands/mvn"
62
+
63
+ require "tetra/main"
@@ -0,0 +1,27 @@
1
+ # encoding: UTF-8
2
+
3
+ module Tetra
4
+ # runs Ant with tetra-specific options
5
+ class AntRunner < KitRunner
6
+ include Logging
7
+
8
+ # runs ant in a subprocess
9
+ def ant(options)
10
+ run_executable("#{get_ant_commandline(@project.full_path)} #{options.join(" ")}")
11
+ end
12
+
13
+ # returns a command line for running Ant from the specified
14
+ # prefix
15
+ def get_ant_commandline(prefix)
16
+ executable = find_executable("ant")
17
+
18
+ if !executable.nil?
19
+ ant_path = File.join(prefix, executable)
20
+
21
+ "#{ant_path}"
22
+ else
23
+ fail ExecutableNotFoundError, "ant"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,95 @@
1
+ # encoding: UTF-8
2
+
3
+ module Tetra
4
+ # generates file archives that accompany spec files
5
+ class Archiver
6
+ include Logging
7
+
8
+ def initialize(project)
9
+ @project = project
10
+ end
11
+
12
+ # generates an archive for the kit package
13
+ def archive_kit(whole)
14
+ destination_dir = File.join(@project.full_path, "output", "#{@project.name}-kit")
15
+ FileUtils.mkdir_p(destination_dir)
16
+ file_prefix = "#{@project.name}-kit"
17
+ file_suffix = ".tar.xz"
18
+
19
+ @project.take_snapshot "Kit archival started"
20
+
21
+ destination_file = (
22
+ if whole
23
+ remove_stale_incremental(destination_dir, file_prefix, file_suffix)
24
+ archive_single("kit", File.join(destination_dir, file_prefix + file_suffix))
25
+ else
26
+ log.debug "doing incremental archive"
27
+ archive_incremental("kit", destination_dir, file_prefix, file_suffix, :archive_kit)
28
+ end
29
+ )
30
+
31
+ @project.take_snapshot "Kit archive generated", :archive_kit
32
+
33
+ destination_file
34
+ end
35
+
36
+ # generates an archive for a project's package based on its file list
37
+ def archive_package(name)
38
+ destination_dir = File.join(@project.full_path, "output", name)
39
+ FileUtils.mkdir_p(destination_dir)
40
+ destination_file = File.join(destination_dir, "#{name}.tar.xz")
41
+
42
+ archive_single(File.join("src", name), destination_file)
43
+ end
44
+
45
+ # archives a directory's contents to the destination file
46
+ def archive_single(source_directory, destination_file)
47
+ log.debug "creating #{destination_file}"
48
+ @project.from_directory source_directory do
49
+ `tar -cJf #{destination_file} *`
50
+ end
51
+
52
+ destination_file
53
+ end
54
+
55
+ # archives a directory's changed contents since last time archive_incremental was called
56
+ # uses snapshots with tag_prefix to keep track of calls to this method
57
+ # destination files will be file_prefix_NNNN_file_suffix
58
+ def archive_incremental(source_directory, destination_dir, file_prefix, file_suffix, tag_prefix)
59
+ @project.from_directory do
60
+ latest_tag_count = @project.latest_tag_count(tag_prefix)
61
+
62
+ if latest_tag_count == 0
63
+ archive_single(source_directory, File.join(destination_dir, file_prefix + file_suffix))
64
+ else
65
+ destination_file = File.join(destination_dir,
66
+ "#{file_prefix}_#{format("%04d", latest_tag_count)}#{file_suffix}")
67
+ tag = @project.latest_tag(tag_prefix)
68
+ log.debug "creating #{destination_file} with files newer than #{tag}"
69
+
70
+ log.debug "files that changed since then: #{@project.git.changed_files_since(tag)}"
71
+ list = @project.git.changed_files_since(tag).select do |file|
72
+ File.expand_path(file) =~ /^#{File.expand_path(source_directory)}\//
73
+ end.map do |file|
74
+ Pathname.new(file).relative_path_from Pathname.new(source_directory)
75
+ end
76
+ @project.from_directory source_directory do
77
+ `tar -cJf #{destination_file} #{list.join(" ")}`
78
+ end
79
+
80
+ destination_file
81
+ end
82
+ end
83
+ end
84
+
85
+ # removes any stale incremental files
86
+ def remove_stale_incremental(destination_dir, file_prefix, file_suffix)
87
+ Dir.entries(destination_dir)
88
+ .select { |f| f =~ /^#{file_prefix}_([0-9]+)#{file_suffix}$/ }
89
+ .each do |f|
90
+ log.debug "removing stale incremental archive #{f}"
91
+ File.delete(File.join(destination_dir, f))
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: UTF-8
2
+
3
+ module Tetra
4
+ # tetra ant
5
+ class AntCommand < Tetra::BaseCommand
6
+ parameter "[ANT OPTIONS] ...", "ant options", attribute_name: "dummy"
7
+
8
+ # override parsing in order to pipe everything to mvn
9
+ # rubocop:disable TrivialAccessors
10
+ def parse(args)
11
+ @options = args
12
+ end
13
+
14
+ def execute
15
+ checking_exceptions do
16
+ project = Tetra::Project.new(".")
17
+ ensure_dry_running(true, project) do
18
+ Tetra::AntRunner.new(project).ant(@options)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,89 @@
1
+ # encoding: UTF-8
2
+
3
+ module Tetra
4
+ # implements common options and utility methods
5
+ class BaseCommand < Clamp::Command
6
+ include Logging
7
+
8
+ # Options available to all tetra commands
9
+ option %w(-v --verbose), :flag, "verbose output"
10
+ option ["--very-verbose"], :flag, "very verbose output"
11
+ option ["--very-very-verbose"], :flag, "very very verbose output"
12
+
13
+ # verbosity handlers
14
+ def very_very_verbose=(flag)
15
+ configure_log_level(verbose?, very_verbose?, flag)
16
+ end
17
+
18
+ def very_verbose=(flag)
19
+ configure_log_level(verbose?, flag, very_very_verbose?)
20
+ end
21
+
22
+ def verbose=(flag)
23
+ configure_log_level(flag, very_verbose?, very_very_verbose?)
24
+ end
25
+
26
+ # maps verbosity options to log level
27
+ def configure_log_level(v, vv, vvv)
28
+ if vvv
29
+ log.level = ::Logger::DEBUG
30
+ elsif vv
31
+ log.level = ::Logger::INFO
32
+ elsif v
33
+ log.level = ::Logger::WARN
34
+ else
35
+ log.level = ::Logger::ERROR
36
+ end
37
+ end
38
+
39
+ # prints an error message and exits unless there is a dry-run in progress
40
+ def ensure_dry_running(state, project)
41
+ if project.dry_running? == state
42
+ yield
43
+ else
44
+ if state == true
45
+ puts "Please start a dry-run first, use \"tetra dry-run\""
46
+ else
47
+ puts "Please finish or abort this dry-run first, use \"tetra finish\" or \"tetra finish --abort\""
48
+ end
49
+ end
50
+ end
51
+
52
+ # outputs output of a file generation
53
+ def print_generation_result(project, result_path, conflict_count = 0)
54
+ puts "#{format_path(result_path, project)} generated"
55
+ puts "Warning: #{conflict_count} unresolved conflicts" if conflict_count > 0
56
+ end
57
+
58
+ # generates a version of path relative to the current directory
59
+ def format_path(path, project)
60
+ full_path = (
61
+ if Pathname.new(path).relative?
62
+ File.join(project.full_path, path)
63
+ else
64
+ path
65
+ end
66
+ )
67
+ Pathname.new(full_path).relative_path_from(Pathname.new(Dir.pwd))
68
+ end
69
+
70
+ # handles most fatal exceptions
71
+ def checking_exceptions
72
+ yield
73
+ rescue Errno::EACCES => e
74
+ $stderr.puts e
75
+ rescue Errno::ENOENT => e
76
+ $stderr.puts e
77
+ rescue Errno::EEXIST => e
78
+ $stderr.puts e
79
+ rescue NoProjectDirectoryError => e
80
+ $stderr.puts "#{e.directory} is not a tetra project directory, see tetra init"
81
+ rescue NoPackageDirectoryError => e
82
+ $stderr.puts "#{e.directory} is not a tetra package directory, see README"
83
+ rescue GitAlreadyInitedError
84
+ $stderr.puts "This directory is already a tetra project"
85
+ rescue ExecutableNotFoundError => e
86
+ $stderr.puts "Executable #{e.executable} not found in kit/ or any of its subdirectories"
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: UTF-8
2
+
3
+ module Tetra
4
+ # tetra download-maven-source-jars
5
+ class DownloadMavenSourceJarsCommand < Tetra::BaseCommand
6
+ def execute
7
+ checking_exceptions do
8
+ project = Tetra::Project.new(".")
9
+ source_getter = Tetra::SourceGetter.new
10
+
11
+ ensure_dry_running(false, project) do
12
+ puts "Getting sources from Maven..."
13
+ succeeded, failed = source_getter.get_maven_source_jars(project)
14
+
15
+ puts "\n**SUMMARY**\n"
16
+ puts "Sources found for:"
17
+ succeeded.each do |path|
18
+ puts " #{format_path(path, project)}"
19
+ end
20
+
21
+ puts "\nSources not found for:"
22
+ failed.each do |path|
23
+ puts " #{format_path(path, project)}"
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: UTF-8
2
+
3
+ module Tetra
4
+ # tetra dry-run
5
+ class DryRunCommand < Tetra::BaseCommand
6
+ def execute
7
+ checking_exceptions do
8
+ if Tetra::Project.new(".").dry_run
9
+ puts "Now dry-running, please start your build."
10
+ puts "To run a Maven installation from the kit, use \"tetra mvn\"."
11
+ puts "If the build succeedes end this dry run with \"tetra finish\"."
12
+ puts "If the build does not succeed use \"tetra finish --abort\" to restore files."
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end