• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nightconcept / almandine / 14757041512

30 Apr 2025 02:28PM UTC coverage: 79.95% (-0.9%) from 80.835%
14757041512

push

github

nightconcept
fix: add and install installing wrong file

61 of 81 new or added lines in 4 files covered. (75.31%)

11 existing lines in 2 files now uncovered.

1615 of 2020 relevant lines covered (79.95%)

2.19 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.69
/src/modules/add.lua
1
--[[
2
  add
3
  @module add
4

5
  Provides functionality to add a dependency to the project manifest and download it to a designated directory.
6
]]
7

8
-- local filesystem_utils = require("utils.filesystem")
9
local url_utils = require("utils.url") -- Require the new utility
1✔
10

11
---@class AddDeps
12
---@field load_manifest fun(): table, string?
13
---@field save_manifest fun(manifest: table): boolean, string?
14
---@field ensure_lib_dir fun(): nil
15
---@field downloader table
16
---@field downloader.download fun(url: string, path: string): boolean, string?
17
---@field hash_utils table
18
---@field hash_utils.hash_dependency fun(dep: string|table): string, string?
19
---@field lockfile table
20
---@field lockfile.generate_lockfile_table fun(deps: table): table
21
---@field lockfile.write_lockfile fun(table): boolean, string?
22
---@field lockfile.load_lockfile fun(): table?, string?
23

24
---@param dep_name string|nil Dependency name to add. If nil, inferred from source URL.
25
---@param dep_source string|table Dependency source string (URL) or table with url/path.
26
---@param dest_dir string|nil Optional destination directory for the installed file.
27
---@param deps AddDeps Table containing dependency injected functions.
28
---@return boolean success True if operation completed successfully.
29
---@return string? error Error message if operation failed.
30
local function add_dependency(dep_name, dep_source, _dest_dir, deps)
31
  deps.ensure_lib_dir()
11✔
32
  local manifest, err = deps.load_manifest()
11✔
33
  if not manifest then
11✔
34
    print(err)
1✔
35
    return false, err
1✔
36
  end
37

38
  -- If no dep_name provided, try to infer from URL
39
  if not dep_name then
10✔
40
    if type(dep_source) == "string" then
3✔
41
      local url = dep_source
2✔
42
      -- Try to extract name from URL
43
      local name = url:match("/([^/]+)%.lua$")
2✔
44
      if name then
2✔
45
        dep_name = name
1✔
46
      else
47
        return false, "Could not infer dependency name from URL"
1✔
48
      end
49
    else
50
      return false, "Dependency name must be provided when source is a table"
1✔
51
    end
52
  end
53

54
  -- If dep_source is a table, extract URL and path
55
  local url, out_path
56
  if type(dep_source) == "table" then
8✔
57
    url = dep_source.url
1✔
58
    out_path = dep_source.path or dep_name .. ".lua"
1✔
59
  else
60
    url = dep_source
7✔
61
    out_path = dep_name .. ".lua"
7✔
62
  end
63

64
  -- Normalize GitHub URLs using the utility function
65
  local source_url, download_url, norm_err = url_utils.normalize_github_url(url)
8✔
66
  if norm_err then
8✔
NEW
67
    return false, "Failed to normalize URL: " .. norm_err
×
68
  end
69
  -- Store the original (or potentially normalized source) URL in the manifest
70
  if type(dep_source) == "table" then
8✔
71
    manifest.dependencies[dep_name] = { url = source_url, path = dep_source.path }
1✔
72
  else
73
    manifest.dependencies[dep_name] = source_url
7✔
74
  end
75

76
  local ok, err2 = deps.save_manifest(manifest)
8✔
77
  if not ok then
8✔
78
    print(err2)
1✔
79
    return false, err2
1✔
80
  end
81
  print(string.format("Added dependency '%s' to project.lua.", dep_name))
7✔
82

83
  -- Download using the potentially raw URL
84
  local ok3, err3 = deps.downloader.download(download_url, out_path)
7✔
85
  if ok3 then
7✔
86
    print(string.format("Downloaded %s to %s", dep_name, out_path))
6✔
87
  else
88
    print(string.format("Failed to download %s: %s", dep_name, err3))
1✔
89
    return false, err3
1✔
90
  end
91

92
  -- Load existing lockfile to check before updating
93
  local existing_lockfile_data, load_err = deps.lockfile.load_lockfile()
6✔
94
  if load_err and not load_err:match("Could not read lockfile") then -- Ignore "not found" error, treat as empty
6✔
NEW
95
    print("Warning: Could not load existing lockfile to check for update: " .. tostring(load_err))
×
96
    -- Proceed to update even if loading failed (except for 'not found')
NEW
97
    existing_lockfile_data = nil -- Treat error as needing update check
×
98
  end
99

100
  -- Update lockfile only if it doesn't exist or the dependency isn't already in it
101
  if not existing_lockfile_data or not existing_lockfile_data[dep_name] then
6✔
102
    print("Updating lockfile...") -- Indicate action
6✔
103
    -- Build resolved_deps table for lockfile with proper hashes
104
    local resolved_deps = {}
6✔
105
    for name, dep in pairs(manifest.dependencies or {}) do
12✔
106
      local lock_dep_entry = type(dep) == "table" and dep or { url = dep }
6✔
107
      local hash, hash_err = deps.hash_utils.hash_dependency(dep)
6✔
108
      if not hash then
6✔
NEW
109
        print("Warning: Could not generate hash for " .. name .. ": " .. tostring(hash_err))
×
NEW
110
        hash = "unknown" -- Don't use URL as fallback anymore
×
111
      end
112
      resolved_deps[name] = {
6✔
113
        hash = hash,
6✔
114
        source = lock_dep_entry.url or tostring(dep),
6✔
115
      }
6✔
116
    end
117
    local lockfile_table = deps.lockfile.generate_lockfile_table(resolved_deps)
6✔
118
    local ok_lock, err_lock = deps.lockfile.write_lockfile(lockfile_table)
6✔
119
    if ok_lock then
6✔
120
      print("Updated lockfile: almd-lock.lua")
6✔
121
    else
NEW
122
      print("Failed to update lockfile: " .. tostring(err_lock))
×
123
      -- Note: The add operation succeeded overall, but lockfile update failed.
124
    end
125
  else
NEW
126
    print(string.format("Lockfile already contains entry for '%s', skipping update.", dep_name))
×
127
  end
128

129
  return true -- Return true because the dependency was added/downloaded successfully
6✔
130
end
131

132
---Prints usage/help information for the `add` command.
133
---Usage: almd add <source> [-d <dir>] [-n <dep_name>]
134
---@return string Usage string for the add command.
135
local function help_info()
UNCOV
136
  return [[
×
137
Usage: almd add <source> [-d <dir>] [-n <dep_name>]
138

139
Options:
140
  -d <dir>     Destination directory for the installed file
141
  -n <name>    Name of the dependency (optional, inferred from URL if not provided)
142

143
Example:
144
  almd add https://example.com/lib.lua
145
  almd add https://example.com/lib.lua -d src/lib/custom
146
  almd add https://example.com/lib.lua -n mylib
147
]]
1✔
148
end
149

150
return {
1✔
151
  add_dependency = add_dependency,
1✔
152
  help_info = help_info,
1✔
153
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc