diff --git a/nano-path-test.yml b/nano-path-test.yml new file mode 100644 index 0000000000..8cdd23d1c5 --- /dev/null +++ b/nano-path-test.yml @@ -0,0 +1,32 @@ +name : nano +version : 6.4 +release : 3 +homepage : https://www.nano-editor.org/dist/v6 +upstreams : + - https://www.nano-editor.org/dist/v6/nano-6.4.tar.xz : 4199ae8ca78a7796de56de1a41b821dc47912c0307e9816b56cc317df34661c0 +summary : GNU Text Editor +description : | + GNU nano is a small and friendly text editor. + + Besides basic text editing, nano offers features like undo/redo, + syntax coloring, interactive search-and-replace, auto-indentation, + line numbers, word completion, file locking, backup files, + and internationalization support. +license : + - GPL-3.0-or-later +builddeps : + - make + - file-devel + - ncurses-devel + - zlib-devel +setup : | + %configure +build : | + %make +install : | + %make_install +packages : + - "%(name)-sharedoc": + paths: + - "/usr/share/doc" +toolchain : gnu diff --git a/source/boulder/controller.d b/source/boulder/controller.d index c9d6232086..7a7dacf893 100644 --- a/source/boulder/controller.d +++ b/source/boulder/controller.d @@ -29,10 +29,10 @@ import std.algorithm : filter; import std.exception : enforce; import std.experimental.logger; import std.file : exists, rmdirRecurse, thisExePath; +import std.format : format; import std.parallelism : totalCPUs; import std.path : absolutePath, baseName, buildNormalizedPath, dirName, buildNormalizedPath; import std.range : take; -import std.string : format; /** * This is the main entry point for all build commands which will be dispatched @@ -65,18 +65,19 @@ public final class Controller : StageContext { if (!mossBinary.exists) { - fatalf("Cannot find `moss` at: %s", _mossBinary); + fatal(format!"Cannot find `moss` at: %s"(_mossBinary)); } if (!containerBinary.exists) { - fatalf("Cannot find `moss-container` at: %s", _containerBinary); + fatal(format!"Cannot find `moss-container` at: %s"(_containerBinary)); } - tracef("moss: %s", _mossBinary); - tracef("moss-container: %s", _containerBinary); + trace(format!"moss: %s"(_mossBinary)); + trace(format!"moss-container: %s"(_containerBinary)); } else { + trace(format!"moss: %s"(_mossBinary)); warning("RUNNING BOULDER WITHOUT CONFINEMENT"); } @@ -154,13 +155,26 @@ public final class Controller : StageContext void build(in string filename) { auto fi = File(filename, "r"); + trace(format!"%s: Parsing recipe file %s"(__FUNCTION__, filename)); recipe = new Spec(fi); recipe.parse(); - + trace(format!"%s: Constructing BuildJob from parsed recipe %s"(__FUNCTION__, filename)); _job = new BuildJob(recipe, filename); + scope (exit) { fi.close(); + /* Unmount anything mounted on both error and normal exit */ + foreach_reverse (ref m; mountPoints) + { + trace(format!"Unmounting %s"(m)); + m.unmountFlags = UnmountFlags.Force | UnmountFlags.Detach; + auto err = m.unmount(); + if (!err.isNull()) + { + error(format!"Unmount failure: %s (%s)"(m.target, err.get.toString)); + } + } } int stageIndex = 0; @@ -177,7 +191,7 @@ public final class Controller : StageContext auto stage = boulderStages[stageIndex]; enforce(stage.functor !is null); - tracef("Stage begin: %s", stage.name); + trace(format!"Stage begin: %s"(stage.name)); StageReturn result = StageReturn.Failure; try { @@ -185,7 +199,7 @@ public final class Controller : StageContext } catch (Exception e) { - errorf("Exception: %s", e.message); + error(format!"Exception: %s"(e.message)); result = StageReturn.Failure; } @@ -198,29 +212,18 @@ public final class Controller : StageContext final switch (result) { case StageReturn.Failure: - errorf("Stage failure: %s", stage.name); + error(format!"Stage failure: %s"(stage.name)); break build_loop; case StageReturn.Success: - infof("Stage success: %s", stage.name); + info(format!"Stage success: %s"(stage.name)); ++stageIndex; break; case StageReturn.Skipped: - tracef("Stage skipped: %s", stage.name); + trace(format!"Stage skipped: %s"(stage.name)); ++stageIndex; break; } } - - /* Unmount anything mounted */ - foreach_reverse (ref m; mountPoints) - { - m.unmountFlags = UnmountFlags.Force | UnmountFlags.Detach; - auto err = m.unmount(); - if (!err.isNull()) - { - errorf("Unmount failure: %s (%s)", m.target, err.get.toString); - } - } } /** @@ -260,7 +263,7 @@ private: { fetcher.clear(); failFlag = true; - errorf("Download failure: %s (reason: %s)", f.sourceURI, failMsg); + error(format!"Download failure: %s (reason: %s)"(f.sourceURI, failMsg)); } /** diff --git a/source/boulder/stages/build_package.d b/source/boulder/stages/build_package.d index d6d6d6ca64..f4ce1af025 100644 --- a/source/boulder/stages/build_package.d +++ b/source/boulder/stages/build_package.d @@ -88,10 +88,16 @@ static private StageReturn buildPackageConfined(scope StageContext context) "-b", context.job.guestPaths.buildRoot, join([context.job.guestPaths.recipe, context.job.name], "/") ]; + /* '-d' was supplied to the boulder invocation, carry it on to mason */ + if (globalLogLevel == LogLevel.trace) + { + args ~= "-d"; + } if (archCommand !is null) { args ~= archCommand; } + trace(format!"%s: executeCommand(%s, %s, %s, \"/\")"(__FUNCTION__, context.containerBinary, args, environ)); auto result = executeCommand(context.containerBinary, args, environ, "/"); auto ret = result.match!((int err) => err != 0 ? StageReturn.Failure : StageReturn.Success, (e) => StageReturn.Failure); @@ -110,12 +116,18 @@ static private StageReturn buildPackageUnconfined(scope StageContext context) "-u", "nobody", "--", /* fakeroot pls! */ "fakeroot", "--", - /* Buidl with mason */ + /* Build with mason */ "mason", "build", "-o", context.job.hostPaths.artefacts, "-b", context.job.hostPaths.buildRoot, "-a", context.architecture, /* Here be your recipe. */ join([context.job.unconfinedRecipe, context.job.name], "/") ]; + /* '-d' was supplied to the boulder invocation, carry it on to mason */ + if (globalLogLevel == LogLevel.trace) + { + args ~= "-d"; + } + trace(format!"%s: executeCommand('runuser, %s, %s, \"/\"')"(__FUNCTION__, args, environ)); auto result = executeCommand("runuser", args, environ, "/"); auto ret = result.match!((int err) => err != 0 ? StageReturn.Failure : StageReturn.Success, (e) => StageReturn.Failure); diff --git a/source/mason/build/builder.d b/source/mason/build/builder.d index 5fb089568d..a848f63cba 100644 --- a/source/mason/build/builder.d +++ b/source/mason/build/builder.d @@ -16,20 +16,19 @@ module mason.build.builder; -import moss.format.source.spec; -import mason.build.context; +import core.sys.posix.sys.stat; import mason.build.collector; -import mason.build.profile; +import mason.build.context; import mason.build.emitter; +import mason.build.profile; import mason.build.util; +import moss.deps.analysis.elves; import moss.deps.analysis; +import moss.format.source.spec; import std.algorithm : each, filter, canFind; -import moss.deps.analysis.elves; +import std.experimental.logger; import std.path : dirName, baseName; import std.string : startsWith, endsWith, format; -import std.experimental.logger; - -import core.sys.posix.sys.stat; /** * As far as boulder is concerned, any directory mode 0755 is utterly uninteresting @@ -71,6 +70,7 @@ public: */ this(string nativeArchitecture) { + trace(__FUNCTION__); if (buildContext.rootDir is null) { buildContext.rootDir = getBuildRoot(); @@ -236,6 +236,7 @@ private: * Setup our boulder chains */ void setupChains() { + trace(__FUNCTION__); const auto boulderChains = [ /* Highest policy */ AnalysisChain("badFiles", [&dropBadPaths], 100), @@ -396,6 +397,7 @@ private: auto debugInfoPath = join([ instance.profiles[0].installRoot, debugInfoPathRelative ], "/"); + trace("debugInfoPath: ", debugInfoPath); auto debugInfoDir = debugInfoPath.dirName; debugInfoDir.mkdirRecurse(); @@ -465,25 +467,27 @@ private: if (code == 0) { - tracef("strip: %s", fileInfo.path); + trace(format!"strip: %s"(fileInfo.path)); } return AnalysisReturn.NextFunction; } /** - * Explicitly requested addition of some path, so add it now. - */ + * Explicitly requested addition of some path, so add it now. + */ void collectPath(in string path, in string root) { import std.path : relativePath; import std.string : format; + debug { trace(format!"%s: %s"(__FUNCTION__, path)); } auto targetPath = path.relativePath(root); if (targetPath[0] != '/') { targetPath = format!"/%s"(targetPath); } + /// FIXME: care about type information auto inf = FileInfo(targetPath, path); inf.target = collector.packageTarget(targetPath); analyser.addFile(inf); @@ -497,6 +501,8 @@ private: { import std.file : dirEntries, DirEntry, SpanMode; + trace(__FUNCTION__); + /** * Custom recursive dirEntries (DFS) style function which lets us * detect empty directories and directories with special permissions @@ -547,6 +553,7 @@ private: import std.algorithm : map, each, joiner; import std.array : array; + trace(__FUNCTION__); string[] arches = ["base"]; arches ~= architectures; @@ -569,34 +576,36 @@ private: * PackageDefinition merged object. This comes from the spec and * our base definitions. */ - void addDefinition(PackageDefinition pd) + void addDefinition(PackageDefinition pkd) { import std.algorithm : each, uniq, sort; import std.range : chain; import std.array : array; + trace(format!"%s: '%s'"(__FUNCTION__, pkd.name)); /* Always insert paths as they're encountered */ - pd = buildContext.spec.expand(pd); - void insertRule(const(string) name) + pkd = buildContext.spec.expand(pkd); + + void insertRule(const(PathDefinition) pd) { - collector.addRule(name, pd.name, inclusionPriority); + collector.addRule(pd, pkd.name, inclusionPriority); ++inclusionPriority; } - pd.paths.each!((p) => insertRule(p)); + pkd.paths.each!((pd) => insertRule(pd)); /* Insert new package if needed */ - if (!(pd.name in packages)) + if (!(pkd.name in packages)) { - packages[pd.name] = pd; + packages[pkd.name] = pkd; return; } /* Merge rules */ - auto oldPkg = &packages[pd.name]; - oldPkg.runtimeDependencies = oldPkg.runtimeDependencies.chain(pd.runtimeDependencies) + auto oldPkg = &packages[pkd.name]; + oldPkg.runtimeDependencies = oldPkg.runtimeDependencies.chain(pkd.runtimeDependencies) .uniq.array; - oldPkg.paths = oldPkg.paths.chain(pd.paths).uniq.array; + oldPkg.paths = oldPkg.paths.chain(pkd.paths).uniq.array; sort(oldPkg.runtimeDependencies); sort(oldPkg.paths); @@ -604,11 +613,11 @@ private: /* Merge details */ if (oldPkg.summary is null) { - oldPkg.summary = pd.summary; + oldPkg.summary = pkd.summary; } if (oldPkg.description is null) { - oldPkg.description = pd.description; + oldPkg.description = pkd.description; } } diff --git a/source/mason/build/collector.d b/source/mason/build/collector.d index 2b8de427ca..2fa9ee4271 100644 --- a/source/mason/build/collector.d +++ b/source/mason/build/collector.d @@ -17,13 +17,16 @@ module mason.build.collector; import std.path; import std.file; +import std.stdio; import std.algorithm : startsWith, filter; import std.exception : enforce; -import std.string : format; +import std.experimental.logger; +import std.format : format; import moss.format.source.package_definition; +import moss.format.source.path_definition; /** - * A CollectionRule simply defines a pattern to match against (glob style) + * A CollectionRule simply defines a path pattern to match against (glob style) * and a priority with which the pattern will be used. * * Increased priority numbers lead to the rule running before other rules. @@ -31,9 +34,10 @@ import moss.format.source.package_definition; package struct CollectionRule { /** - * A glob style pattern to match against + * A PathDefinition supporting a glob style path pattern and a path type + * to match against. */ - string pattern = null; + PathDefinition pathDef; /** * A target name to incorporate, such as "name-devel" @@ -45,10 +49,20 @@ package struct CollectionRule */ int priority = 0; - pure bool match(const(string) inp) @safe + /// FIXME: Update to care about types too + bool match(const(string) encounteredFilePath) @safe { - return (inp == pattern || inp.startsWith(pattern) - || globMatch!(CaseSensitive.yes)(inp, pattern)); + auto result = (pathDef.path == encounteredFilePath || + encounteredFilePath.startsWith(pathDef.path) || + globMatch!(CaseSensitive.yes)(encounteredFilePath, pathDef.path)); + debug + { + if (result && target != null) + { + trace(format!"- '%s' matches rule '%s' from packageTarget '%s'"(encounteredFilePath, pathDef, target)); + } + } + return result; } } @@ -66,32 +80,35 @@ final class BuildCollector public: /** - * Add a priority based rule to the system which can of course be overridden. + * Add a priority based CollectionRule to the system which can of course be overridden. */ - void addRule(string pattern, string target, uint priority = 0) @safe + void addRule(PathDefinition pathDef, string packageTarget, uint priority = 0) @safe { import std.algorithm : sort; + debug { trace(format!"# %s(%s, %s, %s)"(__FUNCTION__, pathDef, packageTarget, priority)); } /* Sort ahead of time */ - rules ~= CollectionRule(pattern, target, priority); + rules ~= CollectionRule(pathDef, packageTarget, priority); rules.sort!((a, b) => a.priority > b.priority); } /** - * Return the package target for the given filesystem path by matching - * globs. + * Return the package target for the given encountered filesystem path by .match-ing + * it against the list of CollectionRules w/PathDefinition globs. + * TODO: .. and type */ - auto packageTarget(const(string) targetPath) + auto packageTarget(const(string) encounteredFilePath) { - auto matchingSet = rules.filter!((r) => r.match(targetPath)); + ///FIXME this needs extra filtering functionality for the type + auto matchingSet = rules.filter!((r) => r.match(encounteredFilePath)); enforce(!matchingSet.empty, - "packageTarget: No matching rule for path: %s".format(targetPath)); + "LINT: packageTarget(): No matching rule for path: %s".format(encounteredFilePath)); return matchingSet.front.target; } private: - /* Map file glob patterns to target packages */ + /* Map PathDefinition glob patterns + file types to target packages */ CollectionRule[] rules; } diff --git a/source/mason/build/context.d b/source/mason/build/context.d index 0bad212a21..7210de1dfb 100644 --- a/source/mason/build/context.d +++ b/source/mason/build/context.d @@ -15,17 +15,18 @@ module mason.build.context; + + import moss.format.source.macros; -import moss.format.source.spec; import moss.format.source.script; - -import std.parallelism : totalCPUs; +import moss.format.source.spec; import std.concurrency : initOnce; -import std.path : buildNormalizedPath; -import std.string : endsWith; import std.experimental.logger; +import std.format : format; +import std.parallelism : totalCPUs; +import std.path : buildNormalizedPath; import std.range : empty; - +import std.string : endsWith; /** * Return the current shared Context for all moss operations */ @@ -53,7 +54,9 @@ public final class BuildContext jobs = 0; + trace(format!"%s.loadMacros()"(__FUNCTION__)); this.loadMacros(); + trace(format!"%s.loadMacros() complete"(__FUNCTION__)); } /** @@ -254,7 +257,7 @@ private: { continue; } - tracef("Loading architecture: %s", target.name.baseName); + trace(format!"%s: Parsing YML macro file: %s"(__FUNCTION__, target.name.baseName)); auto f = new MacroFile(File(target.name)); f.parse(); /* Remove the .yml suffix */ @@ -280,7 +283,9 @@ private: } auto name = nom.name.baseName[0 .. $ - 4]; file = new MacroFile(File(nom.name)); + trace(format!"%s: %s.parse()"(__FUNCTION__, nom.name)); file.parse(); + trace(format!"%s: %s.parse() complete"(__FUNCTION__, nom.name)); actionFiles ~= file; } } diff --git a/source/mason/build/controller/package.d b/source/mason/build/controller/package.d index 9745a58a08..84321ccfad 100644 --- a/source/mason/build/controller/package.d +++ b/source/mason/build/controller/package.d @@ -18,15 +18,16 @@ module mason.build.controller; import mason.build.builder; import mason.build.context; +import moss.format.source.spec; import std.algorithm : each, filter; +import std.array : join; import std.exception : enforce; +import std.experimental.logger; import std.file : exists, mkdirRecurse; -import std.path : dirName, absolutePath, baseName; -import std.string : format, endsWith; -import moss.format.source.spec; +import std.format : format; import std.parallelism : TaskPool, totalCPUs; -import std.array : join; -import std.experimental.logger; +import std.path : absolutePath, baseName, dirName; +import std.string : endsWith; /** * The BuildController is responsible for the main execution cycle of Boulder, @@ -43,11 +44,11 @@ public final class BuildController if (architecture == "native") { import moss.core.platform : platform; - + trace(format!"%s(%s)"(__FUNCTION__, architecture)); architecture = platform().name; } this.architecture = architecture; - infof("Architecture: %s", architecture); + info(format!"Architecture: %s"(architecture)); } /** * Request that we begin building the given path @@ -67,7 +68,9 @@ public final class BuildController /* Set up the new builder */ auto s = new Spec(File(path, "r")); + trace(format!"%s: Parsing Spec(%s)"(__FUNCTION__, path)); s.parse(); + trace(format!"%s: Parsing Spec(%s) complete"(__FUNCTION__, path)); buildContext.spec = s; buildContext.specDir = path.dirName.absolutePath; @@ -113,6 +116,7 @@ public final class BuildController */ bool stageBuild() { + trace(__FUNCTION__); return builder.buildProfiles(); } @@ -152,7 +156,7 @@ private: auto sw = StopWatch(AutoStart.yes); scope (exit) { - infof("[%s] Finished: %s", label, sw.peek); + info(format!"[%s] Finished: %s"(label, sw.peek)); } return dg(); } diff --git a/source/mason/build/profile.d b/source/mason/build/profile.d index 588605f15f..1557698273 100644 --- a/source/mason/build/profile.d +++ b/source/mason/build/profile.d @@ -15,15 +15,16 @@ module mason.build.profile; -import moss.format.source.spec; -import moss.format.source.script; import mason.build.collector; import mason.build.context; -import mason.build.stage; import mason.build.manifest; -import std.array : join; +import mason.build.stage; import moss.deps.analysis; +import moss.format.source.script; +import moss.format.source.spec; +import std.array : join; import std.experimental.logger; +import std.format : format; /** * A build profile is generated for each major build profile in the @@ -42,6 +43,7 @@ public: */ this(const(string) architecture) { + trace(__FUNCTION__); this._architecture = architecture; this._buildRoot = join([buildContext.rootDir, "build", architecture], "/"); this._installRoot = join([buildContext.rootDir, "install"], "/"); @@ -165,6 +167,7 @@ public: import moss.core.ioutil; import std.sumtype : match; + trace(format!"%s(%s, %s,