224 lines
5.6 KiB
Plaintext
224 lines
5.6 KiB
Plaintext
// Module shop system for managing dependencies and mods
|
|
|
|
var io = use('io')
|
|
var toml = use('toml')
|
|
var json = use('json')
|
|
|
|
var Shop = {}
|
|
|
|
var shop_path = '.cell/cell.toml'
|
|
|
|
// Load cell.toml configuration
|
|
Shop.load_config = function() {
|
|
if (!io.exists(shop_path))
|
|
return null
|
|
|
|
var content = io.slurp(shop_path)
|
|
return toml.decode(content)
|
|
}
|
|
|
|
// Save cell.toml configuration
|
|
Shop.save_config = function(config) {
|
|
io.slurpwrite(shop_path, toml.encode(config))
|
|
}
|
|
|
|
// Initialize .cell directory structure
|
|
Shop.init = function() {
|
|
if (!io.exists('.cell')) {
|
|
io.mkdir('.cell')
|
|
}
|
|
|
|
if (!io.exists('.cell/modules')) {
|
|
io.mkdir('.cell/modules')
|
|
}
|
|
|
|
if (!io.exists('.cell/build')) {
|
|
io.mkdir('.cell/build')
|
|
}
|
|
|
|
if (!io.exists('.cell/patches')) {
|
|
io.mkdir('.cell/patches')
|
|
}
|
|
|
|
if (!io.exists('.cell/lock.toml')) {
|
|
io.slurpwrite('.cell/lock.toml', '# Lock file for module integrity\n')
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// Parse module locator (e.g., "git.world/jj/mod@v0.6.3")
|
|
Shop.parse_locator = function(locator) {
|
|
var parts = locator.split('@')
|
|
if (parts.length !== 2) {
|
|
return null
|
|
}
|
|
|
|
return {
|
|
path: parts[0],
|
|
version: parts[1],
|
|
name: parts[0].split('/').pop()
|
|
}
|
|
}
|
|
|
|
// Convert module locator to download URL
|
|
Shop.get_download_url = function(locator) {
|
|
var parsed = Shop.parse_locator(locator)
|
|
if (!parsed) return null
|
|
|
|
// Handle different git hosting patterns
|
|
if (locator.startsWith('https://')) {
|
|
// Remove https:// prefix for parsing
|
|
var cleanLocator = locator.substring(8)
|
|
var hostAndPath = cleanLocator.split('@')[0]
|
|
|
|
// Gitea pattern: gitea.pockle.world/user/repo@branch
|
|
if (hostAndPath.includes('gitea.')) {
|
|
return 'https://' + hostAndPath + '/archive/' + parsed.version + '.zip'
|
|
}
|
|
|
|
// GitHub pattern: github.com/user/repo@tag
|
|
if (hostAndPath.includes('github.com')) {
|
|
return 'https://' + hostAndPath + '/archive/refs/tags/' + parsed.version + '.zip'
|
|
}
|
|
|
|
// GitLab pattern: gitlab.com/user/repo@tag
|
|
if (hostAndPath.includes('gitlab.')) {
|
|
return 'https://' + hostAndPath + '/-/archive/' + parsed.version + '/' + parsed.name + '-' + parsed.version + '.zip'
|
|
}
|
|
}
|
|
|
|
// Fallback to original locator if no pattern matches
|
|
return locator
|
|
}
|
|
|
|
// Add a dependency
|
|
Shop.add_dependency = function(alias, locator) {
|
|
var config = Shop.load_config()
|
|
if (!config) {
|
|
log.error("No cell.toml found")
|
|
return false
|
|
}
|
|
|
|
if (!config.dependencies) {
|
|
config.dependencies = {}
|
|
}
|
|
|
|
config.dependencies[alias] = locator
|
|
Shop.save_config(config)
|
|
return true
|
|
}
|
|
|
|
// Get the API URL for checking remote git commits
|
|
Shop.get_api_url = function(locator) {
|
|
var parsed = Shop.parse_locator(locator)
|
|
if (!parsed) return null
|
|
|
|
// Handle different git hosting patterns
|
|
if (locator.startsWith('https://')) {
|
|
// Remove https:// prefix for parsing
|
|
var cleanLocator = locator.substring(8)
|
|
var hostAndPath = cleanLocator.split('@')[0]
|
|
var parts = hostAndPath.split('/')
|
|
|
|
// Gitea pattern: gitea.pockle.world/user/repo@branch
|
|
if (hostAndPath.includes('gitea.')) {
|
|
var host = parts[0]
|
|
var user = parts[1]
|
|
var repo = parts[2]
|
|
return 'https://' + host + '/api/v1/repos/' + user + '/' + repo + '/branches/' + parsed.version
|
|
}
|
|
|
|
// GitHub pattern: github.com/user/repo@tag or @branch
|
|
if (hostAndPath.includes('github.com')) {
|
|
var user = parts[1]
|
|
var repo = parts[2]
|
|
// Try branch first, then tag
|
|
return 'https://api.github.com/repos/' + user + '/' + repo + '/branches/' + parsed.version
|
|
}
|
|
|
|
// GitLab pattern: gitlab.com/user/repo@tag
|
|
if (hostAndPath.includes('gitlab.')) {
|
|
var user = parts[1]
|
|
var repo = parts[2]
|
|
var projectId = encodeURIComponent(user + '/' + repo)
|
|
return 'https://' + parts[0] + '/api/v4/projects/' + projectId + '/repository/branches/' + parsed.version
|
|
}
|
|
}
|
|
|
|
// Fallback - return null if no API pattern matches
|
|
return null
|
|
}
|
|
|
|
// Extract commit hash from API response
|
|
Shop.extract_commit_hash = function(locator, response) {
|
|
if (!response) return null
|
|
|
|
var data
|
|
try {
|
|
data = json.decode(response)
|
|
} catch (e) {
|
|
log.console("Failed to parse API response: " + e)
|
|
return null
|
|
}
|
|
|
|
// Handle different git hosting response formats
|
|
if (locator.includes('gitea.')) {
|
|
// Gitea: response.commit.id
|
|
return data.commit && data.commit.id
|
|
} else if (locator.includes('github.com')) {
|
|
// GitHub: response.commit.sha
|
|
return data.commit && data.commit.sha
|
|
} else if (locator.includes('gitlab.')) {
|
|
// GitLab: response.commit.id
|
|
return data.commit && data.commit.id
|
|
}
|
|
|
|
return null
|
|
}
|
|
|
|
// Get the module directory for a given alias
|
|
Shop.get_module_dir = function(alias) {
|
|
var config = Shop.load_config()
|
|
if (!config || !config.dependencies || !config.dependencies[alias]) {
|
|
return null
|
|
}
|
|
|
|
var version = config.dependencies[alias]
|
|
var module_name = alias + '@' + version.split('@')[1]
|
|
|
|
// Check if replaced
|
|
if (config.replace && config.replace[version]) {
|
|
return config.replace[version]
|
|
}
|
|
|
|
return '.cell/modules/' + module_name
|
|
}
|
|
|
|
// Compile a module
|
|
Shop.compile_module = function(alias) {
|
|
var module_dir = Shop.get_module_dir(alias)
|
|
if (!module_dir) {
|
|
log.error("Module not found: " + alias)
|
|
return false
|
|
}
|
|
|
|
log.console("Would compile module: " + alias + " from " + module_dir)
|
|
return true
|
|
}
|
|
|
|
// Build all modules
|
|
Shop.build = function() {
|
|
var config = Shop.load_config()
|
|
if (!config || !config.dependencies) {
|
|
return true
|
|
}
|
|
|
|
for (var alias in config.dependencies) {
|
|
Shop.compile_module(alias)
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
return Shop |