mirror of
https://github.com/imjasonh/terraform-playground
synced 2026-07-07 23:35:16 +00:00
wheel: strip extras from console-script entry points; lock: strip inline comments from first '#'
- console-script targets like 'pkg.mod:main [extra]' no longer leak the '[extra]' suffix into the generated launcher; module-less entry points are skipped instead of producing invalid Python - stripComment now strips from the first '#' (not only ' #') and trims trailing whitespace, matching its docstring - adds tests demonstrating both behaviors Co-authored-by: Jason Hall <imjasonh@users.noreply.github.com>
This commit is contained in:
parent
f83222fbd9
commit
7290806232
4 changed files with 84 additions and 9 deletions
|
|
@ -119,15 +119,13 @@ func Parse(r io.Reader) ([]Requirement, error) {
|
|||
}
|
||||
|
||||
func stripComment(s string) string {
|
||||
// A '#' starts a comment unless escaped; requirements files don't escape so
|
||||
// we treat the first unquoted '#' as a comment start.
|
||||
if i := strings.Index(s, " #"); i >= 0 {
|
||||
return s[:i]
|
||||
// A '#' starts a comment. Requirements files don't support escaping '#',
|
||||
// and no valid pinned/hashed line contains one, so we strip from the first
|
||||
// '#' and drop any trailing whitespace it leaves behind.
|
||||
if i := strings.IndexByte(s, '#'); i >= 0 {
|
||||
s = s[:i]
|
||||
}
|
||||
if strings.HasPrefix(strings.TrimSpace(s), "#") {
|
||||
return ""
|
||||
}
|
||||
return s
|
||||
return strings.TrimRight(s, " \t")
|
||||
}
|
||||
|
||||
func isOption(s string) bool {
|
||||
|
|
|
|||
|
|
@ -92,6 +92,26 @@ requests[socks,security]==2.31.0 --hash=sha256:` + strings.Repeat("a", 64) + `
|
|||
}
|
||||
}
|
||||
|
||||
func TestStripsInlineComments(t *testing.T) {
|
||||
h := strings.Repeat("a", 64)
|
||||
for _, in := range []string{
|
||||
"flask==2.3.3 --hash=sha256:" + h + " # via app", // space before #
|
||||
"flask==2.3.3 --hash=sha256:" + h + "#no-space", // no space before #
|
||||
"flask==2.3.3 --hash=sha256:" + h + "\t# tabbed", // tab before #
|
||||
} {
|
||||
reqs, err := Parse(strings.NewReader(in))
|
||||
if err != nil {
|
||||
t.Fatalf("Parse(%q): %v", in, err)
|
||||
}
|
||||
if len(reqs) != 1 || reqs[0].Name != "flask" || reqs[0].Version != "2.3.3" {
|
||||
t.Fatalf("Parse(%q) = %+v", in, reqs)
|
||||
}
|
||||
if len(reqs[0].Hashes) != 1 {
|
||||
t.Errorf("Parse(%q): expected hash to survive comment stripping, got %v", in, reqs[0].Hashes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizeName(t *testing.T) {
|
||||
for _, tc := range []struct{ in, want string }{
|
||||
{"Flask", "flask"},
|
||||
|
|
|
|||
|
|
@ -379,11 +379,23 @@ func parseConsoleScripts(s string) map[string]entryPoint {
|
|||
}
|
||||
name = strings.TrimSpace(name)
|
||||
target = strings.TrimSpace(target)
|
||||
// Entry-point targets may carry an optional "[extras]" suffix
|
||||
// (e.g. "pkg.mod:main [cli]"); it is not part of the import path and
|
||||
// must be stripped or the generated launcher is invalid Python.
|
||||
if i := strings.IndexByte(target, '['); i >= 0 {
|
||||
target = strings.TrimSpace(target[:i])
|
||||
}
|
||||
module, attr, _ := strings.Cut(target, ":")
|
||||
module = strings.TrimSpace(module)
|
||||
attr = strings.TrimSpace(attr)
|
||||
if module == "" {
|
||||
// Without a module we cannot generate a valid launcher.
|
||||
continue
|
||||
}
|
||||
if attr == "" {
|
||||
attr = "main"
|
||||
}
|
||||
out[name] = entryPoint{module: strings.TrimSpace(module), attr: strings.TrimSpace(attr)}
|
||||
out[name] = entryPoint{module: module, attr: attr}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
|
|
|||
|
|
@ -151,6 +151,51 @@ func TestFilesLayout(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestConsoleScriptExtrasStripped(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
path, _ := testwheel.Write(t, dir, testwheel.Spec{
|
||||
Name: "tool",
|
||||
Version: "1.0",
|
||||
Modules: map[string]string{"tool/cli.py": "def main():\n pass\n"},
|
||||
ConsoleScripts: map[string]string{
|
||||
"tool": "tool.cli:main [fast]", // extras must be stripped
|
||||
"broken": ":main", // no module: must be skipped
|
||||
"colored": "tool.cli:main[color]", // extras with no space
|
||||
},
|
||||
})
|
||||
w, err := Open(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() { _ = w.Close() }()
|
||||
|
||||
files, err := w.Files(layout)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
byPath := map[string]string{}
|
||||
for _, f := range files {
|
||||
byPath[f.Path] = string(f.Data)
|
||||
}
|
||||
|
||||
bin := "app/.venv/bin/"
|
||||
for _, name := range []string{"tool", "colored"} {
|
||||
body, ok := byPath[bin+name]
|
||||
if !ok {
|
||||
t.Fatalf("missing console script %q", name)
|
||||
}
|
||||
if strings.Contains(body, "[") {
|
||||
t.Errorf("script %q still contains extras:\n%s", name, body)
|
||||
}
|
||||
if !strings.Contains(body, "from tool.cli import main") || !strings.Contains(body, "sys.exit(main())") {
|
||||
t.Errorf("script %q has unexpected body:\n%s", name, body)
|
||||
}
|
||||
}
|
||||
if _, ok := byPath[bin+"broken"]; ok {
|
||||
t.Error("module-less entry point should not produce a launcher")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilesDeterministic(t *testing.T) {
|
||||
path := writeFixture(t)
|
||||
digest := func() string {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue