fig18 0.1.45-i386-mingw32

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.
@@ -0,0 +1,116 @@
1
+ require 'ostruct'
2
+ require 'set'
3
+
4
+ require 'fig/logging'
5
+
6
+ # This class copies files from the project directories in ~/.fighome to the
7
+ # user's working directory. It keeps track of which files have already been copied, and which
8
+ # package/versions they came from, and deletes files as necessary to ensure that
9
+ # we never have files from two different versions of the same package in the user's
10
+ # working directory.
11
+ class Retriever
12
+ def initialize(base_dir)
13
+ @base_dir = base_dir
14
+ @configs = {}
15
+ @fig_dir = File.join(@base_dir, '.fig')
16
+
17
+ file = File.join(@fig_dir, 'retrieve')
18
+ if File.exist?(file)
19
+ load(file)
20
+ end
21
+ end
22
+
23
+ def with_package_config(name, version)
24
+ if name and version
25
+ @config = @configs[name]
26
+ if @config && @config.version != version
27
+ @config.files.each do |relpath|
28
+ Fig::Logging.info "- [#{@config.name}/#{@config.version}] #{relpath}"
29
+ FileUtils.rm_f(File.join(@base_dir, relpath))
30
+ end
31
+ @config = nil
32
+ end
33
+ if not @config
34
+ @config = new_package_config(name, version)
35
+ @configs[name] = @config
36
+ end
37
+ else
38
+ @config = nil
39
+ end
40
+ yield
41
+ end
42
+
43
+ def retrieve(source, relpath)
44
+ copy(source, relpath)
45
+ end
46
+
47
+ def save
48
+ FileUtils.mkdir_p(@fig_dir)
49
+ File.open(File.join(@fig_dir, 'retrieve'), 'w') do |f|
50
+ @configs.each do |name,config|
51
+ config.files.each do |target|
52
+ f << target << '=' << config.name << '/' << config.version << "\n"
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def load(file)
61
+ File.open(file).each_line do |line|
62
+ line = line.strip()
63
+ if line =~ /^(.+)=(.+)\/(.+)$/
64
+ target = $1
65
+ config_name = $2
66
+ config_version = $3
67
+ config = @configs[config_name]
68
+ if config
69
+ if config.version != config_version
70
+ raise 'version mismatch in .figretrieve'
71
+ end
72
+ else
73
+ config = new_package_config(config_name, config_version)
74
+ @configs[config_name] = config
75
+ end
76
+ config.files << target
77
+ else
78
+ raise "parse error in #{file}: #{line}"
79
+ end
80
+ end
81
+ end
82
+
83
+ def new_package_config(name, version)
84
+ config = OpenStruct.new
85
+ config.name = name
86
+ config.version = version
87
+ config.files = Set.new()
88
+ return config
89
+ end
90
+
91
+ def copy(source, relpath)
92
+ target = File.join(@base_dir, relpath)
93
+ if File.directory?(source)
94
+ FileUtils.mkdir_p(target)
95
+ Dir.foreach(source) do |child|
96
+ if child != '.' and child != '..'
97
+ source_file = File.join(source, child)
98
+ target_file = File.join(relpath, child)
99
+ Fig::Logging.debug "Copying #{source_file} to #{target_file}."
100
+ copy(source_file, target_file)
101
+ end
102
+ end
103
+ else
104
+ if !File.exist?(target) || File.mtime(source) > File.mtime(target)
105
+ if Fig::Logging.debug?
106
+ Fig::Logging.debug "Copying package [#{@config.name}/#{@config.version}] from #{source} to #{target}."
107
+ else
108
+ Fig::Logging.info "+ [#{@config.name}/#{@config.version}] #{relpath}"
109
+ end
110
+ FileUtils.mkdir_p(File.dirname(target))
111
+ FileUtils.cp(source, target, :preserve => true)
112
+ end
113
+ @config.files << relpath if @config
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,13 @@
1
+ require 'fig/userinputerror'
2
+
3
+ module Fig
4
+ class URLAccessError < UserInputError
5
+ attr_reader :urls, :package, :version
6
+
7
+ def initialize(urls, package, version)
8
+ @urls = urls
9
+ @package = package
10
+ @version = version
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,4 @@
1
+ module Fig
2
+ class UserInputError < StandardError
3
+ end
4
+ end
@@ -0,0 +1,46 @@
1
+ # Keeping Windows-specific implementation details here.
2
+
3
+ require 'erb'
4
+ require 'fileutils'
5
+
6
+ # I don't know how to set environment variables so that a sub-shell will
7
+ # be able to use them. Therefore, I'm punting, and creating a batch script
8
+ # on the fly to run a user supplied command.
9
+
10
+ module Fig
11
+ class Windows
12
+
13
+ BATCH_SCRIPT_TEMPLATE = <<EOF
14
+ @echo off
15
+ % ENV.each do |k,v|
16
+ set <%= k %>=<%= v %>
17
+ % end
18
+
19
+ cmd /C <%= command %>
20
+ EOF
21
+
22
+
23
+ def self.with_generated_batch_script(cmd)
24
+ command = cmd.join(' ')
25
+ template = ERB.new(BATCH_SCRIPT_TEMPLATE, 0, '%')
26
+ output = template.result(binding)
27
+ begin
28
+ tf = File.new('C:/tmp/fig_command.bat', 'w')
29
+ FileUtils.chmod(0755, tf.path)
30
+ File.open(tf.path, 'w') do |fh|
31
+ fh.puts output
32
+ end
33
+ tf.close
34
+ yield tf.path
35
+ ensure
36
+ # tf.delete
37
+ end
38
+ end
39
+
40
+ def self.shell_exec_windows(cmd)
41
+ with_generated_batch_script(cmd) do |f|
42
+ Kernel.exec(f)
43
+ end
44
+ end
45
+ end
46
+ end
data/lib/fig.rb ADDED
@@ -0,0 +1,230 @@
1
+ require 'rubygems'
2
+ require 'net/ftp'
3
+ require 'log4r'
4
+
5
+ require 'fig/environment'
6
+ require 'fig/figrc'
7
+ require 'fig/logging'
8
+ require 'fig/options'
9
+ require 'fig/os'
10
+ require 'fig/package'
11
+ require 'fig/package/configuration'
12
+ require 'fig/package/publish'
13
+ require 'fig/parser'
14
+ require 'fig/repository'
15
+ require 'fig/retriever'
16
+ require 'fig/userinputerror'
17
+ require 'fig/windows'
18
+
19
+ module Fig
20
+ DEFAULT_FIG_FILE = 'package.fig'
21
+
22
+ def parse_descriptor(descriptor)
23
+ # todo should use treetop for these:
24
+ package_name = descriptor =~ %r< ^ ( [^:/]+ ) >x ? $1 : nil
25
+ config_name = descriptor =~ %r< : ( [^:/]+ ) >x ? $1 : nil
26
+ version_name = descriptor =~ %r< / ( [^:/]+ ) >x ? $1 : nil
27
+ return package_name, config_name, version_name
28
+ end
29
+
30
+ def run_fig(argv)
31
+ shell_command = nil
32
+ argv.each_with_index do |arg, i|
33
+ if arg == '--'
34
+ shell_command = argv[(i+1)..-1]
35
+ argv.slice!(i..-1)
36
+ break
37
+ end
38
+ end
39
+
40
+ options, argv, exit_value = parse_options(argv)
41
+ if not exit_value.nil?
42
+ return exit_value
43
+ end
44
+
45
+ Logging.initialize_pre_configuration(options[:log_level])
46
+
47
+ vars = {}
48
+ ENV.each {|key,value| vars[key]=value }
49
+
50
+ remote_url = nil
51
+ if options[:update] || options[:publish] || options[:update_if_missing] || options[:list_remote]
52
+ remote_url = ENV['FIG_REMOTE_URL']
53
+ if remote_url.nil?
54
+ $stderr.puts 'Please define the FIG_REMOTE_URL environment variable.'
55
+ return 1
56
+ end
57
+ end
58
+
59
+ configuration = FigRC.find(
60
+ options[:figrc],
61
+ remote_url,
62
+ options[:login],
63
+ options[:home],
64
+ options[:no_figrc]
65
+ )
66
+
67
+ Logging.initialize_post_configuration(options[:log_config] || configuration['log configuration'], options[:log_level])
68
+
69
+ remote_user = nil
70
+
71
+ os = OS.new(options[:login])
72
+ repos = Repository.new(
73
+ os,
74
+ File.expand_path(File.join(options[:home], 'repos')),
75
+ remote_url,
76
+ configuration,
77
+ remote_user,
78
+ options[:update],
79
+ options[:update_if_missing]
80
+ )
81
+ retriever = Retriever.new('.')
82
+ # Check to see if this is still happening with the new layers of abstraction.
83
+ at_exit { retriever.save }
84
+ env = Environment.new(os, repos, vars, retriever)
85
+
86
+ options[:modifiers].each do |modifier|
87
+ env.apply_config_statement(nil, modifier, nil)
88
+ end
89
+
90
+ input = nil
91
+ if options[:input] == :none
92
+ # ignore
93
+ elsif options[:input] == '-'
94
+ input = $stdin.read
95
+ elsif options[:input].nil?
96
+ input = os.read(DEFAULT_FIG_FILE) if os.exist?(DEFAULT_FIG_FILE)
97
+ else
98
+ if os.exist?(options[:input])
99
+ input = os.read(options[:input])
100
+ else
101
+ $stderr.puts %Q<File not found: "#{options[:input]}".>
102
+ return 1
103
+ end
104
+ end
105
+
106
+ options[:cleans].each do |descriptor|
107
+ package_name, version_name = descriptor.split('/')
108
+ repos.clean(package_name, version_name)
109
+ end
110
+ if options[:list]
111
+ repos.list_packages.sort.each do |item|
112
+ puts item
113
+ end
114
+ return 0
115
+ end
116
+
117
+ if options[:list_remote]
118
+ repos.list_remote_packages.sort.each do |item|
119
+ puts item
120
+ end
121
+ return 0
122
+ end
123
+
124
+ if not options[:list_configs].empty?
125
+ options[:list_configs].each do |descriptor|
126
+ package_name, version_name = descriptor.split('/')
127
+ repos.read_local_package(package_name, version_name).configs.each do |config|
128
+ puts config.name
129
+ end
130
+ end
131
+ return 0
132
+ end
133
+
134
+ if input
135
+ package = Parser.new(configuration).parse_package(nil, nil, '.', input)
136
+ direct_retrieves=[]
137
+ if options[:retrieve]
138
+ package.retrieves.each do |var, path|
139
+ if var =~ /^@([^\/]+)(.*)/
140
+ direct_retrieves << [$1, $2, path]
141
+ else
142
+ env.add_retrieve(var, path)
143
+ end
144
+ end
145
+ end
146
+ unless options[:publish] || options[:list] || options[:publish_local]
147
+ env.register_package(package)
148
+ env.apply_config(package, options[:config], nil)
149
+ direct_retrieves.each do |info|
150
+ env.direct_retrieve(info[0], info[1], info[2])
151
+ end
152
+ end
153
+ else
154
+ package = Package.new(nil, nil, '.', [])
155
+ end
156
+
157
+ if options[:publish] || options[:publish_local]
158
+ if !argv.empty?
159
+ $stderr.puts %Q<Unexpected arguments: #{argv.join(' ')}>
160
+ return 10
161
+ end
162
+ package_name, config_name, version_name = parse_descriptor(options[:publish] || options[:publish_local])
163
+ if package_name.nil? || version_name.nil?
164
+ $stderr.puts 'Please specify a package name and a version name.'
165
+ return 10
166
+ end
167
+ if not options[:modifiers].empty?
168
+ publish_statements = options[:resources] + options[:archives] + [Package::Configuration.new('default', options[:modifiers])]
169
+ publish_statements << Package::Publish.new('default','default')
170
+ elsif not package.statements.empty?
171
+ publish_statements = package.statements
172
+ else
173
+ $stderr.puts 'Nothing to publish.'
174
+ return 1
175
+ end
176
+ if options[:publish]
177
+ Logging.info "Checking status of #{package_name}/#{version_name}..."
178
+ if repos.list_remote_packages.include?("#{package_name}/#{version_name}")
179
+ Logging.info "#{package_name}/#{version_name} has already been published."
180
+ if not options[:force]
181
+ Logging.fatal 'Use the --force option if you really want to overwrite, or use --publish-local for testing.'
182
+ return 1
183
+ else
184
+ Logging.info 'Overwriting...'
185
+ end
186
+ end
187
+ end
188
+ Logging.info "Publishing #{package_name}/#{version_name}."
189
+ repos.publish_package(publish_statements, package_name, version_name, options[:publish_local])
190
+ elsif options[:echo]
191
+ puts env[options[:echo]]
192
+ elsif shell_command
193
+ argv.shift
194
+ env.execute_shell(shell_command) { |cmd| os.shell_exec cmd }
195
+ elsif argv[0]
196
+ package_name, config_name, version_name = parse_descriptor(argv.shift)
197
+ env.include_config(package, package_name, config_name, version_name, {}, nil)
198
+ env.execute_config(package, package_name, config_name, nil, argv) { |cmd| os.shell_exec cmd }
199
+ elsif input
200
+ env.execute_config(package, nil, options[:config], nil, argv) { |cmd| os.shell_exec cmd }
201
+ elsif !repos.updating?
202
+ $stderr.puts USAGE
203
+ $stderr.puts %q<Run "fig --help" for a full list of commands.>
204
+ end
205
+
206
+ return 0
207
+ end
208
+
209
+ def run_with_exception_handling(argv)
210
+ begin
211
+ return_code = run_fig(argv)
212
+ return return_code
213
+ rescue URLAccessError => exception
214
+ urls = exception.urls.join(', ')
215
+ $stderr.puts "Access to #{urls} in #{exception.package}/#{exception.version} not allowed."
216
+ return 1
217
+ rescue UserInputError => exception
218
+ # If there's no message, we assume that the cause has already been logged.
219
+ if not exception.message.nil?
220
+ $stderr.puts exception.to_s
221
+ end
222
+
223
+ return 1
224
+ rescue OptionParser::InvalidOption => exception
225
+ $stderr.puts exception.to_s
226
+ $stderr.puts USAGE
227
+ return 1
228
+ end
229
+ end
230
+ end