source: users/jberry/mpwa/app/controllers/ports_controller.rb @ 23606

Last change on this file since 23606 was 23606, checked in by jberry@…, 13 years ago

Begin reorg of mpwa hierarchy to match revised design

File size: 5.7 KB
Line 
1require "fileutils"
2
3class PortsController < ApplicationController
4 
5    def makeTempDir()
6        tmpdir = Dir::tmpdir
7        basename = "macports"
8        n = 1
9        begin
10            tmpname = File.join(tmpdir, sprintf('%s.%d.%d', basename, $$, n))
11            n += 1
12            next if File.exist?(tmpname)
13            begin
14                Dir.mkdir(tmpname)
15            rescue SystemCallError
16                next
17            end
18        end while !File.exist?(tmpname)
19        return tmpname
20    end
21
22    def subversionCommand(args)
23        `#{svn} #{args}`
24    end
25
26    def ensureRepositoryPath(root, path)
27        # Make sure the root director exists
28        assert { File.directory?(root) }
29       
30        # Step through path, building each component that doesn't exist
31        Pathname.new(path).descend do |p|
32            full = Pathname.new(root) + p
33            if !full.directory?
34                full.mkdir
35                subversionCommand("add #{full}")
36                subversionCommand("commit -m 'Make repository path segment' #{full}")
37             end
38        end
39    end
40   
41    def submit
42        # TODO:
43        # => Move some of this into the model
44        # => And/or break up into more methods
45       
46        # Get and validate parameters
47        @portName = params[:portname]
48        @portpkg = params[:portpkg]
49       
50        # Validate parameters (we're probably making this too hard)
51        raise "bad portName" if @portName.nil?
52        raise "bad package" if @portpkg.nil?
53       
54        tempDir = makeTempDir
55        portpkg = "#{tempDir}/portpkg.tgz"
56        pkgdir = "#{tempDir}/portpkg"
57        common = "#{tempDir}/common"
58        target = "#{tempDir}/target"
59
60        # Form partial path to the common directory for the portname
61        firstChar = @portName[0,1].downcase
62        commonPartial = "common/#{firstChar}/#{@portName}"
63       
64        # Look for, and create if not found, the common directory for the port
65        ensureRepositoryPath(repo_port, commonPartial)
66       
67        # Unpack the submitted portdir into a temporary directory
68        File.open(portpkg, "w") { |f| f.write(@portpkg.read) }       
69        system("#{tar} -C #{tempDir} -zf #{portpkg} -x portpkg")
70       
71        # Check out a private temporary copy of the common directory
72        # so that we don't get into concurrency issues by multi-modifying the directory
73        subversionCommand("co #{repo_port_url}/#{commonPartial} #{common}")
74       
75        # Sync the submission into the common directory by parsing the results of mtree
76        changeCnt = 0
77        treeOut = `#{mtree} -c -k type,cksum -p #{pkgdir} | #{mtree} -p #{common}`
78        treeOut.each_line do |line|
79            puts "Line #{line}"
80           
81            case line
82            when /^\w+/
83                puts "Whitespace line #$1"
84               
85            when /^(.*) changed$/
86                srcFile = File.join(pkgdir, $1)
87                dstFile = File.join(common, $1)
88                puts "Changed file #{srcFile} != #{dstFile}"
89                FileUtils.cp(srcFile, dstFile)
90                changeCnt += 1
91               
92            when /^(.*) extra$/
93                dstFile = File.join(common, $1)
94                if /^\./ =~ File.basename(dstFile)
95                    puts "Skipping invisible extra entry #{dstFile}"
96                else
97                    puts "Extra entry #{dstFile}"
98                    subversionCommand("rm #{dstFile}")
99                    changeCnt += 1
100               end
101               
102            when /^(.*) missing$/
103                srcFile = File.join(pkgdir, $1)
104                dstFile = File.join(common, $1)
105
106                if /^\./ =~ File.basename(dstFile)
107                    puts "Skipping invisible new entry #{dstFile}"
108                else
109                    puts "New entry #{srcFile} ==> #{dstFile}"
110 
111                    if File.directory?(srcFile)
112                        subversionCommand("mkdir #{dstFile}")
113                    else
114                        FileUtils.cp(srcFile, dstFile)
115                        subversionCommand("add #{dstFile}")
116                    end
117                   
118                    changeCnt += 1
119                end
120
121            end
122        end
123       
124        if changeCnt == 0
125            puts "No changes detected, so don't create a new submission"
126        else
127            puts "Creating new submission from #{common}"
128
129            # Commit changes to the common directory
130            commitOutput = subversionCommand("commit -m 'New submission of #{@portName}' #{common}")
131            commitRevision = /^Committed revision (\d+)./.match(commitOutput)[1]
132           
133            # Form the portid from the committed revision number
134            portid = commitRevision
135           
136    return
137            puts "Creating new submission #{commitRevision} at #{repo_port}/#{commitRevision}"
138   
139            # Make the target directory structure
140            subversionCommand("mkdir -m 'Create new submission #{commitRevision} of port #{@portName}' #{submission_url}/#{commitRevision}")
141   
142            # Check out the submission directory
143            subversionCommand("co #{submission_url}/#{commitRevision} #{target}")
144   
145            # Add original package and meta directory
146            FileUtils.cp(package, "#{target}/port.tgz")
147            FileUtils.mkdir("#{target}/meta")
148            subversionCommand("add #{target}/port.tgz #{target}/meta")
149   
150            # Copy over the common directory into unpacked
151            subversionCommand("cp #{common} #{target}/unpacked")
152   
153            # Commit the submission directory
154            subversionCommand("commit -m 'Complete submission #{commitRevision} of port #{@portName}' #{target}")
155        end
156    end
157 
158end
Note: See TracBrowser for help on using the repository browser.