mirror of
https://github.com/chromebrew/chromebrew.git
synced 2026-01-09 23:48:01 -05:00
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
363 lines
9.6 KiB
Ruby
Executable File
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
|