Initial commit
This commit is contained in:
commit
6eec995d98
15 changed files with 212 additions and 0 deletions
1
.mol/repo
Normal file
1
.mol/repo
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
yawdl https://codeberg.org/chersbobers/yawdl.git
|
||||||
15
README.md
Normal file
15
README.md
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
# mol
|
||||||
|
a simple [maybe suckless] package manager uses hg/git repos to build.
|
||||||
|
|
||||||
|
install all you need is crystal
|
||||||
|
## linux/bsd/mac
|
||||||
|
chmod +x build.sh
|
||||||
|
./build.sh
|
||||||
|
|
||||||
|
## windows
|
||||||
|
./build.ps1
|
||||||
|
|
||||||
|
## usage
|
||||||
|
mol grab <repo_url/name(if in repo)> [needs a molfile]
|
||||||
|
mol remove <name>
|
||||||
|
mol update <name> (updates package)`
|
||||||
1
build.ps1
Normal file
1
build.ps1
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
crystal build src/mol.cr -o mol.exe --release
|
||||||
2
build.sh
Normal file
2
build.sh
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/sh
|
||||||
|
crystal build src/mol.cr -o mol --release
|
||||||
BIN
gc.dll
Normal file
BIN
gc.dll
Normal file
Binary file not shown.
BIN
iconv-2.dll
Normal file
BIN
iconv-2.dll
Normal file
Binary file not shown.
BIN
libcrypto-3-x64.dll
Normal file
BIN
libcrypto-3-x64.dll
Normal file
Binary file not shown.
BIN
libssl-3-x64.dll
Normal file
BIN
libssl-3-x64.dll
Normal file
Binary file not shown.
BIN
mol.exe
Normal file
BIN
mol.exe
Normal file
Binary file not shown.
BIN
mol.pdb
Normal file
BIN
mol.pdb
Normal file
Binary file not shown.
BIN
pcre2-8.dll
Normal file
BIN
pcre2-8.dll
Normal file
Binary file not shown.
2
shard.lock
Normal file
2
shard.lock
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
version: 2.0
|
||||||
|
shards: {}
|
||||||
19
shard.yml
Normal file
19
shard.yml
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
name: mol
|
||||||
|
version: 0.1.0
|
||||||
|
|
||||||
|
# authors:
|
||||||
|
# - name <email@example.com>
|
||||||
|
|
||||||
|
# description: |
|
||||||
|
# Short description of mol
|
||||||
|
|
||||||
|
# dependencies:
|
||||||
|
# pg:
|
||||||
|
# github: will/crystal-pg
|
||||||
|
# version: "~> 0.5"
|
||||||
|
|
||||||
|
# development_dependencies:
|
||||||
|
# webmock:
|
||||||
|
# github: manastech/webmock.cr
|
||||||
|
|
||||||
|
# license: MIT
|
||||||
172
src/mol.cr
Normal file
172
src/mol.cr
Normal file
|
|
@ -0,0 +1,172 @@
|
||||||
|
require "file_utils"
|
||||||
|
require "http/client"
|
||||||
|
|
||||||
|
BIN = Path.home / ".local" / "bin"
|
||||||
|
SRC = ".mol/src"
|
||||||
|
DB = ".mol/repo"
|
||||||
|
REPO = ENV.fetch("MOL_REPO", "https://git.sr.ht/~chersbobers/mol-pkgrepo/blob/master/PACKAGES?raw=true")
|
||||||
|
OS = {% if flag?(:win32) %}"windows"{% elsif flag?(:linux) %}"linux"{% else %}"macos"{% end %}
|
||||||
|
|
||||||
|
def run(cmd, args, dir = nil)
|
||||||
|
Process.run(cmd, args, chdir: dir,
|
||||||
|
output: Process::Redirect::Inherit,
|
||||||
|
error: Process::Redirect::Inherit).success?
|
||||||
|
end
|
||||||
|
|
||||||
|
def lookup(t) : {String, String?}
|
||||||
|
return {t, nil} if t.includes?("://")
|
||||||
|
if File.exists?(DB)
|
||||||
|
File.each_line(DB) do |l|
|
||||||
|
l = l.strip; next if l.empty? || l.starts_with?('#')
|
||||||
|
p = l.split; next unless p[0] == t
|
||||||
|
return {p[1], p.find(&.starts_with?("B=")).try(&.[2..])}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
abort "#{t} not found, run: mol sync"
|
||||||
|
end
|
||||||
|
|
||||||
|
def installed?(name)
|
||||||
|
Dir.exists?(File.join(SRC, name)) || File.exists?((BIN / name).to_s)
|
||||||
|
end
|
||||||
|
|
||||||
|
def link_bins(path)
|
||||||
|
Dir.mkdir_p(BIN)
|
||||||
|
[File.join(path,"bin"), File.join(path,"target","release"), path].each do |d|
|
||||||
|
next unless Dir.exists?(d)
|
||||||
|
Dir.each_child(d) do |f|
|
||||||
|
full = File.join(d, f)
|
||||||
|
next unless File.executable?(full) && !File.directory?(full) && !f.includes?('.')
|
||||||
|
dest = (BIN / f).to_s
|
||||||
|
FileUtils.cp(full, dest); File.chmod(dest, 0o755)
|
||||||
|
puts "-> #{dest}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_molpkg(path) : {Array(String), Array(String)}
|
||||||
|
file = File.join(path, "mol.pkg")
|
||||||
|
deps = [] of String
|
||||||
|
build = [] of String
|
||||||
|
return deps, build unless File.exists?(file)
|
||||||
|
|
||||||
|
in_build = false
|
||||||
|
in_os = false
|
||||||
|
in_install = false
|
||||||
|
|
||||||
|
File.each_line(file) do |l|
|
||||||
|
l = l.strip
|
||||||
|
if l.includes?("(deps")
|
||||||
|
l.scan(/"([^"]+)"/).each { |m| deps << m[1] }
|
||||||
|
elsif l.includes?("(build")
|
||||||
|
in_build = true
|
||||||
|
elsif l.includes?("(install")
|
||||||
|
in_build = false; in_install = true
|
||||||
|
elsif in_build && l.includes?("(#{OS}")
|
||||||
|
in_os = true
|
||||||
|
elsif in_build && in_os && l.starts_with?("(run")
|
||||||
|
parts = l.scan(/"([^"]+)"/).map(&.[1])
|
||||||
|
build << parts.join(" ") if parts.any?
|
||||||
|
elsif l == ")" && in_os
|
||||||
|
in_os = false
|
||||||
|
elsif l == ")" && in_build
|
||||||
|
in_build = false
|
||||||
|
elsif in_install && l.includes?("(bin")
|
||||||
|
name = l.scan(/"([^"]+)"/).first?.try(&.[1])
|
||||||
|
if name
|
||||||
|
src = File.join(path, name)
|
||||||
|
src = File.join(path, "#{name}.exe") if OS == "windows" && !File.exists?(src)
|
||||||
|
if File.exists?(src)
|
||||||
|
dest = (BIN / File.basename(src)).to_s
|
||||||
|
FileUtils.cp(src, dest); File.chmod(dest, 0o755)
|
||||||
|
puts "-> #{dest}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
{deps, build}
|
||||||
|
end
|
||||||
|
|
||||||
|
def install(name, src = false)
|
||||||
|
return if installed?(name)
|
||||||
|
puts "installing #{name}"
|
||||||
|
url, bin = lookup(name)
|
||||||
|
|
||||||
|
if !src && bin
|
||||||
|
r = HTTP::Client.get(bin)
|
||||||
|
abort "download failed" unless r.success?
|
||||||
|
dest = (BIN / File.basename(bin)).to_s
|
||||||
|
File.write(dest, r.body); File.chmod(dest, 0o755)
|
||||||
|
puts "-> #{dest}"
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
n = url.split('/').last.gsub(/\.hg$|\.git$/, "")
|
||||||
|
path = File.join(SRC, n)
|
||||||
|
vcs = url.includes?("hg") ? "hg" : "git"
|
||||||
|
abort "clone failed" unless run(vcs, ["clone", url, path])
|
||||||
|
|
||||||
|
deps, build_cmds = parse_molpkg(path)
|
||||||
|
deps.each { |dep| install(dep) }
|
||||||
|
|
||||||
|
if build_cmds.any?
|
||||||
|
build_cmds.each do |cmd|
|
||||||
|
parts = cmd.split
|
||||||
|
abort "build failed: #{cmd}" unless run(parts[0], parts[1..], path)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
abort "no build steps for #{OS} in #{n}"
|
||||||
|
end
|
||||||
|
|
||||||
|
link_bins(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_pkg(name)
|
||||||
|
path = File.join(SRC, name)
|
||||||
|
FileUtils.rm_rf(path) if Dir.exists?(path)
|
||||||
|
["", ".exe"].each do |ext|
|
||||||
|
b = (BIN / "#{name}#{ext}").to_s
|
||||||
|
File.delete(b) if File.exists?(b)
|
||||||
|
end
|
||||||
|
puts "removed #{name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_pkg(name)
|
||||||
|
path = File.join(SRC, name)
|
||||||
|
abort "#{name} not found, install first" unless Dir.exists?(path)
|
||||||
|
vcs = Dir.exists?(File.join(path, ".hg")) ? "hg" : "git"
|
||||||
|
args = vcs == "hg" ? ["pull", "-u"] : ["pull"]
|
||||||
|
abort "pull failed" unless run(vcs, args, path)
|
||||||
|
_, build_cmds = parse_molpkg(path)
|
||||||
|
build_cmds.each do |cmd|
|
||||||
|
parts = cmd.split
|
||||||
|
abort "build failed: #{cmd}" unless run(parts[0], parts[1..], path)
|
||||||
|
end
|
||||||
|
link_bins(path)
|
||||||
|
puts "updated #{name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
Dir.mkdir_p(SRC)
|
||||||
|
Dir.mkdir_p(File.dirname(DB))
|
||||||
|
|
||||||
|
case ARGV[0]?
|
||||||
|
when "install"
|
||||||
|
name = ARGV[1]? || abort("usage: mol install <name> [--source]")
|
||||||
|
src = ARGV.includes?("--source")
|
||||||
|
install(name, src)
|
||||||
|
when "remove"
|
||||||
|
name = ARGV[1]? || abort("usage: mol remove <name>")
|
||||||
|
remove_pkg(name)
|
||||||
|
when "update"
|
||||||
|
name = ARGV[1]? || abort("usage: mol update <name>")
|
||||||
|
update_pkg(name)
|
||||||
|
when "sync"
|
||||||
|
r = HTTP::Client.get(REPO)
|
||||||
|
abort "sync failed" unless r.success?
|
||||||
|
File.write(DB, r.body); puts "synced"
|
||||||
|
when "-l"
|
||||||
|
abort "no repo, run: mol sync" unless File.exists?(DB)
|
||||||
|
File.each_line(DB) { |l| l=l.strip; puts l.split[0] unless l.empty? || l.starts_with?('#') }
|
||||||
|
else
|
||||||
|
puts "mol as in molecule\n install <name> [--source] install a package\n remove <name> remove a package\n update <name> pull and rebuild\n sync fetch package list\n -l list packages"
|
||||||
|
end
|
||||||
BIN
zlib1.dll
Normal file
BIN
zlib1.dll
Normal file
Binary file not shown.
Reference in a new issue