George S. Baugh doge

doge запушил(а) new-routing в Troglodyne/houstonpm

  • f28e2e9854 Update the routes and templates for the routing of tCMS by tPSGI Two routes called redirect_permanent from Trog::Routes::HTML, which no longer has it. It is now a method of the tPSGI object in $query->{tpsgi}, so the old about page and the old stylesheet URL would have died. The route for a talk was a regex with a capture, and tPSGI routes by OpenAPI path templates, so it is now /talks/{fragment+}, and it reads the fragment from $query->{input}. The regex also required a leading digit, so the route still answers 404 without one. An exact path, such as /talks/index.html, wins over the template. The fragment is percent-encoded before it goes in the Location header, so a request cannot add a header. routes.pm called Text::Xslate without loading it, so it now uses it. The sponsors and FAQ pages set their own title, rather than show the default title of the site. The title bar linked the Perl Mongers logo from pm.org, where it no longer exists, so every page had a broken image. The theme now has its own copy of the logo from its current place on that site. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • 62f97ceeee Merge pull request #5 from oodler577/main updating some info on the website
  • c5f9712b03 updating some info on the website
  • ea510743b8 Update mailing list loc
  • 1ec180894c fix pages

20 часов назад

doge создал новую ветку new-routing в Troglodyne/houstonpm

20 часов назад

doge запушил(а) posts-template в Troglodyne/tCMS

  • a88083467f Give a redirect exactly one leading slash, and not only at most one The dispatcher kept the path of a to and cut its leading slashes down to one. A to of https:$host has the path $host, with no slash at all, and the dispatcher kept it as it was. A browser reads that as a path relative to the page, but a client that parses it more loosely can read it as a host. Now the path gets one slash if it has none, as well as one slash if it has several. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

1 день назад

doge запушил(а) posts-template в Troglodyne/tCMS

  • 24a4eacf06 Route every post at its default href by one template Each post gave the routing table a route of its own, and _routes gave each of those a /secure copy. A site with tens of thousands of posts then gave tPSGI an OpenAPI document with tens of thousands of paths. tPSGI checks that document against the OpenAPI schema when a worker starts. The check costs about 6.6 ms and 36 KB for each path, so on such a site each worker spent minutes and gigabytes on it, and never answered its first request before the machine ran out of memory. Almost all of those routes are the same operation: a GET of /posts/<id> that Trog::Routes::HTML::posts answers, and posts() finds the post by the id in the path. So _routes now drops those routes and adds one template, /posts/{id}, and its /secure copy. On the site above the document has 81 paths, and the router builds in 0.3 s. A route under /posts that another callback answers, and a post at an href of its own, keep their routes. An alias under /posts still reaches its post, because tPSGI rewrites an alias before it routes. The template names its callback as a string, as the data routes do. The scripts and the inputs of a route are looked up by that name, and a reference names whatever sub is there when it is taken. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • e4370fe152 Let a theme name the scripts of every page A route names the scripts of its page, and a template may not write a <script src> of its own, since the scripts of a page are one bundle that only a route can declare. But a theme can name scripts only on the routes that it ships, and a script that a theme puts in a bar of the page, which every page has, belongs to every route. So such a theme had nowhere to put it but a <script src> in its template. A theme now names those scripts in @Theme::scripts. build_routes puts them before the scripts of every route, so they are in each bundle, and it declares those bundles at startup as it does the others. It does this after _routes, which keeps one table for the life of the process, so that each build sees the theme as it is. Each route is copied rather than changed, as a route and its /secure copy can share one hash, and a shared one would get the scripts twice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • 50f411ab5e Keep the files of a theme apart from their URLs Trog::Themes answered two kinds of path without saying which. td() said that it was a URL path, but it answered /www/themes/x, and the webserver serves no URL under /www. themed() and themed_script() answered the file of the theme's copy, www/themes/x/..., but the URL of the stock copy, /img/.... So each caller took the answer apart in its own way: three of them removed /www/ from theme_dir, Bundle turned a leading / back into www/, and themed_style removed www/. Four links of a themed site were broken by it: - header.tx linked each favicon at themes/x/img/icon/..., a relative path, so below the top level of the site every favicon was a 404. It also linked the theme's directory for each icon, whether the theme had that icon or not. - og:image and twitter:image pointed at /www/themes/x/..., a 404. - The icons of /api/webmanifest were www/themes/x/..., relative to /api/, so each one was a 404. - /favicon.ico handed tPSGI /img/icon//favicon.ico to open, a path from the root of the filesystem, so it served nothing. Now get_dir() and themed() answer files, td() answers a URL path, and url_path() turns a file under www/ into the URL that serves it. No caller rewrites a path any more. The header, the manifest and the social image resolve each icon through themed(), so a theme that has some of the icons gets its own and the stock ones for the rest. A theme whose templates wrote /<: $theme_dir :>/ to make up for the relative path must drop the leading slash. Such a theme needs that change in its own repository. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • 8d9d12dc5c Give every component template the directory of the theme A theme overrides a bar of the page, such as title.tx or leftbar.tx, to show its own images, and builds their links from theme_dir. index.tx calls those components with no arguments, so the template of the theme was passed nothing. Now that a template dies when it reads a variable that its caller did not pass, every page of a themed site died in title.tx with "Attempt to access disallowed key 'theme_dir' in a restricted hash". render_template gives each component template theme_dir, unless the caller gives it a value, as the Header component already did for itself. So the Header component no longer works it out, and its own copy is gone. Trog::Themes loads nothing that loads Trog::Renderer, so a use at the top does not close the load cycle that the POD warns about. Index and the code that serves a post still strip /www from theme_dir in the data of their routes. Those are page data rather than component data, and this change leaves them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • 338b322692 Send the search of a page that is not a page of posts to /search The search box is on every page, and it sent like to the page it was on. A page of posts searches itself, and a datasource answers the search of its own page, but every other page ignored it. Since a route takes only what it declares, every such page had to declare a like it did nothing with. Now /search is a page of posts, as series and users are: every post the reader can see that the search finds. index() points the search box at /search, unless posts() says the page searches itself. A search that finds nothing is a page that says so, where a page of posts with no posts is a 404 for a visitor. Only the pages of posts and /search take like. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

