tetra 1.2.2 → 2.0.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 (52) hide show
  1. data/CONTRIBUTING.md +11 -0
  2. data/Gemfile.lock +24 -2
  3. data/README.md +11 -16
  4. data/SPECIAL_CASES.md +15 -2
  5. data/lib/template/kit.spec +2 -0
  6. data/lib/template/package.spec +2 -2
  7. data/lib/tetra.rb +4 -1
  8. data/lib/tetra/facades/bash.rb +6 -2
  9. data/lib/tetra/facades/git.rb +35 -20
  10. data/lib/tetra/facades/process_runner.rb +2 -0
  11. data/lib/tetra/facades/tar.rb +14 -0
  12. data/lib/tetra/facades/unzip.rb +14 -0
  13. data/lib/tetra/packages/package.rb +2 -1
  14. data/lib/tetra/project.rb +25 -88
  15. data/lib/tetra/project_initer.rb +90 -0
  16. data/lib/tetra/ui/change_sources_subcommand.rb +32 -0
  17. data/lib/tetra/ui/dry_run_subcommand.rb +5 -4
  18. data/lib/tetra/ui/generate_all_subcommand.rb +0 -2
  19. data/lib/tetra/ui/generate_spec_subcommand.rb +1 -0
  20. data/lib/tetra/ui/init_subcommand.rb +25 -4
  21. data/lib/tetra/ui/main.rb +6 -6
  22. data/lib/tetra/ui/patch_subcommand.rb +2 -2
  23. data/lib/tetra/ui/subcommand.rb +1 -1
  24. data/lib/tetra/version.rb +1 -1
  25. data/spec/data/commons-collections-3.2.1-src.tar.gz +0 -0
  26. data/{integration-tests → spec/data}/commons-collections-3.2.1-src.zip +0 -0
  27. data/spec/lib/coarse/dry_run_subcommand_spec.rb +31 -0
  28. data/spec/lib/coarse/generate_all_subcommand_spec.rb +128 -0
  29. data/spec/lib/coarse/generate_spec_subcommand_spec.rb +29 -0
  30. data/spec/lib/coarse/init_subcommand_spec.rb +85 -0
  31. data/spec/lib/coarse/main_spec.rb +19 -0
  32. data/spec/lib/{ant_spec.rb → fine/ant_spec.rb} +0 -0
  33. data/spec/lib/{git_spec.rb → fine/git_spec.rb} +54 -6
  34. data/spec/lib/{kit_package_spec.rb → fine/kit_package_spec.rb} +0 -0
  35. data/spec/lib/{kit_spec.rb → fine/kit_spec.rb} +0 -0
  36. data/spec/lib/{maven_website_spec.rb → fine/maven_website_spec.rb} +0 -0
  37. data/spec/lib/{mvn_spec.rb → fine/mvn_spec.rb} +0 -0
  38. data/spec/lib/{package_spec.rb → fine/package_spec.rb} +7 -0
  39. data/spec/lib/{pom_getter_spec.rb → fine/pom_getter_spec.rb} +0 -0
  40. data/spec/lib/{pom_spec.rb → fine/pom_spec.rb} +0 -0
  41. data/spec/lib/{project_spec.rb → fine/project_spec.rb} +1 -39
  42. data/spec/lib/{scriptable_spec.rb → fine/scriptable_spec.rb} +0 -0
  43. data/spec/lib/{speccable_spec.rb → fine/speccable_spec.rb} +0 -0
  44. data/spec/lib/fine/tar_spec.rb +22 -0
  45. data/spec/lib/fine/unzip_spec.rb +22 -0
  46. data/spec/lib/{version_matcher_spec.rb → fine/version_matcher_spec.rb} +0 -0
  47. data/spec/spec_helper.rb +19 -2
  48. data/tetra.gemspec +1 -0
  49. metadata +45 -19
  50. data/integration-tests/build-commons.sh +0 -30
  51. data/lib/template/gitignore +0 -2
  52. data/lib/tetra/ui/generate_archive_subcommand.rb +0 -16
