tetra 0.40.0 → 0.41.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/.gitignore +1 -1
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +48 -0
  4. data/MOTIVATION.md +9 -3
  5. data/README.md +5 -5
  6. data/SPECIAL_CASES.md +1 -3
  7. data/integration-tests/{commons.sh → build-commons.sh} +26 -6
  8. data/integration-tests/build-obs.sh +21 -0
  9. data/lib/template/kit_item.spec +53 -0
  10. data/lib/template/package.spec +4 -2
  11. data/lib/tetra.rb +5 -3
  12. data/lib/tetra/archiver.rb +23 -87
  13. data/lib/tetra/commands/generate_all.rb +13 -16
  14. data/lib/tetra/commands/generate_kit_archive.rb +4 -4
  15. data/lib/tetra/commands/generate_kit_spec.rb +4 -2
  16. data/lib/tetra/commands/generate_package_archive.rb +1 -1
  17. data/lib/tetra/commands/generate_package_spec.rb +2 -2
  18. data/lib/tetra/git.rb +19 -10
  19. data/lib/tetra/glue_kit_item.rb +42 -0
  20. data/lib/tetra/jar_kit_item.rb +45 -0
  21. data/lib/tetra/kit.rb +73 -0
  22. data/lib/tetra/maven_kit_item.rb +64 -0
  23. data/lib/tetra/package.rb +82 -0
  24. data/lib/tetra/project.rb +26 -22
  25. data/lib/tetra/spec_generator.rb +38 -42
  26. data/lib/tetra/version.rb +1 -1
  27. data/spec/lib/archiver_spec.rb +30 -86
  28. data/spec/lib/git_spec.rb +8 -8
  29. data/spec/lib/glue_kit_item_spec.rb +31 -0
  30. data/spec/lib/kit_spec.rb +67 -0
  31. data/spec/lib/maven_kit_item_spec.rb +74 -0
  32. data/spec/lib/package_spec.rb +78 -0
  33. data/spec/lib/project_spec.rb +1 -1
  34. data/spec/lib/spec_generator_spec.rb +59 -87
  35. metadata +15 -8
  36. data/lib/template/kit.spec +0 -64
  37. data/lib/tetra/kit_spec_adapter.rb +0 -28
  38. data/lib/tetra/package_spec_adapter.rb +0 -59
  39. data/lib/tetra/template_manager.rb +0 -33
  40. data/spec/lib/template_manager_spec.rb +0 -54
data/.gitignore CHANGED
@@ -23,5 +23,5 @@ _yardoc
23
23
  doc/
24
24
 
25
25
  # integration test files
26
- integration-tests/galaxy
26
+ integration-tests/commons
27
27
 
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  source "http://rubygems.org"
2
4
 
3
5
  # See tetra.gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,48 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ tetra (0.40.0)
5
+ clamp
6
+ json
7
+ nokogiri
8
+ rest-client
9
+ rubyzip (>= 1.0)
10
+ text
11
+
12
+ GEM
13
+ remote: http://rubygems.org/
14
+ specs:
15
+ clamp (0.6.3)
16
+ diff-lcs (1.2.5)
17
+ json (1.8.1)
18
+ mime-types (2.3)
19
+ mini_portile (0.6.0)
20
+ netrc (0.7.7)
21
+ nokogiri (1.6.3.1)
22
+ mini_portile (= 0.6.0)
23
+ rake (10.3.2)
24
+ rest-client (1.7.2)
25
+ mime-types (>= 1.16, < 3.0)
26
+ netrc (~> 0.7)
27
+ rspec (3.0.0)
28
+ rspec-core (~> 3.0.0)
29
+ rspec-expectations (~> 3.0.0)
30
+ rspec-mocks (~> 3.0.0)
31
+ rspec-core (3.0.4)
32
+ rspec-support (~> 3.0.0)
33
+ rspec-expectations (3.0.4)
34
+ diff-lcs (>= 1.2.0, < 2.0)
35
+ rspec-support (~> 3.0.0)
36
+ rspec-mocks (3.0.4)
37
+ rspec-support (~> 3.0.0)
38
+ rspec-support (3.0.4)
39
+ rubyzip (1.1.6)
40
+ text (1.3.0)
41
+
42
+ PLATFORMS
43
+ ruby
44
+
45
+ DEPENDENCIES
46
+ rake
47
+ rspec
48
+ tetra!
data/MOTIVATION.md CHANGED
@@ -11,13 +11,19 @@ A typical example is packaging any software built by Maven on SUSE distros. A nu
11
11
  * Maven often uses multiple versions of a same library or plugin during the same build. Usually distros do not accept more than one version of any given library to reduce maintenance work;