2 дней назад

doge создал новую ветку posts-template в Troglodyne/tCMS

2 дней назад

doge запушил(а) master в Troglodyne/tPSGI

  • 16f921ec94 Merge pull request #22 from Troglodyne-Internet-Widgets/openapi-routing Route by an OpenAPI 3 document, rather than a list of regexes
  • be155af285 Take perl's own booleans in a router's document A router had to write Mojo::JSON::true, by its full name, because the true that use 5.040 imports failed the check against the OpenAPI schema. JSON::Validator 5.19 compares enum values by a checksum, and a native true does not hash as the JSON true of required: true. The router now checks a copy of each document in which perl's booleans are Cpanel::JSON::XS booleans. The callbacks in the copy are the same subs, and the router's own document is left as it was. The documents in the POD and the tests say plain true. Without the copy, t/TPSGI-Router.t dies as it builds its router. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • 266eafe760 Route by an OpenAPI 3 document, rather than a list of regexes A router exported @routes: regex keys, tried with m/^$key$/ in array order after an exact pass. The one real router builds that array from a hash, so its regex routes were tried in an order that changed from process to process, and the "longest first" that respond() promised was never done. Every literal key was also tried as a regex, so the dot of /humans.txt matched any character. Each parameter was checked by a coderef of its own, and the catalog of routes could not be encoded, because of those coderefs. A router now exports %openapi, an OpenAPI 3 document as Perl data, and the new TPSGI::Router compiles it. The callback is the operation's x-tpsgi-callback, x-tpsgi-data and x-tpsgi-env replace data and env, and the callback finds the whole operation in $query->{dispatcher}. A template takes {name}, several to a segment, and a {name+} that takes the rest of the path. Its literal text is quotemeta'd, and no variable takes a newline, which keeps what the old test of extract_query asked of a dot. The most concrete template wins, by a total order of segment kind, then literal length, then the string. So the order never comes from a hash. JSON::Validator checks each request against the operation's parameters and requestBody, and coerces the values. validate_request() coerces its own copy of each value, so the router hands it getters and writes the coerced values back. The old strict rule stays: an operation that declares a query parameter or a body takes no undeclared query key. A body of a media type that the operation does not take is a 415, and a path with a method that it has no route for is a 405 with Allow, where it was a 400. A router that still has @routes dies as it loads, through cannot_start(), and says where to read. Compiling a document takes about 50 ms, against about 27 us to validate a request, and new() runs per request. So the router is built once per worker, for each list of router files. A request that failed validation got badrequest() with the query, which has no method and no path, so the log line warned and the warning was fatal. It now gets what respond() knows of the request. Each new rule was broken once on purpose, and the test of it failed: the exact pass, quotemeta, the newline rule, the segment rank, the literal length, the twin and duplicate templates, a {name+} that is not last, HEAD, 405 and Allow, 415, the undeclared key, the write-back of coerced values, a callback by name and a missing one, an invalid document, a stale router, the cache and x-tpsgi-data. Content type negotiation is JSON::Validator's own negotiate_content_type(), not a second copy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • a38be39bc5 Merge pull request #21 from Troglodyne-Internet-Widgets/dzil-5.040 Build with Dist::Zilla, and hold the code to the 5.040 profile
  • 8c23cfb45b Say that tarbaby restarts drop no request, and drop a stale XXX tarbaby's abstract and usage named only autoreload. The server it runs also lets a worker answer the connection it accepted before a HUP retires it, which is the other reason to start tPSGI through it. stream_raw_cgi() was documented as printing the HTTP status line for the CGI. It prints nothing of its own: it runs the file with the response handle selected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