@@ -0,0 +1,90 @@
1
+ # encoding: UTF-8
2
+
3
+ module Tetra
4
+ # takes care of intiializing a tetra project
5
+ module ProjectIniter
6
+ include Logging
7
+
8
+ # path of the project template files
9
+ TEMPLATE_PATH = File.join(File.dirname(__FILE__), "..", "template")
10
+
11
+ # includers get class methods defined in ClassMethods
12
+ def self.included(base)
13
+ base.extend(ClassMethods)
14
+ end
15
+ # class methods container
16
+ module ClassMethods
17
+ # returns true if the specified directory is a valid tetra project
18
+ def project?(dir)
19
+ Tetra::Logger.instance.debug "Checking for tetra project: #{dir}, contents: #{Dir.new(dir).to_a}"
20
+ File.directory?(File.join(dir, "src")) &&
21
+ File.directory?(File.join(dir, "kit")) &&
22
+ File.directory?(File.join(dir, ".git"))
23
+ end
24
+
25
+ # inits a new project directory structure
26
+ def init(dir, include_bundled_software = true)
27
+ Dir.mkdir(dir)
28
+ Dir.chdir(dir) do
29
+ git = Tetra::Git.new(".")
30
+
31
+ git.init
32
+
33
+ FileUtils.mkdir_p("src")
34
+ FileUtils.mkdir_p("kit")
35
+
36
+ # populate the project with templates and commit it
37
+ project = Project.new(".")
38
+
39
+ project.template_files(include_bundled_software).each do |source, destination|
40
+ FileUtils.cp_r(File.join(TEMPLATE_PATH, source), destination)
41
+ end
42
+
43
+ git.commit_directories(["."], "Template files added")
44
+ end
45
+ end
46
+ end
47
+
48
+ # returns a hash that maps filenames that should be copied from TEMPLATE_PATH
49
+ # to the value directory
50
+ def template_files(include_bundled_software)
51
+ result = {
52
+ "kit" => ".",
53
+ "packages" => ".",
54
+ "src" => "."
55
+ }
56
+
57
+ if include_bundled_software
58
+ Dir.chdir(TEMPLATE_PATH) do
59
+ Dir.glob(File.join("bundled", "*")).each do |file|
60
+ result[file] = "kit"
61
+ end
62
+ end
63
+ end
64
+
65
+ result
66
+ end
67
+
68
+ # adds a source archive at the project, both in original and unpacked forms
69
+ def commit_source_archive(file, message)
70
+ from_directory do
71
+ result_dir = File.join(packages_dir, name)
72
+ FileUtils.mkdir_p(result_dir)
73
+
74
+ result_path = File.join(result_dir, File.basename(file))
75
+ FileUtils.cp(file, result_path)
76
+ @git.commit_file(result_path, "Source archive added")
77
+
78
+ unarchiver = if file =~ /\.zip$/
79
+ Tetra::Unzip.new
80
+ else
81
+ Tetra::Tar.new
82
+ end
83
+
84
+ Dir.glob(File.join("src", "*")).each { |f| FileUtils.rm_rf(f) }
85
+ unarchiver.decompress(file, "src")
86
+ commit_sources(message, true)
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: UTF-8
2
+
3
+ module Tetra
4
+ # tetra change-sources
5
+ class ChangeSourcesSubcommand < Tetra::Subcommand
6
+ parameter "[SOURCE_ARCHIVE]", "new source tarball or zipfile"
7
+ parameter "[MESSAGE]", "a short change description", default: "Sources changed"
8
+ option %w(-n --no-archive), :flag, "use current src/ contents instead of an archive (see SPECIAL_CASES.md)",
9
+ default: false
10
+
11
+ def execute
12
+ if source_archive.nil? && no_archive? == false
13
+ signal_usage_error "please specify a source archive file or use \"--no-archive\" (see SPECIAL_CASES.md)."
14
+ end
15
+
16
+ checking_exceptions do
17
+ project = Tetra::Project.new(".")
18
+ ensure_dry_running(:is_not_in_progress, project) do
19
+ if no_archive? == false
20
+ project.commit_source_archive(File.expand_path(source_archive), message)
21
+ puts "New sources committed."
22
+ puts "Please delete any stale source archives from packages/ before proceeding."
23
+ else
24
+ project.commit_sources(message, true)
25
+ puts "New sources committed."
26
+ puts "Please copy source archive(s) corresponding to src/ in packages/ before proceeding."
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -7,10 +7,11 @@ module Tetra
7
7
  checking_exceptions do
