tetra 0.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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