2 дней назад

doge создал новую ветку master в Troglodyne/tPSGI

2 дней назад

doge запушил(а) master в Troglodyne/tCMS

  • 4b5f97c642 Merge pull request #379 from Troglodyne-Internet-Widgets/bundle-route-js Serve the scripts of a page as one versioned bundle
  • ad06d59b3c Say in the POD of the bundle route which lists it serves, and who declares them The route answers 404 for a list of real scripts that no route declared. Its POD did not say so, or say that the declarations come from TCMS::build_routes() at startup and from finish_render() when it links a bundle. A reader of the route could not tell why a hand-written bundle URL fails, or that this is what keeps a URL from making tCMS build a bundle. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • 656da54486 Name the scripts of a page in its route, and serve only the bundles that routes declare The bundle route built a bundle for any list of real scripts that its URL named. It kept none of them, but it still read, minified and hashed the scripts for each one, so a request could cost the server that work as often as somebody asked. A limit on the cache would have traded that for evicting the bundles that pages use. Now a route definition names the scripts of its page: scripts for every reader, and authenticated_scripts for a reader who is logged in as well. build_routes passes them on as x-tcms-scripts and x-tcms-authenticated_scripts, and finish_render reads them from the dispatcher, which tPSGI sets from the route table after it reads the request. So no list comes from the request. Before this, finish_render read $vars->{scripts}, which a route that spreads %$query last could take from a query parameter, and which would now be fatal. The routes of posts come from the datastore, so _routes gives each route whose callback is posts, series or users the scripts of a post page, unless the route names its own. /metrics and /admin/wyzzerdd name theirs. The fourth argument of index() is gone. build_routes declares the two lists of each route to Trog::Bundle at startup, so every worker knows them before it renders a page. scripts() declares the list that it is given, since only a route can have named it. served() returns undef for a list that nobody declared, and the route answers 404. So the cache holds only declared bundles. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • 8c75661894 Keep only the bundles that pages link, and die on a script that is not there The cache of bundles was emptied when it held 16, because the route built and kept any list that a URL named. The lists that pages link are a few per route, and they are the only ones worth keeping. So scripts(), which finish_render calls, now keeps its bundle, and the new served(), which the route calls, keeps nothing. served() returns the bundle that a page linked when that bundle is current, and otherwise it builds one for the request. The limit is gone. A page that named a missing script used to get a bundle without that script, and a warning. The page then failed in the browser, far from the cause. scripts() now dies and names the script. served() returns undef for such a name, so the route answers 404 to a URL. The editing scripts now load for any reader who is logged in, not only for an admin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • eb82d617e9 Save each bundle that a page links as a static, and drop it when a script changes In production the webserver serves www/static directly, so a bundle that is saved there never reaches perl. The first version of the bundle did not save it, because the route builds any list that a URL names, and saving each of those would let anyone fill the disk. finish_render now saves the bundle that it links, after the response, once per process. Only the lists that routes name reach finish_render, so the set of files is small and fixed. The route still saves nothing. The href of a bundle is a digest of its body, so a saved bundle is never wrong. When a script changes, the saved pages still link the old href, and the old bundles stay on disk. So the first save also has tPSGI watch www/scripts, and the scripts directory of the theme when there is one, in the way that DirIndex watches its directory. A change throws away the saved html and js renders. The pages are rendered again and link the new bundle. A page that still links an old href gets the route's redirect. %saved is a package variable, so that the test can start from a worker that has saved nothing. Two tests that make sure a page is never saved now leave the saved bundles out. Without that, they passed only because an earlier subtest had already saved the bundle in this process. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • Просмотр сравнение для этих 234 коммитов »