8
8
  project = Tetra::Project.new(".")
9
9
 
10
- if project.src_patched? && !project.first_dry_run
11
- puts "Some files in src/ were changed since last dry-run,"
12
- puts "use \"tetra patch message\" to include changes in a patch before dry-running."
13
- puts "Dry run not started"
10
+ if project.src_patched?
11
+ puts "Changes detected in src/, please use:"
12
+ puts " \"tetra patch\" to include those changes in the package as a patch file"
13
+ puts " \"tetra change-sources\" to completely swap the source archive."
14
+ puts "Dry run not started."
14
15
  else
15
16
  project.dry_run
16
17
  puts "Dry-run started in a new bash shell."
@@ -14,8 +14,6 @@ module Tetra
14
14
 
15
15
  GenerateScriptSubcommand.new(@invocation_path).execute
16
16
 
17
- GenerateArchiveSubcommand.new(@invocation_path).execute
18
-
19
17
  command = GenerateSpecSubcommand.new(@invocation_path)
20
18
  command.filter = filter
21
19
  command.pom = pom
@@ -20,6 +20,7 @@ module Tetra
20
20
  result_path, conflict_count = package.to_spec
21
21
  print_generation_result(project, result_path, conflict_count)
22
22
  puts "Warning: #{pom} not found, some spec fields will be left blank" unless File.file?(pom)
23
+ puts "Warning: source archive not found, package will not build" unless project.src_archive
23
24
  end
24
25
  end
25
26
  end
@@ -3,12 +3,33 @@
3
3
  module Tetra
4
4
  # tetra init
5
5
  class InitSubcommand < Tetra::Subcommand
6
+ parameter "PACKAGE_NAME", "name of the package to create"
7
+ parameter "[SOURCE_ARCHIVE]", "source tarball or zipfile"
8
+ option %w(-n --no-archive), :flag, "create a project without a source archive (see SPECIAL_CASES.md)",
9
+ default: false
10
+
6
11
  def execute
7
12
  checking_exceptions do
8
- Tetra::Project.init(".")
9
- puts "Project inited."
10
- puts "Add sources to src/, binary dependencies to kit/."
11
- puts "When you are ready to test a build, use \"tetra dry-run\""
13
+ if source_archive.nil? && no_archive? == false
14
+ signal_usage_error "please specify a source archive file or use \"--no-archive\" (see SPECIAL_CASES.md)."
15
+ end
16
+ if !source_archive.nil? && !File.readable?(source_archive)
17
+ signal_usage_error "#{source_archive} is not a file or it is not readable."
18
+ end
19
+
20
+ Tetra::Project.init(package_name)
21
+ project = Tetra::Project.new(package_name)
22
+ puts "Project inited in #{package_name}/."
23
+
24
+ if source_archive
25
+ puts "Decompressing sources..."
26
+ project.commit_source_archive(File.expand_path(source_archive), "Inital sources added from archive")
27
+ puts "Sources decompressed in #{package_name}/src/, original archive copied in #{package_name}/packages/."
28
+ else
29
+ puts "Use \"tetra change-sources\" to add sources to this project."
30
+ end
31
+ puts "Please add any other precompiled build dependency to kit/."
32
+ puts "When you are ready to test a build, use \"tetra dry-run\" from the project directory"
12
33
  end
13
34
  end
14
35
  end
@@ -27,12 +27,6 @@ module Tetra
27
27
  Tetra::GenerateScriptSubcommand
28
28
  )
29
29
 
30
- subcommand(
31
- "generate-archive",
32
- "Create or refresh the package tarball",
33
- Tetra::GenerateArchiveSubcommand
34
- )
35
-
36
30
  subcommand(
37
31
  "generate-spec",
38
32
  "Create or refresh the package spec file",
@@ -51,6 +45,12 @@ module Tetra
51
45
  Tetra::PatchSubcommand
52
46
  )
53
47
 
48
+ subcommand(
49
+ "change-sources",
50
+ "Swaps the sources for this package with new ones",
51
+ Tetra::ChangeSourcesSubcommand
52
+ )
53
+
54
54
  subcommand(
55
55
  "move-jars-to-kit",
56
56
  "Locates jars in src/ and moves them to kit/",
@@ -3,14 +3,14 @@
3
3
  module Tetra
4
4
  # tetra patch
5
5
  class PatchSubcommand < Tetra::Subcommand
6
- option %w(-n --new-tarball), :flag, "suppress patch creation, roll all changes so far in the tarball"
7
6
  parameter "[MESSAGE]", "a short patch description", default: "Sources updated"
8
7
 
9
8
  def execute
10
9
  checking_exceptions do
11
10
  project = Tetra::Project.new(".")
12
11
  ensure_dry_running(:is_not_in_progress, project) do
13
- project.commit_sources(message, new_tarball?)
12
+ project.commit_sources(message, false)
13
+ puts "Patch recorded, use \"tetra generate-spec\" to update the specfile"
14
14
  end
15
15
  end
16
16
  end
@@ -95,7 +95,7 @@ module Tetra
95
95
  rescue Errno::EEXIST => e
96
96
  $stderr.puts e
97
97
  rescue NoProjectDirectoryError => e
98
- $stderr.puts "#{e.directory} is not a tetra project directory, see tetra init"
98
+ $stderr.puts "#{e.directory} is not a tetra project directory, see \"tetra init\""
99
99
  rescue GitAlreadyInitedError
100
100
  $stderr.puts "This directory is already a tetra project"
101
101
  rescue ExecutionFailed => e
@@ -2,5 +2,5 @@
2
2
 
3
3
  # base module for tetra
4
4
  module Tetra
5
- VERSION = "1.2.2"
5
+ VERSION = "2.0.0"
6
6
  end
@@ -0,0 +1,31 @@
1
+ require "spec_helper"
2
+
3
+ describe "`tetra dry-run`", type: :aruba do
4
+ it "does not start a dry-run if init has not run yet" do
5
+ run_simple("tetra dry-run")
6
+
7
+ expect(stderr_from("tetra dry-run")).to include("is not a tetra project directory")
8
+ end
9
+
10
+ it "does a dry-run build" do
11
+ run_simple("tetra init --no-archive mypackage")
12
+ cd("mypackage")
13
+
14
+ run_interactive("tetra dry-run")
15
+ type("echo ciao")
16
+ type("echo ciao > ciao.jar")
17
+ type("\u{0004}") # ^D (Ctrl+D), terminates bash with exit status 0
18
+
19
+ expect(all_output).to include("Dry-run started")
20
+ expect(all_output).to include("ciao")
21
+ expect(all_output).to include("Dry-run finished")
22
+
23
+ # check that markers were written in git repo
24
+ run_simple("git rev-list --format=%B --max-count=1 HEAD~")
25
+ expect(stdout_from("git rev-list --format=%B --max-count=1 HEAD~")).to include("tetra: dry-run-started")
26
+
27
+ run_simple("git rev-list --format=%B --max-count=1 HEAD")
28
+ expect(stdout_from("git rev-list --format=%B --max-count=1 HEAD")).to include("tetra: dry-run-finished")
29
+ expect(stdout_from("git rev-list --format=%B --max-count=1 HEAD")).to include("tetra: build-script-line: echo ciao")
30
+ end
31
+ end
@@ -0,0 +1,128 @@
1
+ require "spec_helper"
2
+
3
+ describe "`tetra generate-all`", type: :aruba do
4
+ it "generates specs and tarballs for a sample package, source archive workflow" do
5
+ archive_contents = File.read(File.join("spec", "data", "commons-collections-3.2.1-src.zip"))
6
+ write_file("commons-collections.zip", archive_contents)
7
+
8
+ # init project
9
+ run_simple("tetra init commons-collections commons-collections.zip")
10
+ cd(File.join("commons-collections", "src", "commons-collections-3.2.1-src"))
11
+
12
+ # first dry-run, all normal
13
+ @aruba_timeout_seconds = 120
14
+ run_interactive("tetra dry-run --very-very-verbose")
15
+ type("mvn package -DskipTests")
16
+ type("\u{0004}") # ^D (Ctrl+D), terminates bash with exit status 0
17
+
18
+ expect(all_output).to include("[INFO] BUILD SUCCESS")
19
+ expect(all_output).to include("Checking for tetra project")
20
+
21
+ # first generate-all, all normal
22
+ run_simple("tetra generate-all")
23
+
24
+ expect(output_from("tetra generate-all")).to include("commons-collections-kit.spec generated")
25
+ expect(output_from("tetra generate-all")).to include("commons-collections-kit.tar.xz generated")
26
+ expect(output_from("tetra generate-all")).to include("build.sh generated")
27
+ expect(output_from("tetra generate-all")).to include("commons-collections.spec generated")
28
+
29
+ # patch one file
30
+ append_to_file("README.txt", "patched by tetra test")
31
+
32
+ # second dry-run fails: sources changed
33
+ run_simple("tetra dry-run")
34
+ expect(output_from("tetra dry-run")).to include("Changes detected in src")
35
+ expect(output_from("tetra dry-run")).to include("Dry run not started")
36
+
37
+ # run patch
38
+ run_simple("tetra patch")
39
+
40
+ # third dry-run succeeds with patch
41
+ run_interactive("tetra dry-run")
42
+ type("mvn package -DskipTests")
43
+ type("\u{0004}") # ^D (Ctrl+D), terminates bash with exit status 0
44
+
45
+ expect(all_output).to include("[INFO] BUILD SUCCESS")
46
+
47
+ run_simple("tetra generate-all --very-very-verbose")
48
+
49
+ expect(output_from("tetra generate-all --very-very-verbose")).to include("commons-collections-kit.spec generated")
50
+ expect(output_from("tetra generate-all --very-very-verbose")).to include("commons-collections-kit.tar.xz generated")
51
+ expect(output_from("tetra generate-all --very-very-verbose")).to include("build.sh generated")
52
+ expect(output_from("tetra generate-all --very-very-verbose")).to include("commons-collections.spec generated")
53
+ expect(output_from("tetra generate-all --very-very-verbose")).to include("0001-Sources-updated.patch generated")
54
+
55
+ with_file_content("../../packages/commons-collections/commons-collections.spec") do |content|
56
+ expect(content).to include("0001-Sources-updated.patch")
57
+ end
58
+ end
59
+
60
+ it "generates specs and tarballs for a sample package, manual source workflow" do
61
+ archive_contents = File.read(File.join("spec", "data", "commons-collections-3.2.1-src.zip"))
62
+ write_file("commons-collections.zip", archive_contents)
63
+
64
+ # init project
65
+ run_simple("tetra init -n commons-collections")
66
+
67
+ # add sources
68
+ run_simple("unzip commons-collections.zip -d commons-collections/src")
69
+
70
+ cd("commons-collections")
71
+
72
+ # first dry-run fails: sources changed
73
+ run_simple("tetra dry-run")
74
+ expect(output_from("tetra dry-run")).to include("Changes detected in src")
75
+ expect(output_from("tetra dry-run")).to include("Dry run not started")
76
+
77
+ # run change-sources
78
+ run_simple("tetra change-sources ../commons-collections.zip")
79
+ expect(output_from("tetra change-sources ../commons-collections.zip")).to include("New sources committed")
80
+
81
+ # second dry-run, all normal
82
+ cd(File.join("src", "commons-collections-3.2.1-src"))
83
+ @aruba_timeout_seconds = 120
84
+ run_interactive("tetra dry-run")
85
+ type("mvn package -DskipTests")
86
+ type("\u{0004}") # ^D (Ctrl+D), terminates bash with exit status 0
87
+
88
+ expect(all_output).to include("[INFO] BUILD SUCCESS")
89
+
90
+ # first generate-all, all normal
91
+ run_simple("tetra generate-all")
92
+
93
+ expect(output_from("tetra generate-all")).to include("commons-collections-kit.spec generated")
94
+ expect(output_from("tetra generate-all")).to include("commons-collections-kit.tar.xz generated")
95
+ expect(output_from("tetra generate-all")).to include("build.sh generated")
96
+ expect(output_from("tetra generate-all")).to include("commons-collections.spec generated")
97
+
98
+ # patch one file
99
+ append_to_file("README.txt", "patched by tetra test")
100
+
101
+ # second dry-run fails: sources changed
102
+ run_simple("tetra dry-run")
103
+ expect(output_from("tetra dry-run")).to include("Changes detected in src")
104
+ expect(output_from("tetra dry-run")).to include("Dry run not started")
105
+
106
+ # run patch
107
+ run_simple("tetra patch")
108
+
109
+ # third dry-run succeeds with patch
110
+ run_interactive("tetra dry-run")
111
+ type("mvn package -DskipTests")
112
+ type("\u{0004}") # ^D (Ctrl+D), terminates bash with exit status 0
113
+ expect(all_output).to include("[INFO] BUILD SUCCESS")
114
+
115
+ run_simple("tetra generate-all")
116
+
117
+ expect(output_from("tetra generate-all")).to include("commons-collections-kit.spec generated")
118
+ expect(output_from("tetra generate-all")).to include("commons-collections-kit.tar.xz generated")
119
+ expect(output_from("tetra generate-all")).to include("build.sh generated")
120
+ expect(output_from("tetra generate-all")).to include("commons-collections.spec generated")
121
+ expect(output_from("tetra generate-all")).to include("0001-Sources-updated.patch generated")
122
+
123
+ with_file_content("../../packages/commons-collections/commons-collections.spec") do |content|
124
+ expect(content).to include("0001-Sources-updated.patch")
125
+ expect(content).to include("commons-collections.zip")
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+
3
+ describe "`tetra generate-spec`", type: :aruba do
4
+ it "outputs a warning if source files are not found" do
5
+ archive_contents = File.read(File.join("spec", "data", "commons-collections-3.2.1-src.zip"))
6
+ write_file("commons-collections.zip", archive_contents)
7
+
8
+ run_simple("tetra init --no-archive commons-collections")
9
+ cd("commons-collections")
10
+
11
+ cd("src")
12
+ run_simple("unzip ../../commons-collections.zip")
13
+ cd("commons-collections-3.2.1-src")
14
+
15
+ run_simple("tetra change-sources --no-archive")
16
+ expect(output_from("tetra change-sources --no-archive")).to include("New sources committed")
17
+
18
+ @aruba_timeout_seconds = 120
19
+ run_interactive("tetra dry-run")
20
+ type("mvn package -DskipTests")
21
+ type("\u{0004}") # ^D (Ctrl+D), terminates bash with exit status 0
22
+
23
+ expect(all_output).to include("[INFO] BUILD SUCCESS")
24
+
25
+ run_simple("tetra generate-spec")
26
+
27
+ expect(output_from("tetra generate-spec")).to include("Warning: source archive not found, package will not build")
28
+ end
29
+ end