Files
chromebrew/crew
Fred Clift 378a292faa update tmux, fix libevent build, fix crew wget
3 changes to get tmux to work:
update tmux to latest release

remove openssl dependency for libevent (partly because openssl forumla
on chromebrew is broken right now, partly because we dont need it.)

change command line options for wget in crew script:
man page says -N is incompatible with -O (and wget complains every run)
--content-disposition not needed since we specify -O and big files on
github (which are backed by aws) can not be retrieved with this flag,
probably because AWS doesn't support HEAD requests for those files
2016-06-01 12:20:41 -06:00

363 lines
9.6 KiB
Ruby
Executable File

#!/usr/bin/env ruby
require 'find'
require 'net/http'
require 'uri'
require 'digest/sha1'
require 'json'
require 'fileutils'
@command = ARGV[0]
@pkgName = ARGV[1]
CREW_PREFIX = '/usr/local'
CREW_LIB_PATH = CREW_PREFIX + '/lib/crew/'
CREW_CONFIG_PATH = CREW_PREFIX + '/etc/crew/'
CREW_BREW_DIR = CREW_PREFIX + '/tmp/crew/'
CREW_DEST_DIR = CREW_BREW_DIR + '/dest'
SHORTARCH = `getconf LONG_BIT | tr -d '\n\r'`
$LOAD_PATH.unshift "#{CREW_LIB_PATH}lib"
USER = `whoami`.chomp
@device = JSON.parse(File.read(CREW_CONFIG_PATH + 'device.json'), symbolize_names: true)
#symbolize also values
@device.each do |key, elem|
@device[key] = @device[key].to_sym rescue @device[key]
end
def setPkg (pkgName, silent = false)
require CREW_LIB_PATH + 'packages/' + pkgName
@pkg = Object.const_get(pkgName.capitalize)
@pkg.name = pkgName
puts "Found #{pkgName}, version #{@pkg.version}" unless silent
end
def list_packages
Find.find (CREW_LIB_PATH + 'packages') do |filename|
Find.find(CREW_CONFIG_PATH + 'meta/') do |packageList|
packageName = File.basename filename, '.rb'
print '(i) ' if packageList == CREW_CONFIG_PATH + 'meta/' + packageName + '.filelist'
end
puts File.basename filename, '.rb' if File.extname(filename) == '.rb'
end
end
def search (pkgName, silent = false)
Find.find (CREW_LIB_PATH + 'packages') do |filename|
return setPkg(pkgName, silent) if filename == CREW_LIB_PATH + 'packages/' + pkgName + '.rb'
end
abort "package #{pkgName} not found :("
end
def update
abort "'crew update' is used to update crew itself. Use 'crew upgrade <packageName> to upgrade a specific package." if @pkgName
#update package lists
Dir.chdir CREW_LIB_PATH do
system "git fetch origin master"
system "git reset --hard origin/master"
end
puts "Package lists, crew, and library updated."
#check for outdated installed packages
puts "Checking for package updates..."
puts ""
canBeUpdated = 0
@device[:installed_packages].each do |package|
search package[:name], true
if package[:version] != @pkg.version
canBeUpdated += 1
puts @pkg.name + " could be updated from " + package[:version] + " to " + @pkg.version
end
end
if canBeUpdated > 0
puts ""
puts "Run 'crew upgrade' to upgrade everything or 'crew upgrade <packageName>' to upgrade a specific package."
else
puts "Your software is up to date."
end
end
def upgrade
if @pkgName
search @pkgName
currentVersion = nil
@device[:installed_packages].each do |package|
if package[:name] == @pkg.name
currentVersion = package[:version]
end
end
if currentVersion != @pkg.version
search @pkg.name
puts "Updating #{@pkg.name}..."
remove
resolveDependenciesAndInstall
else
puts "#{@pkg.name} is already up to date."
end
else
toBeUpdated = []
@device[:installed_packages].each do |package|
search package[:name], true
if package[:version] != @pkg.version
toBeUpdated.push(package[:name])
end
end
if toBeUpdated.length > 0
puts "Updating packages..."
toBeUpdated.each do |package|
search package
remove
resolveDependenciesAndInstall
end
puts "Packages have been updated."
else
puts "Your software is already up to date."
end
end
end
def download
if @pkg.binary_url && @pkg.binary_url.has_key?(@device[:architecture])
url = @pkg.binary_url[@device[:architecture]]
source = false
puts "Precompiled binary available, downloading..."
else
url = @pkg.source_url
source = true
puts "No precompiled binary available for your platform, downloading source..."
end
uri = URI.parse url
filename = File.basename(uri.path)
if source
sha1sum = @pkg.source_sha1
else
sha1sum = @pkg.binary_sha1[@device[:architecture]]
end
Dir.chdir CREW_BREW_DIR do
system('wget', '--continue', '--no-check-certificate', url, '-O', filename)
abort 'Checksum mismatch :/ try again' unless Digest::SHA1.hexdigest( File.read("./#{filename}") ) == sha1sum
end
puts "Archive downloaded"
return {source: source, filename: filename}
end
def resolveDependenciesAndInstall
begin
origin = @pkg.name
resolveDependencies
search origin
install
rescue InstallError => e
puts "#{@pkg.name} failed to install: #{e.to_s}"
ensure
#cleanup
unless ARGV[2] == 'keep'
Dir.chdir CREW_BREW_DIR do
system "rm -rf *"
system "mkdir dest" #this is a little ugly, feel free to find a better way
end
end
end
end
def resolveDependencies
@dependencies = []
def pushDeps
if @pkg.dependencies
@dependencies.unshift @pkg.dependencies
@pkg.dependencies.each do |dep|
search dep, true
pushDeps
end
end
end
pushDeps
return if @dependencies.empty?
puts "Following packages also need to be installed: "
@dependencies.flatten!.uniq!
@dependencies.each do |dep|
print dep + " "
end
puts ""
puts "Do you agree? [Y/n]"
response = STDIN.getc
case response
when "n"
abort "No changes made."
when "\n", "y", "Y"
puts "Proceeding..."
proceed = true
else
puts "I don't understand '#{response}' :("
abort "No changes made."
end
if proceed
@dependencies.each do |dep|
search dep
install
end
end
end
def install
if @device[:installed_packages].any? { |pkg| pkg[:name] == @pkg.name }
puts "Package #{@pkg.name} already installed, skipping..."
return
end
unless @pkg.is_fake?
meta = download
Dir.chdir CREW_BREW_DIR do
puts "Unpacking archive, this may take a while..."
system "tar", "xf", meta[:filename]
if meta[:source] == true
abort "You don't have a working C compiler. Run 'crew install buildessential' to get one and try again." unless system("gcc", "--version")
topdir = `tar -tf #{meta[:filename]} | sed -e 's@/.*@@' | uniq`.chomp!
Dir.chdir CREW_BREW_DIR + topdir do
puts "Building from source, this may take a while..."
@pkg.build
system "rm -rf", CREW_DEST_DIR + "/*" #wipe crew destdir
puts "Preconfiguring package..."
@pkg.install
end
Dir.chdir CREW_DEST_DIR do
#create directory list
system "find . -type f > ../filelist"
system "find . -type l >> ../filelist"
system "cut -c2- ../filelist > filelist"
#create file list
system "find . -type d > ../dlist"
system "cut -c2- ../dlist > dlistcut"
system "tail -n +2 dlistcut > dlist"
#remove temporary files
system "rm dlistcut ../dlist ../filelist"
#create resulting folders list
directories = []
Dir.glob('*').select do |fn|
if File.directory?(fn)
directories.push(fn)
end
end
#wipe directories with the same name in brew dir to avoid conflicts
directories.each do |dir|
system "rm -rf ../" + dir.chomp
end
#move result files and directories to brew dir
system "mv * ../"
end
end
puts "Installing..."
FileUtils.mv 'dlist', CREW_CONFIG_PATH + "meta/#{@pkg.name}.directorylist"
FileUtils.mv 'filelist', CREW_CONFIG_PATH + "meta/#{@pkg.name}.filelist"
File.open(CREW_CONFIG_PATH + "meta/#{@pkg.name}.directorylist").each_line do |line|
system "sudo", "mkdir", "-p", line.chomp
end
File.open(CREW_CONFIG_PATH + "meta/#{@pkg.name}.filelist").each_line do |line|
system "sudo", "mv", CREW_BREW_DIR + line.chomp, line.chomp
end
end
end
#add to installed packages
@device[:installed_packages].push(name: @pkg.name, version: @pkg.version)
File.open(CREW_CONFIG_PATH + 'device.json', 'w') do |file|
output = JSON.parse @device.to_json
file.write JSON.pretty_generate(output)
end
puts "#{@pkg.name.capitalize} installed!"
end
def remove
unless @device[:installed_packages].any? { |pkg| pkg[:name] == @pkg.name }
puts "Package #{@pkg.name} isn't installed."
return
end
unless @pkg.is_fake?
Dir.chdir CREW_CONFIG_PATH do
File.open("meta/#{@pkg.name}.filelist").each_line do |line|
begin
File.unlink line.chomp
rescue => exception #swallow exception
end
end
File.readlines("meta/#{@pkg.name}.directorylist").reverse.each do |line|
begin
Dir.rmdir line.chomp
rescue => exception #swallow exception
end
end
File.unlink "meta/#{@pkg.name}.filelist"
File.unlink "meta/#{@pkg.name}.directorylist"
end
end
#remove from installed packages
@device[:installed_packages].each do |elem|
@device[:installed_packages].delete elem if elem[:name] == @pkg.name
end
File.open(CREW_CONFIG_PATH + 'device.json', 'w') do |file|
out = JSON.parse @device.to_json
file.write JSON.pretty_generate(out)
end
puts "#{@pkg.name.capitalize} removed!"
end
case @command
when "search"
if @pkgName
search @pkgName
else
list_packages
end
when "download"
search @pkgName
download
when "update"
update
when "upgrade"
upgrade
when "install"
search @pkgName
resolveDependenciesAndInstall
when "remove"
abort 'Removing actions must be ran with sudo.' unless USER == 'root'
search @pkgName
remove
when nil
puts "Chromebrew, version 0.2.1"
puts "Usage: crew [command] [package]"
puts "Available commands: search, download, install, remove"
else
puts "I have no idea how to do #{@command} :("
puts "Available commands: search, download, install, remove"
end