2 дней назад

doge запушил(а) strict-validation в Troglodyne/tPSGI

  • 5eb7d55926 Give a callback the input of a request apart from the rest of its query extract_query() merged the query string, the body, the path and x-tpsgi-data into the same hash as everything tPSGI knows of the request: the route, the method, the domain, the dispatcher. Validation now refuses an undeclared name, but a declared one could still stand in for a key that tPSGI or the application set, and an application that hands the query to a template hands the request every variable of the template. @reserved papered over part of it, by letting the query string carry the keys that route() then overwrote. Now extract_input() builds the input alone, and route() puts it in $query->{input}. The rest of the query is what tPSGI sets, and no request can reach it, so @reserved goes: a key such as route is a 400 like any other undeclared key. The input is flat, so a name can mean one thing only. new() dies on an operation that gives one name to two of the path, the query and the body, and on x-tpsgi-data that sets a name the request can give. A body schema that says additionalProperties can still take any name, so validate() refuses a field or file of such a body whose name is a path variable or a query parameter. In CGI mode the input is empty, as the query was. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • 9a36d98ac0 Refuse every name in a request that its operation does not declare The router refused an undeclared query key only for an operation that declared a query parameter or a request body. An operation that declared neither took any key, and a body sent to an operation with no requestBody was never checked at all. extract_query() merges the query, the fields of the body and its files into the one hash that the callback gets. So any name in a request could stand in for a key that the callback meant to set itself, and the callback cannot tell the two apart. Now each operation is strict. A query key must be a query parameter, or a key that tPSGI sets itself. A body to an operation with no requestBody is a 400. A field or a file must be a property of the schema of the media type that was sent, unless that schema says additionalProperties, in which case JSON::Validator decides as before. The files reach validate() by name, because extract_query() merged them into the query unchecked. CGI mode stays as it was. route() builds no query for an operation with x-tpsgi-env, so nothing is validated, and the CGI reads the request from %ENV. It is how a CGI that reads whatever it is sent can move to tPSGI one route at a time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • 16f921ec94 Merge pull request #22 from Troglodyne-Internet-Widgets/openapi-routing Route by an OpenAPI 3 document, rather than a list of regexes
  • be155af285 Take perl's own booleans in a router's document A router had to write Mojo::JSON::true, by its full name, because the true that use 5.040 imports failed the check against the OpenAPI schema. JSON::Validator 5.19 compares enum values by a checksum, and a native true does not hash as the JSON true of required: true. The router now checks a copy of each document in which perl's booleans are Cpanel::JSON::XS booleans. The callbacks in the copy are the same subs, and the router's own document is left as it was. The documents in the POD and the tests say plain true. Without the copy, t/TPSGI-Router.t dies as it builds its router. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • 266eafe760 Route by an OpenAPI 3 document, rather than a list of regexes A router exported @routes: regex keys, tried with m/^$key$/ in array order after an exact pass. The one real router builds that array from a hash, so its regex routes were tried in an order that changed from process to process, and the "longest first" that respond() promised was never done. Every literal key was also tried as a regex, so the dot of /humans.txt matched any character. Each parameter was checked by a coderef of its own, and the catalog of routes could not be encoded, because of those coderefs. A router now exports %openapi, an OpenAPI 3 document as Perl data, and the new TPSGI::Router compiles it. The callback is the operation's x-tpsgi-callback, x-tpsgi-data and x-tpsgi-env replace data and env, and the callback finds the whole operation in $query->{dispatcher}. A template takes {name}, several to a segment, and a {name+} that takes the rest of the path. Its literal text is quotemeta'd, and no variable takes a newline, which keeps what the old test of extract_query asked of a dot. The most concrete template wins, by a total order of segment kind, then literal length, then the string. So the order never comes from a hash. JSON::Validator checks each request against the operation's parameters and requestBody, and coerces the values. validate_request() coerces its own copy of each value, so the router hands it getters and writes the coerced values back. The old strict rule stays: an operation that declares a query parameter or a body takes no undeclared query key. A body of a media type that the operation does not take is a 415, and a path with a method that it has no route for is a 405 with Allow, where it was a 400. A router that still has @routes dies as it loads, through cannot_start(), and says where to read. Compiling a document takes about 50 ms, against about 27 us to validate a request, and new() runs per request. So the router is built once per worker, for each list of router files. A request that failed validation got badrequest() with the query, which has no method and no path, so the log line warned and the warning was fatal. It now gets what respond() knows of the request. Each new rule was broken once on purpose, and the test of it failed: the exact pass, quotemeta, the newline rule, the segment rank, the literal length, the twin and duplicate templates, a {name+} that is not last, HEAD, 405 and Allow, 415, the undeclared key, the write-back of coerced values, a callback by name and a missing one, an invalid document, a stale router, the cache and x-tpsgi-data. Content type negotiation is JSON::Validator's own negotiate_content_type(), not a second copy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