12
12
  * Maven requires itself in order to build. To be more exact, Maven needs Nexus, which in turn needs Maven and Nexus. To be more exact, its build dependency graph is a very complicated mess with lots of cycles that have to be broken manually.
13
13
 
14
- The current solution in openSUSE is having the packager handle those differences, but this limits the amount of software the community is able to package due to the high effort required to overcome them.
14
+ ## Existing solutions
15
15
 
16
- The Fedora community is experimenting with another set of tools, [XMvn](http://mizdebsk.fedorapeople.org/xmvn/site/), which goals are similar to `tetra`'s.
16
+ In the openSUSE community, it is a packager's duty to handle those differences, but this limits the amount of software the community is able to package due to the high effort required to overcome them.
17
+
18
+ The Fedora community uses another set of tools, [XMvn](http://mizdebsk.fedorapeople.org/xmvn/site/), which goals are similar to `tetra`'s. They are limited to Maven, though.
19
+
20
+ The Debian community has [various tools](https://wiki.debian.org/Java/Packaging), and among those one that automatically patches `pom.xml` Maven files. The downside is that those files will be different from the original upstream's, so they will have to be kept up to date.
21
+
22
+ The Arch community [basically ignores the problem](https://wiki.archlinux.org/index.php/Java_Package_Guidelines): "You do not need to compile Java applications from source.".
17
23
 
18
24
  ## Kit rationale
19
25
 
20
- `tetra` simplifies the packaging process mostly because of its use of a binary blob package that contains all build time dependencies for a set of packages called a **kit**.
26
+ `tetra` simplifies the packaging process mostly because of its use of packaged binary blobs that contain all build time dependencies for a set of packages. This is called a **kit**.
21
27
 
22
28
  Building software from a binary blob is unusual for Linux distros, and it surely has some drawbacks. It is anyway believed that benefits outweigh them, in fact using prebuilt software:
23
29
 
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # tetra – builds RPMs for Java software
2
2
 
3
- `tetra` is a set of tools to help you build RPM packages for Java projects.
3
+ `tetra` is a tool to help you build RPM packages for Java projects.
4
4
 
5
- Packaging of Java projects is sometimes hard because build tools like Maven partially overlap with distro tools like RPM in functionality.
5
+ Packaging of Java projects is sometimes hard - mainly because build tools like Maven partially overlap with distro ones like RPM.
6
6
 
7
- This tool's goal is to drastically simplifies packaging.
7
+ See [MOTIVATION.md](MOTIVATION.md) for further information.
8
8
 
9
9
  ## Installation
10
10
 
@@ -31,7 +31,7 @@ Done!
31
31
 
32
32
  ### How can that possibly work?
33
33
 
34
- With `tetra` you are not building all dependencies from source, just your package. Everything else is shipped already compiled with attached source files, which is much easier to implement and automate. Yet, it is sufficient to fulfill open source licenses and to have a repeatable, networkless build. See [MOTIVATION.md](MOTIVATION.md) for further information.
34
+ With `tetra` you are not building all dependencies from source, just your package. Everything else is shipped already compiled with attached source files, which is much easier to implement and automate. Yet, it is sufficient to fulfill open source licenses and to have a repeatable, networkless build.
35
35
 
36
36
  ## A commons-collections walkthrough
37
37
 
@@ -71,7 +71,7 @@ Finally, generate build scripts, spec files and tarballs in the `output/` direct
71
71
 
72
72
  tetra generate-all
73
73
 
74
- Note that `tetra` will generate files for the commons-collections package and for the binary-only myproject-kit package, which is a special container of all build-time dependencies (basically, the `kit/` folder). This will be shared among all packages you might add to your `tetra` project.
74
+ Note that `tetra` will generate files for the commons-collections package and all binary-only build-time dependencies (basically, the `kit/` folder). This will be shared among all packages you might add to your `tetra` project.
75
75
 
76
76
  ## In-depth information
77
77
 
data/SPECIAL_CASES.md CHANGED
@@ -14,11 +14,9 @@ You can do any manual changes to spec and build.sh files and regenerate them lat
14
14
  * `tetra generate-package-archive`: (re)generates a package tarball;
15
15
  * `tetra generate-package-spec`: (re)generates a package spec;
16
16
 
17
- Note that, by default, `generate-kit-archive` will generate additional "diff" tar.xz files instead of rewriting the whole archive - this will result in faster uploads if you use OBS (see below). You can use the `--whole` option to regenerate a single complete archive.
18
-
19
17
  ## Kit sources
20
18
 
21
- Your kit is basically a binary blob. If its sources are needed for proper packaging, for example to comply with the GPL, some extra steps are needed.
19
+ Your kit packages are basically binary blobs. If its sources are needed for proper packaging, for example to comply with the GPL, some extra steps are needed.
22
20
 
23
21
  If you use Maven, most (~90%) sources can be automatically downloaded:
24
22
 
@@ -1,12 +1,12 @@
1
1
  #!/bin/bash
2
2
 
3
- # A crude integration test that builds commons-collections
3
+ # A crude integration test that builds some Apache Commons libraries
4
4
 
5
5
  set -e
6
6
 
7
- rm -Rf galaxy
8
- mkdir galaxy
9
- cd galaxy
7
+ rm -Rf commons
8
+ mkdir commons
9
+ cd commons
10
10
  tetra init
11
11
 
12
12
  cd src
@@ -27,7 +27,19 @@ cd src/commons-collections/commons-collections-3.2.1-src/
27
27
  tetra mvn package -DskipTests
28
28
  tetra finish
29
29
 
30
- tetra generate-all
30
+ tetra generate-kit-archive
31
+ tetra generate-kit-spec
32
+ tetra generate-package-archive
33
+ tetra generate-package-spec
34
+ # simulate tetra generate-package-script
35
+ cat >../../../output/commons-collections/build.sh <<"EOF"
36
+ #!/bin/bash
37
+ PROJECT_PREFIX=`readlink -e .`
38
+ cd .
39
+ cd src/commons-collections/commons-collections-3.2.1-src/
40
+ $PROJECT_PREFIX/kit/apache-maven-3.1.1/bin/mvn -Dmaven.repo.local=$PROJECT_PREFIX/kit/m2 -s$PROJECT_PREFIX/kit/m2/settings.xml -o package -DskipTests
41
+ EOF
42
+
31
43
  cd ../../..
32
44
 
33
45
  cd src
@@ -44,9 +56,17 @@ tetra finish
44
56
 
45
57
  tetra generate-kit-archive
46
58
  tetra generate-kit-spec
47
- tetra generate-package-script
48
59
  tetra generate-package-archive
49
60
  tetra generate-package-spec
61
+ # simulate tetra generate-package-script
62
+ cat >../../../output/commons-fileupload/build.sh <<"EOF"
63
+ #!/bin/bash
64
+ PROJECT_PREFIX=`readlink -e .`
65
+ cd .
66
+ cd src/commons-fileupload/commons-fileupload-1.3-src/
67
+ $PROJECT_PREFIX/kit/apache-maven-3.1.1/bin/mvn -Dmaven.repo.local=$PROJECT_PREFIX/kit/m2 -s$PROJECT_PREFIX/kit/m2/settings.xml -o package -DskipTests
68
+ EOF
69
+
50
70
  cd ../../..
51
71
 
52
72
 
@@ -0,0 +1,21 @@
1
+ #!/bin/bash
2
+
3
+ # A crude integration test that tries OBS building
4
+ # assumes an OpenSUSE host is set up with passwordless SSH access
5
+ # assumes this host has osc installed and properly configured in sudoers
6
+ # assumes that a project directory exists
7
+
8
+ set -e
9
+
10
+ OBS_HOST=obs-client
11
+ OBS_PROJECT_DIR=/home/silvio/obs/home\:SilvioMoioli
12
+
13
+ scp -r commons/output/* $OBS_HOST:/$OBS_PROJECT_DIR
14
+ ssh -t $OBS_HOST <<EOF
15
+ cd $OBS_PROJECT_DIR/commons-kit/ &&\
16
+ osc build -k../rpms -p../rpms &&\
17
+ cd ../commons-collections/ &&\
18
+ osc build -k../rpms -p../rpms &&\
19
+ cd ../commons-fileupload/ &&\
20
+ osc build -k../rpms -p../rpms
21
+ EOF
@@ -0,0 +1,53 @@
1
+ #
2
+ # spec file for a build-time dependency of project "<%= project.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
+ Name: <%= package_name %>
16
+ Version: 1
17
+ Release: 1
18
+ License: SUSE-NonFree
19
+ Summary: Build-time dependency of project "<%= project.name %>"
20
+ Url: https://github.com/SilvioMoioli/tetra
21
+ Group: Development/Libraries/Java
22
+ Source0: %{name}.tar.xz
23
+ BuildRoot: %{_tmppath}/%{name}-%{version}-build
24
+ BuildArch: noarch
25
+ BuildRequires: xz
26
+ Provides: <%= provides_symbol %> == <%= provides_version %>
27
+ <% if conflicts %>
28
+ Conflicts: otherproviders(<%= provides_symbol %>)
29
+ <% end %>
30
+
31
+ %description
32
+ This package has been automatically created by tetra in order to
33
+ satisfy build time dependencies of Java packages.
34
+ It should not be used except for rebuilding other packages,
35
+ thus it should never be installed on end users' systems.
36
+
37
+ %prep
38
+ %setup -q -c
39
+
40
+ %build
41
+ # nothing to do, precompiled by design
42
+
43
+ %install
44
+ export NO_BRP_CHECK_BYTECODE_VERSION=true
45
+ install -d -m 0755 %{buildroot}%{_datadir}/tetra/<%= install_dir %>
46
+ cp -a * %{buildroot}%{_datadir}/tetra/<%= install_dir %>
47
+
48
+ %files
49
+ %defattr(-,root,root)
50
+ %{_datadir}/tetra
51
+ %{_datadir}/tetra/<%= install_dir %>
52
+
53
+ %changelog
@@ -27,7 +27,9 @@ Source1: build.sh
27
27
  BuildRoot: %{_tmppath}/%{name}-%{version}-build
28
28
  BuildRequires: xz
29
29
  BuildRequires: java-devel
30
- BuildRequires: <%= project_name %>-kit >= <%= project_version %>
30
+ <% kit_items.each do |item| %>
31
+ BuildRequires: <%= item.provides_symbol %> == <%= item.provides_version %>
32
+ <% end %>
31
33
  BuildArch: noarch
32
34
  Provides: mvn(<%= group_id %>:<%= artifact_id %>) == <%= version %>
33
35
  Requires: java
@@ -43,7 +45,7 @@ Requires: mvn(<%= dependency_id[0] %>:<%= dependency_id[1] %>) <% if depen
43
45
  %prep
44
46
  %setup -q -c -n src/<%= name %>
45
47
  cp -f %{SOURCE1} .
46
- cp -Rf %{_datadir}/tetra/<%= project_name %>-kit ../../kit
48
+ cp -Rf %{_datadir}/tetra ../../kit
47
49
 
48
50
  %build
49
51
  cd ../../
data/lib/tetra.rb CHANGED
@@ -22,7 +22,6 @@ require "zip"
22
22
  # internal, backend
23
23
  require "tetra/version"
24
24
  require "tetra/logger"
25
- require "tetra/template_manager"
26
25
  require "tetra/git"
27
26
  require "tetra/script_generator"
28
27
  require "tetra/project"
@@ -34,10 +33,13 @@ require "tetra/source_getter"
34
33
  require "tetra/kit_runner"
35
34
  require "tetra/ant_runner"
36
35
  require "tetra/maven_runner"
37
- require "tetra/kit_spec_adapter"
38
- require "tetra/package_spec_adapter"
39
36
  require "tetra/spec_generator"
40
37
  require "tetra/archiver"
38
+ require "tetra/maven_kit_item"
39
+ require "tetra/jar_kit_item"
40
+ require "tetra/glue_kit_item"
41
+ require "tetra/kit"
42
+ require "tetra/package"
41
43
  require "tetra/kit_checker"
42
44
 
43
45
  # internal, UI
@@ -1,94 +1,30 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  module Tetra
4
- # generates file archives that accompany spec files
5
- class Archiver
4
+ # implements a to_archive method
5
+ module Archiver
6
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))
7
+ # expected attributes:
8
+ # project (Tetra::Project)
9
+ # package_name (string)
10
+ # source_dir (string)
11
+ # source_paths ([string])
12
+ # destination_dir (string)
13
+
14
+ # generates an archive and returns its name
15
+ # this will archive source_paths starting from source_dir in
16
+ # destination_dir + package_name + extension
17
+ def to_archive
18
+ full_destination_dir = File.join(project.full_path, "output", destination_dir)
19
+ FileUtils.mkdir_p(full_destination_dir)
20
+
21
+ project.from_directory(source_dir) do
22
+ destination_path = File.join(full_destination_dir, "#{package_name}.tar.xz")
23
+ log.debug "creating #{destination_path}"
24
+
25
+ `tar -cJf #{destination_path} #{source_paths.join(" ")}`
26
+
27
+ destination_path
92
28
  end
93
29
  end
94
30
  end
@@ -4,7 +4,6 @@ module Tetra
4
4
  # tetra generate-all
5
5
  class GenerateAllCommand < Tetra::BaseCommand
6
6
  option %w(-f --filter), "FILTER", "filter files to be installed by this package spec", default: "*.jar"
7
- option %w(-w --whole), :flag, "recreate the whole archive (not incremental)"
8
7
  parameter "[DIRECTORY]", "path to a package directory (src/<package name>)", default: "."
9
8
  parameter "[POM]", "a package pom file path", default: "pom.xml"
10
9
 
@@ -12,25 +11,23 @@ module Tetra
12
11
  checking_exceptions do
13
12
  project = Tetra::Project.new(".")
14
13
  ensure_dry_running(false, project) do
15
- package_name = project.get_package_name(directory)
14
+ GenerateKitArchiveCommand.new(@invocation_path).execute
16
15
 
17
- result_path = Tetra::Archiver.new(project).archive_kit(whole?)
18
- print_generation_result(project, result_path)
16
+ GenerateKitSpecCommand.new(@invocation_path).execute
19
17
 
20
- result_path, conflict_count = Tetra::SpecGenerator.new(project).generate_kit_spec
21
- print_generation_result(project, result_path, conflict_count)
18
+ script_command = GeneratePackageScriptCommand.new(@invocation_path)
19
+ script_command.directory = directory
20
+ script_command.execute
22
21
 
23
- history_file = File.join(Dir.home, ".bash_history")
24
- result_path, conflict_count = Tetra::ScriptGenerator.new(project, history_file)
25
- .generate_build_script(package_name)
26
- print_generation_result(project, result_path, conflict_count)
22
+ archive_command = GeneratePackageArchiveCommand.new(@invocation_path)
23
+ archive_command.directory = directory
24
+ archive_command.execute
27
25
 
28
- result_path = Tetra::Archiver.new(project).archive_package package_name
29
- print_generation_result(project, result_path)
30
-
31
- result_path, conflict_count = Tetra::SpecGenerator.new(project)
32
- .generate_package_spec package_name, pom, filter
33
- print_generation_result(project, result_path, conflict_count)
26
+ archive_command = GeneratePackageSpecCommand.new(@invocation_path)
27
+ archive_command.filter = filter
28
+ archive_command.directory = directory
29
+ archive_command.pom = pom
30
+ archive_command.execute
34
31
  end
35
32
  end
36
33
  end