Initial commit

This commit is contained in:
chersbobers 2026-05-11 17:00:07 +12:00
commit 6eec995d98
15 changed files with 212 additions and 0 deletions

1
.mol/repo Normal file
View file

@ -0,0 +1 @@
yawdl https://codeberg.org/chersbobers/yawdl.git

15
README.md Normal file
View 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
View file

@ -0,0 +1 @@
crystal build src/mol.cr -o mol.exe --release

2
build.sh Normal file
View file

@ -0,0 +1,2 @@
#!/bin/sh
crystal build src/mol.cr -o mol --release

BIN
gc.dll Normal file

Binary file not shown.

BIN
iconv-2.dll Normal file

Binary file not shown.

BIN
libcrypto-3-x64.dll Normal file

Binary file not shown.

BIN
libssl-3-x64.dll Normal file

Binary file not shown.

BIN
mol.exe Normal file

Binary file not shown.

BIN
mol.pdb Normal file

Binary file not shown.

BIN
pcre2-8.dll Normal file

Binary file not shown.

2
shard.lock Normal file
View file

@ -0,0 +1,2 @@
version: 2.0
shards: {}

19
shard.yml Normal file
View 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
View 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

Binary file not shown.