2 дней назад

doge создал новую ветку strict-validation в Troglodyne/tPSGI

2 дней назад

doge создал(а) репозиторий Troglodyne/tPSGI

2 дней назад

doge запушил(а) component-theme-dir в Troglodyne/tCMS

  • e4370fe152 Let a theme name the scripts of every page A route names the scripts of its page, and a template may not write a <script src> of its own, since the scripts of a page are one bundle that only a route can declare. But a theme can name scripts only on the routes that it ships, and a script that a theme puts in a bar of the page, which every page has, belongs to every route. So such a theme had nowhere to put it but a <script src> in its template. A theme now names those scripts in @Theme::scripts. build_routes puts them before the scripts of every route, so they are in each bundle, and it declares those bundles at startup as it does the others. It does this after _routes, which keeps one table for the life of the process, so that each build sees the theme as it is. Each route is copied rather than changed, as a route and its /secure copy can share one hash, and a shared one would get the scripts twice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • 50f411ab5e Keep the files of a theme apart from their URLs Trog::Themes answered two kinds of path without saying which. td() said that it was a URL path, but it answered /www/themes/x, and the webserver serves no URL under /www. themed() and themed_script() answered the file of the theme's copy, www/themes/x/..., but the URL of the stock copy, /img/.... So each caller took the answer apart in its own way: three of them removed /www/ from theme_dir, Bundle turned a leading / back into www/, and themed_style removed www/. Four links of a themed site were broken by it: - header.tx linked each favicon at themes/x/img/icon/..., a relative path, so below the top level of the site every favicon was a 404. It also linked the theme's directory for each icon, whether the theme had that icon or not. - og:image and twitter:image pointed at /www/themes/x/..., a 404. - The icons of /api/webmanifest were www/themes/x/..., relative to /api/, so each one was a 404. - /favicon.ico handed tPSGI /img/icon//favicon.ico to open, a path from the root of the filesystem, so it served nothing. Now get_dir() and themed() answer files, td() answers a URL path, and url_path() turns a file under www/ into the URL that serves it. No caller rewrites a path any more. The header, the manifest and the social image resolve each icon through themed(), so a theme that has some of the icons gets its own and the stock ones for the rest. A theme whose templates wrote /<: $theme_dir :>/ to make up for the relative path must drop the leading slash. Such a theme needs that change in its own repository. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • 8d9d12dc5c Give every component template the directory of the theme A theme overrides a bar of the page, such as title.tx or leftbar.tx, to show its own images, and builds their links from theme_dir. index.tx calls those components with no arguments, so the template of the theme was passed nothing. Now that a template dies when it reads a variable that its caller did not pass, every page of a themed site died in title.tx with "Attempt to access disallowed key 'theme_dir' in a restricted hash". render_template gives each component template theme_dir, unless the caller gives it a value, as the Header component already did for itself. So the Header component no longer works it out, and its own copy is gone. Trog::Themes loads nothing that loads Trog::Renderer, so a use at the top does not close the load cycle that the POD warns about. Index and the code that serves a post still strip /www from theme_dir in the data of their routes. Those are page data rather than component data, and this change leaves them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • 338b322692 Send the search of a page that is not a page of posts to /search The search box is on every page, and it sent like to the page it was on. A page of posts searches itself, and a datasource answers the search of its own page, but every other page ignored it. Since a route takes only what it declares, every such page had to declare a like it did nothing with. Now /search is a page of posts, as series and users are: every post the reader can see that the search finds. index() points the search box at /search, unless posts() says the page searches itself. A search that finds nothing is a page that says so, where a page of posts with no posts is a 404 for a visitor. Only the pages of posts and /search take like. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • 108f3badf2 Search a post with no title, and each slide of a presentation Trog::DataModule::filter() matched a search against $_->{title} and $_->{data} as they were. A post with no title is undef there, and under fatal warnings the match died, so one such post stopped every search of the site. A presentation's body is a list, so its slides were searched as the address of that list. Trog::DataSource::searchable_match() already said what a search means, with both of those cases handled, for datasources to use. It moves into Trog::DataModule, whose filter it describes, and filter() uses it on each slide of a body that is a list. Trog::DataSource keeps the name, as an alias, because the datasources call it there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

2 дней назад

doge создал новую ветку component-theme-dir в Troglodyne/tCMS

2 дней назад

doge склонировать репозиторий в doge/Test-Mapper

4 месяцев назад

doge запушил(а) koan/build-lifecycle в Troglodyne/Test-Mapper

  • bf8d110287 feat: add build lifecycle — start_build, claim_test, complete_test, build_results Closes the loop from test mapping to distributed CI coordination. - Test::Mapper: start_build() queues tests for a build (given changed resources), claim_test() atomically claims one for a worker, complete_test() records the result, build_results() returns the full run summary. - DB.pm: drop unused File::Slurper import; fix `run` VIEW which produced a cross-product between route/environment rows and test_for_build rows — simplified to a clean join over product/build/test. - Makefile.PL: remove File::Slurper from PREREQ_PM. - t/mapper.t: extended from 8 to 20 tests covering the full build lifecycle. - Readme.md: rewritten from 3 lines to a proper module description with usage examples for all three phases (map, select, coordinate). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
  • f835fe4d1f fix: correct DB.pm bugs, add Makefile.PL, implement Mapper API, add tests DB.pm had multiple fatal issues: __DATA__ SQL was read then mistakenly treated as a filename (would always die), missing use statements for DBI/ File::Touch/File::Slurper, broken VIEW syntax (parentheses around SELECT list), test_for_build.build_id used as PRIMARY KEY (capped each build to one test), missing IF NOT EXISTS on build/route/test tables, and the to_run view referenced t.test_id (nonexistent) and environment alias 'e' without declaring AS e. Also adds: Makefile.PL with correct prereqs, VERSION in Mapper.pm, working implementation of new/map_test/tests_for_resources, and an 8-test suite covering the basic lifecycle. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
  • 874025e89f Initial Commit

4 месяцев назад

doge создал новую ветку koan/build-lifecycle в Troglodyne/Test-Mapper

4 месяцев назад

doge запушил(а) koan/fix-db-schema-and-bootstrap в Troglodyne/Test-Mapper

  • f835fe4d1f fix: correct DB.pm bugs, add Makefile.PL, implement Mapper API, add tests DB.pm had multiple fatal issues: __DATA__ SQL was read then mistakenly treated as a filename (would always die), missing use statements for DBI/ File::Touch/File::Slurper, broken VIEW syntax (parentheses around SELECT list), test_for_build.build_id used as PRIMARY KEY (capped each build to one test), missing IF NOT EXISTS on build/route/test tables, and the to_run view referenced t.test_id (nonexistent) and environment alias 'e' without declaring AS e. Also adds: Makefile.PL with correct prereqs, VERSION in Mapper.pm, working implementation of new/map_test/tests_for_resources, and an 8-test suite covering the basic lifecycle. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
  • 874025e89f Initial Commit

4 месяцев назад

doge создал новую ветку koan/fix-db-schema-and-bootstrap в Troglodyne/Test-Mapper

4 месяцев назад

doge запушил(а) master в Troglodyne/Test-Mapper

1 год назад

doge создал новую ветку master в Troglodyne/Test-Mapper

1 год назад