MODULE--------------------------------------------------------------------------ProjectManager EXPORTSMain ; IMPORT Text, TextRd, TextSeq, TextTextTbl, ParseParams, Rsrc, Time, FileWr, Pathname, Env, Process, RefList, Stdio, Wr, Fmt, OSError, Rd, Scan, FmtTime; IMPORT (* FSFixed AS *) FS; IMPORT SMsg AS Msg, PkgBase, PkgBaseBundle, PrjDesc, ProjectManagerBundle, Snapshots, FSUtils, TextUtils, CompactRC, Copyright, Release, PoolSet, SimpleScanner, ScanToken, Checkpoint, RsrcUtils, PkgVC, APN AS APN, DirStack, Confirmation, Tag, ChangeSet, OSSpecials, PkgVCUtils, Creation, TextReadingUtils, Version, SortedTextChangeSetTbl, SortedTimeChangeSetTbl, SortedTextPrjDescTbl, SortedTimePrjDescTbl; FROM TextUtils IMPORT MemberOfTextSeq;
REVEAL SimpleScanner.Token = ScanToken.T BRANDED "ScanToken prjm 0.0" OBJECT METHODS END;---------------------------------------------------------------------------
PROCEDURE---------------------------------------------------------------------------M (msg : TEXT) = BEGIN TRY Wr.PutText(Stdio.stdout, msg & "\n"); EXCEPT ELSE Msg.Fatal("cannot write to stdout", 1000); END; END M;
PROCEDURE---------------------------------------------------------------------------OutTextSeq (header : TEXT; seq : TextSeq.T) = BEGIN IF NOT Msg.tFlag THEN RETURN END; M(header); IF seq.size() > 0 THEN FOR i := 0 TO seq.size() - 1 DO M(" " & seq.get(i)); END; ELSE M("none"); END; M(""); END OutTextSeq;
PROCEDURE---------------------------------------------------------------------------TOutTextSeq (header : TEXT; seq : TextSeq.T) = BEGIN IF NOT Msg.tFlag THEN RETURN END; Msg.T(header); IF seq.size() > 0 THEN FOR i := 0 TO seq.size() - 1 DO Msg.T(" " & seq.get(i)); END; ELSE Msg.T("none"); END; Msg.T(""); END TOutTextSeq;
PROCEDURE---------------------------------------------------------------------------VOutTextSeq (header : TEXT; seq : TextSeq.T) = BEGIN IF NOT Msg.vFlag THEN RETURN END; Msg.V(header); IF seq.size() > 0 THEN FOR i := 0 TO seq.size() - 1 DO Msg.V(" " & seq.get(i)); END; ELSE Msg.T("none"); END; Msg.V(""); END VOutTextSeq;
PROCEDURE---------------------------------------------------------------------------OutTextTable (header : TEXT; tbl : TextTextTbl.T) = VAR iter : TextTextTbl.Iterator; key, val : TEXT; empty := TRUE; BEGIN IF tbl = NIL THEN Msg.Error2("OutTextTable", "internal error: tbl is NIL"); RETURN; END; M(header); iter := tbl.iterate(); WHILE iter.next(key, val) DO empty := FALSE; M(" " & key & " " & val); END; IF empty THEN M("none"); END; M(""); END OutTextTable;
PROCEDURE---------------------------------------------------------------------------TOutTextTable (header : TEXT; tbl : TextTextTbl.T) = VAR iter := tbl.iterate(); key, val : TEXT; empty := TRUE; BEGIN Msg.T(header); WHILE iter.next(key, val) DO empty := FALSE; Msg.T(" " & key & " " & val); END; IF empty THEN Msg.T("none"); END; Msg.T(""); END TOutTextTable;
TYPE Action = {BuildLocal, BuildProject, BuildGlobal, BuiltOk, ShipLocal, ShipProject, ShipGlobal, Clean, RealClean, Diff, CDiff, UDiff, IsRelease, IsModified, ShowModified, IsOutOfDate, ShowOutOfDate, HasConflicts, ShowConflicts, Checkout, CommitDevel, CommitRelease, CommitLocalFiles, NewSnapshot, NewRelease, MakeRelease, StableRelease, Apply, OrderedApply, ApplyAction, OrderedApplyAction, SelectBy, OrderedSelectBy, CheckImports, DependingNodes, CreatePkgOvrFiles, ShowPackages, ShowPackageKinds, ShowSrcDirectories, ShowUpdateSequence, ShowSnapshot, ShowRelease, EditSnapshot, EditRelease, ShowPackagePaths, SnapshotLog, ReleaseLog, ShowReleases, ShowSnapshots, ShowChangeSets, ChangeSetLog, ChangeSetDiff, ChangeSetCDiff, ChangeSetUDiff, EditChangeSet, MergeChangeSet, ListKinds, DumpKinds, CheckState, ShowStateCache, NewStateCache, ShowShortStatus, ShowLongStatus, PurgeUnsureVersionInfo, PurgeBuildInfo, Import, Export, Undefined }; ActionSet = SET OF Action; CommitType = {Major, Minor, Patch}; CONST BuildAction = ActionSet{Action.BuildLocal, Action.BuildProject, Action.BuildGlobal}; ShipAction = ActionSet{Action.ShipLocal, Action.ShipProject, Action.ShipGlobal}; CleanAction = ActionSet{Action.Clean, Action.RealClean}; DiffAction = ActionSet{Action.Diff, Action.CDiff, Action.UDiff, Action.ChangeSetDiff, Action.ChangeSetCDiff, Action.ChangeSetUDiff}; PredicateAction = ActionSet{Action.IsRelease, Action.IsModified, Action.IsOutOfDate, Action.HasConflicts}; PkgCommitAction = ActionSet{Action.CommitDevel, Action.CommitRelease}; PkgFreezeAction = ActionSet{Action.NewSnapshot, Action.NewRelease, Action.MakeRelease}; ApplyAction = ActionSet{Action.ApplyAction, Action.OrderedApplyAction}; ApplyCmdListAction = ActionSet{Action.Apply, Action.OrderedApply}; SelectByCmdListAction = ActionSet{Action.SelectBy, Action.OrderedSelectBy}; PreParseAction = ActionSet{Action.BuildLocal, Action.BuildProject, Action.BuildGlobal, Action.ShipGlobal, Action.ShipLocal, Action.ShipProject, Action.Diff, Action.CDiff, Action.UDiff, Action.ChangeSetDiff, Action.ChangeSetCDiff, Action.ChangeSetUDiff, Action.MergeChangeSet, Action.IsRelease, Action.IsModified, Action.IsOutOfDate, Action.HasConflicts, Action.ShowConflicts, Action.ShowModified, Action.ShowOutOfDate, Action.Clean, Action.RealClean, Action.CommitDevel, Action.CommitRelease, Action.NewSnapshot, Action.NewRelease, Action.MakeRelease, Action.ApplyAction, Action.StableRelease, Action.Apply, Action.OrderedApply, Action.OrderedApplyAction, Action.SelectBy, Action.OrderedSelectBy, Action.DependingNodes, Action.CheckImports, Action.CreatePkgOvrFiles, Action.ShowPackages, Action.ShowPackageKinds, Action.ShowSrcDirectories, Action.ShowUpdateSequence, Action.ShowSnapshot, Action.ShowRelease, Action.EditSnapshot, Action.EditRelease, Action.ShowPackagePaths, Action.ShowSnapshots, Action.ShowReleases, Action.ShowChangeSets, Action.ChangeSetLog, Action.SnapshotLog, Action.ReleaseLog, Action.CheckState, Action.ShowStateCache, Action.NewStateCache, Action.ShowShortStatus, Action.ShowLongStatus, Action.PurgeUnsureVersionInfo, Action.PurgeBuildInfo, Action.BuiltOk, Action.Import, Action.Export, Action.Checkout}; PreCheckAction = ActionSet{Action.BuildLocal, Action.BuildProject, Action.BuildGlobal, Action.ShipGlobal, Action.ShipLocal, Action.ShipProject, Action.MergeChangeSet, Action.IsRelease, Action.IsModified, Action.IsOutOfDate, Action.HasConflicts, Action.ShowConflicts, Action.ShowModified, Action.ShowOutOfDate, Action.Clean, Action.RealClean, Action.CreatePkgOvrFiles, Action.CommitDevel, Action.CommitRelease, Action.NewSnapshot, Action.NewRelease, Action.MakeRelease, Action.ApplyAction, Action.Apply, Action.OrderedApply, Action.OrderedApplyAction, Action.SelectBy, Action.OrderedSelectBy, Action.ShowPackages, Action.ShowPackageKinds, Action.ShowSrcDirectories, Action.ShowUpdateSequence, Action.CheckState, Action.BuiltOk, Action.DependingNodes, Action.CheckImports}; PreDepAction = ActionSet{Action.BuildLocal, Action.BuildProject, Action.BuildGlobal, Action.ShipGlobal, Action.ShipLocal, Action.ShipProject, Action.CommitRelease, Action.OrderedSelectBy, Action.OrderedApply, Action.OrderedApplyAction, Action.ShowUpdateSequence, Action.CreatePkgOvrFiles, Action.DependingNodes, Action.CheckImports}; NoCacheAction = ActionSet{Action.StableRelease, Action.ShowSnapshots, Action.ShowReleases, Action.ShowChangeSets, Action.EditChangeSet, Action.ChangeSetLog, Action.SnapshotLog, Action.ReleaseLog, Action.ShowSnapshot, Action.ShowRelease, Action.EditSnapshot, Action.EditRelease, Action.ShowPackagePaths, Action.Import, Action.Export, Action.ListKinds, Action.DumpKinds}; NoSnapsAction = ActionSet{Action.ListKinds, Action.DumpKinds, Action.IsRelease, Action.IsModified, Action.IsOutOfDate, Action.HasConflicts, Action.ShowConflicts, Action.ShowModified, Action.ShowOutOfDate, Action.BuiltOk, Action.ShowStateCache, Action.NewStateCache, Action.ShowShortStatus, Action.ShowLongStatus, Action.PurgeUnsureVersionInfo, Action.PurgeBuildInfo, Action.ShowPackages, Action.ShowPackageKinds, Action.ShowSrcDirectories, Action.ShowUpdateSequence, Action.Apply, Action.OrderedApply, Action.OrderedApplyAction, Action.CheckImports, Action.CheckState, Action.SelectBy, Action.OrderedSelectBy} + BuildAction + ShipAction + CleanAction;---------------------------------------------------------------------------
CONST ActStateFN = "ActState"; OldStateFN = "OldState"; PrjDescFN = "PrjDesc"; PrjMagicFN = "PrjMagic"; PrjDepGraphFN = "DepGraph"; PrjCheckpFN = ".checkpoint"; PkgOvrFN = "PkgOvr";---------------------------------------------------------------------------
VAR (* Main *) homeDir := Env.Get("HOME"); user := Env.Get("USER"); rsrcPath : Rsrc.Path; noAction : BOOLEAN; nodep := FALSE; depsMandatory := TRUE; nTargets : CARDINAL; targets : TextSeq.T; action := Action.Undefined; stopOnErrors := TRUE; stopOnFailures := TRUE; prjFileName := PrjDescFN; actPrjFileName := PrjDescFN; prjMagicFile := PrjMagicFN; prjDepGraphFile := PrjDepGraphFN; cfg := NEW(PkgBase.T); cfgData : TEXT; prjdesc : PrjDesc.T; commitType : CommitType := CommitType.Patch; cmdList : TEXT; externalShell : TEXT := NIL; dependendPkgs := FALSE; onlyModified := FALSE; onlyOutOfDate := FALSE; onlyNotReleased := FALSE; modifiedAndDeps := FALSE; outOfDateAndDeps := FALSE; force := FALSE; forceRelease := FALSE; useStateCache := TRUE; updateStateCache := FALSE; verboseCache := TRUE; cacheEarly := FALSE; modifiedPkgs : TextSeq.T := NIL; outOfDatePkgs : TextSeq.T := NIL; snapshotName : TEXT; newName : TEXT := NIL; packageKind : PkgBase.Kind := NIL; defaultPackageKind : PkgBase.Kind := NIL; snaps : Snapshots.T; env : TextTextTbl.T; vars : TextTextTbl.T; stateLabelPattern: TEXT := NIL; collectionroot : TEXT := Pathname.Current; lazy : BOOLEAN; inCheckpFileName := PrjCheckpFN; outCheckpFileName:= PrjCheckpFN; useInternalVC := TRUE; useVC := TRUE; pkgvcCreator : PoolSet.PkgVCCreator; platform : TEXT; packageDir : TEXT := "."; prjName : TEXT := "undefined"; prjRoot : TEXT := "."; fileName : TEXT := NIL; name : TEXT := NIL; commitFile : TEXT := NIL; commitMsg : TEXT := NIL; tag1 : TEXT := NIL; tag2 : TEXT := NIL; tag1vals : TextTextTbl.T := NIL; tag2vals : TextTextTbl.T := NIL; tag1prjdesc : PrjDesc.T := NIL; tag2prjdesc : PrjDesc.T := NIL; changeSetName : TEXT := NIL; changeSet : ChangeSet.T := NIL; importRelevanceLevel := 2; autoovr := TRUE; savePreReleases := FALSE; sort := Snapshots.Sort.None; sortUp := TRUE; longListing := FALSE; sortByModificationDate := FALSE; (* former constants, now configurable*) snapshotDir := "snaps";---------------------------------------------------------------------------
PROCEDURE---------------------------------------------------------------------------CommitHookDefined (hook : TEXT) : BOOLEAN = BEGIN RETURN CompactRC.Defined(env, hook) OR CompactRC.Defined(env, "external-commit-hook"); END CommitHookDefined;
PROCEDURE---------------------------------------------------------------------------InitGlobalVars () = VAR cfgDataRd : TextRd.T; hosttype : TEXT; ostype : TEXT; BEGIN vars := NEW(TextTextTbl.Default).init(); env := CompactRC.Eval(ProjectManagerBundle.Get()); env := CompactRC.Evaluate(env); defaultPackageKind := CompactRC.ComputePkgKind(env); EVAL env.get("HOME", homeDir); EVAL env.get("USER", user); EVAL cfg.init(env); hosttype := CompactRC.GetValue(env, "tpc-hosttype"); IF hosttype = NIL THEN hosttype := CompactRC.GetValue(env, "tpc-hosttype-default"); END; IF hosttype = NIL THEN hosttype := "unknown"; END; ostype := CompactRC.GetValue(env, "tpc-ostype"); IF ostype = NIL THEN ostype := CompactRC.GetValue(env, "tpc-ostype-default"); END; IF ostype = NIL THEN ostype := "unknown"; END; platform := hosttype & "-" & ostype; (* use a platform dependend checkpoint file if it exists *) IF FSUtils.IsFile(inCheckpFileName & "-" & platform) OR NOT FSUtils.IsFile(inCheckpFileName) THEN inCheckpFileName := inCheckpFileName & "-" & platform; outCheckpFileName := inCheckpFileName; END; packageKind := Env.Get("PKGKIND"); IF packageKind = NIL THEN IF NOT env.get("pkgkind", packageKind) THEN packageKind := NIL; END; END; IF CompactRC.Defined(env, "collectionroot") THEN collectionroot := CompactRC.GetValue(env, "collectionroot"); END; IF CompactRC.Defined(env, "internal-vc") THEN useInternalVC := TextUtils.BoolVal(CompactRC.GetValue(env, "internal-vc"), TRUE); END; IF CompactRC.Defined(env, "prjm-internal-vc") THEN useInternalVC := TextUtils.BoolVal(CompactRC.GetValue(env, "prjm-internal-vc"), TRUE); END; IF CompactRC.Defined(env, "enforce-pkgdeps") THEN depsMandatory := TextUtils.BoolVal(CompactRC.GetValue(env, "enforce-pkgdeps"), TRUE); END; IF CompactRC.Defined(env, "cvspath") THEN EVAL env.put("cvspath", CompactRC.GetValue(env, "cvspath")); END; IF CompactRC.Defined(env, "editor") THEN EVAL env.put("editor", CompactRC.GetValue(env, "editor")); END; VAR cacheIgnoreDirs : TEXT := NIL; cacheIgnoreFiles : TEXT := NIL; fingerprintIgnoreDirs : TEXT := NIL; fingerprintIgnoreFiles : TEXT := NIL; BEGIN EVAL env.get("filecache-ignore-dirs", cacheIgnoreDirs); EVAL env.get("filecache-ignore-files", cacheIgnoreFiles); EVAL env.get("fingerprint-ignore-dirs", fingerprintIgnoreDirs); EVAL env.get("fingerprint-ignore-files", fingerprintIgnoreFiles); TRY Checkpoint.DefineIgnorePatterns( cacheIgnoreDirs, cacheIgnoreFiles, fingerprintIgnoreDirs, fingerprintIgnoreFiles); EXCEPT Checkpoint.Error(e) => Msg.Error("wrong pattern in config file: " & e); END; END; IF CompactRC.Defined(env, "configpath") THEN WITH configpath = CompactRC.GetValue(env, "configpath") DO Msg.V(" using CONFIGPATH from .compactrc or compactrc:\n " & configpath); rsrcPath := NIL; WITH p = TextUtils.SubstChar(TextUtils.Compress(configpath), ';', ' ') DO (* FIXME: this will break if filenames contain blanks. Use TextUtils.Tokenize instead. *) WITH trd = TextRd.New(p) DO TRY WHILE NOT Rd.EOF(trd) DO WITH dir = TextReadingUtils.GetToken(trd) DO IF rsrcPath = NIL THEN rsrcPath := RefList.List1(dir); ELSE rsrcPath := RefList.AppendD(rsrcPath, RefList.List1(dir)); END; END; END; EXCEPT ELSE END; END; END; END; ELSE Msg.V(" using DEFAULT CONFIGPATH"); rsrcPath := Rsrc.BuildPath( Pathname.Join(homeDir, "compact", NIL), "/usr/contrib/lib/compact", "/usr/local/lib/compact", "/opt/compact"); END; rsrcPath := RefList.AppendD(rsrcPath, RefList.List1( ProjectManagerBundle.Get())); (* PkgBaseBundle.Get())); *) (* rsrcPath defined *) cfgData := CompactRC.GetRsrcText("PkgBase.DefaultData", PkgBaseBundle.Get(), rsrcPath, env); cfgDataRd := TextRd.New(cfgData); IF NOT cfg.addDefs(cfgDataRd) THEN Msg.Fatal("error in PkgBase.DefaultData", 1001); END; (* initializing local version control backend *) TRY packageDir := DirStack.GetWorkingDir(); PkgVC.VC.setPackageRoot(APN.New(packageDir)); prjName := Pathname.Last(packageDir); prjRoot := packageDir; EXCEPT DirStack.Error(t) => Msg.Error(t); Process.Exit(2); | PkgVC.E(t) => Msg.Error(t); Process.Exit(2); END; PkgVC.VC.setEnvironment(env); END InitGlobalVars;
PROCEDURE---------------------------------------------------------------------------InitSnapshots () = BEGIN TRY IF NOT FSUtils.IsDir(snapshotDir) THEN WITH msg = "The snapshot directory `" & snapshotDir & "' does not exist.\n" & "Shall I create it now" DO IF NOT force AND NOT PkgVC.confirmation.okay(msg) THEN IF action IN NoSnapsAction THEN Msg.Warning("no snapshot directory - subsequent actions "& "may fail"); ELSE Msg.Fatal("cannot continue without snapshot directory"); END; END; END; IF force THEN Msg.T("creating new snapshot directory"); ELSE Msg.V("creating new snapshot directory"); END; END; IF useVC THEN snaps := NEW(Snapshots.T).init(snapshotDir, cfg, PkgVC.VC); ELSE snaps := NEW(Snapshots.T).init(snapshotDir, cfg); END; EXCEPT Snapshots.Error(e) => Msg.Fatal("cannot read snapshot directory: " & e); END; END InitSnapshots;
PROCEDURE---------------------------------------------------------------------------Usage () = BEGIN TRY RsrcUtils.PageResource(rsrcPath, "ShortUsageHelp", pageit); EXCEPT RsrcUtils.Error(e) => TRY Wr.PutText(Stdio.stderr, "error listing help: " & e & "\n") EXCEPT ELSE END; END; Process.Exit(0); END Usage; VAR pageit := TRUE;
VAR pp := NEW(ParseParams.T).init(Stdio.stderr);---------------------------------------------------------------------------
PROCEDURE---------------------------------------------------------------------------PreEvalArguments () = BEGIN TRY pageit := NOT pp.keywordPresent("-nopager") AND NOT pp.keywordPresent("-pipe"); (* release version option *) IF pp.keywordPresent("-version") THEN Release.Show(); Process.Exit(0); END; (* creation date option *) IF pp.keywordPresent("-created") THEN M(Creation.Date & " on " & Creation.System); Process.Exit(0); END; (* some message and trace options *) Msg.vFlag := pp.keywordPresent("-v"); (* be verbose *) Msg.dFlag := pp.keywordPresent("-d"); (* debug messages *) Msg.tFlag := NOT pp.keywordPresent("-q"); (* do not run quiet *) noAction := pp.keywordPresent("-n"); (* don't execute anything *) stopOnErrors := NOT pp.keywordPresent("-k"); stopOnFailures := NOT pp.keywordPresent("-f"); PrjDesc.debugStateCache := pp.keywordPresent("-debugStateCache"); EXCEPT ParseParams.Error => Msg.Fatal("parameter error", 3); <*NOWARN*> END; END PreEvalArguments;
PROCEDURE---------------------------------------------------------------------------EvalArguments () = PROCEDURE CheckCommitType() = BEGIN IF pp.keywordPresent("patch") THEN commitType := CommitType.Patch; ELSIF pp.keywordPresent("minor") THEN commitType := CommitType.Minor; ELSIF pp.keywordPresent("major") THEN commitType := CommitType.Major; END; END CheckCommitType; BEGIN TRY (* help option *) IF pp.keywordPresent("-h") OR pp.keywordPresent("-help") THEN Usage(); END; (* man option *) IF pp.keywordPresent("-man") OR pp.keywordPresent("-desc") THEN TRY RsrcUtils.PageResource(rsrcPath, "UsageHelp", pageit); EXCEPT RsrcUtils.Error(e) => TRY Wr.PutText(Stdio.stdout, "error listing description: " & e & "\n") EXCEPT ELSE END; END; Process.Exit(0); END; (* copyright option *) IF pp.keywordPresent("-cr") OR pp.keywordPresent("-copyright") THEN Copyright.Show(Copyright.T.All); Process.Exit(0); END; (* some message and trace options *) onlyModified := pp.keywordPresent("-m"); onlyOutOfDate := pp.keywordPresent("-o") OR pp.keywordPresent("-outofdate"); useStateCache := NOT pp.keywordPresent("-nocache") AND NOT pp.keywordPresent("-noc"); IF pp.keywordPresent("-qc") OR pp.keywordPresent("quietCache") OR pp.keywordPresent("-quietcache") THEN verboseCache := FALSE; END; IF pp.keywordPresent("-ce") OR pp.keywordPresent("cacheEarly") OR pp.keywordPresent("-cacheearly") THEN cacheEarly := TRUE; END; IF pp.keywordPresent("-message") OR pp.keywordPresent("-msg") THEN commitMsg := pp.getNext(); END; IF pp.keywordPresent("-file") THEN commitFile := pp.getNext(); END; IF pp.keywordPresent("-nostdin") OR pp.keywordPresent("-usegui") THEN PkgVC.confirmation := NEW(Confirmation.ExternalClosure, cmd := "confirm"); END; IF pp.keywordPresent("-md") OR pp.keywordPresent("-modifieddeps")THEN onlyModified := TRUE; modifiedAndDeps := TRUE; END; IF pp.keywordPresent("-od") OR pp.keywordPresent("-outofdatedeps") THEN onlyOutOfDate := TRUE; outOfDateAndDeps := TRUE; END; IF pp.keywordPresent("-nd") OR pp.keywordPresent("-nodep") THEN nodep := TRUE; depsMandatory := FALSE; END; dependendPkgs := pp.keywordPresent("-dep") OR pp.keywordPresent("-dependend"); lazy := pp.keywordPresent("-lazy"); savePreReleases := pp.keywordPresent("-saveprereleases") OR pp.keywordPresent("-saveall"); IF pp.keywordPresent("-fr") OR pp.keywordPresent("-forcerelease")THEN forceRelease := TRUE; END; IF pp.keywordPresent("-F") OR pp.keywordPresent("-force")THEN force := TRUE; END; IF pp.keywordPresent("-noivc") OR pp.keywordPresent("-nointernalvc") OR pp.keywordPresent("-nointernalversioncontrol") THEN useInternalVC := FALSE; END; IF pp.keywordPresent("-novc") OR pp.keywordPresent("-noversioncontrol") THEN useVC := FALSE; END; WHILE pp.keywordPresent("-D") DO VAR n, v : TEXT; def := pp.getNext(); seq := TextUtils.Split(def, "="); BEGIN IF seq.size() < 2 THEN Msg.Fatal("variable definition without `=': " & def); END; v := TextUtils.Compress(seq.remhi()); WHILE seq.size() > 0 DO n := TextUtils.Compress(seq.remlo()); IF Text.Empty(n) THEN Msg.Fatal("empty variable name in " & def); END; EVAL vars.put(n, v); Msg.D(" " & n & " = " & v); END; END; END; (* implicit environment variables TAG1 and TAG2 *) IF pp.keywordPresent("-t") THEN tag1 := pp.getNext(); END; IF pp.keywordPresent("-t") THEN tag2 := pp.getNext(); END; (* named change set *) IF pp.keywordPresent("-changeset") OR pp.keywordPresent("-cs")THEN changeSetName := pp.getNext(); END; (* explicit project filename *) IF pp.keywordPresent("-p") THEN prjFileName := pp.getNext(); prjMagicFile := Pathname.Prefix(prjFileName); prjMagicFile := Pathname.Join(prjMagicFile, PrjMagicFN, NIL); prjDepGraphFile := Pathname.Prefix(prjFileName); prjDepGraphFile := Pathname.Join(prjDepGraphFile, PrjDepGraphFN, NIL); actPrjFileName := prjFileName; END; (* explicit checkpoint file *) IF pp.keywordPresent("-checkpointfile") OR pp.keywordPresent("-cpf") THEN inCheckpFileName := pp.getNext(); outCheckpFileName := inCheckpFileName; END; (* explicit snapshot directory *) IF pp.keywordPresent("-snapdir") OR pp.keywordPresent("-sd") THEN snapshotDir := pp.getNext(); END; (* external shell *) IF pp.keywordPresent("-shell") OR pp.keywordPresent("-sh") THEN externalShell := pp.getNext(); END; (* explicit package kind *) IF pp.keywordPresent("-pkgkind") OR pp.keywordPresent("-kind") THEN packageKind := pp.getNext(); END; (* import relevance level for PkgOvr files *) IF pp.keywordPresent("-relevancelevel") OR pp.keywordPresent("-importlevel") OR pp.keywordPresent("-irl") THEN TRY importRelevanceLevel := Scan.Int(pp.getNext()); EXCEPT ELSE Msg.Fatal("cannot convert import relevance level (integer)"); END; END; IF pp.keywordPresent("-novr") THEN autoovr := FALSE; END; (* building *) IF pp.keywordPresent("-localbuild") OR pp.keywordPresent("-build") OR pp.keywordPresent("-buildlocal") THEN action := Action.BuildLocal; ELSIF pp.keywordPresent("-projectbuild") OR pp.keywordPresent("-buildproject") THEN action := Action.BuildProject; ELSIF pp.keywordPresent("-globalbuild") OR pp.keywordPresent("-buildglobal") THEN action := Action.BuildGlobal; ELSIF pp.keywordPresent("-builtokay") OR pp.keywordPresent("-builtok") OR pp.keywordPresent("-bok") THEN action := Action.BuiltOk; ELSIF pp.keywordPresent("-createpkgovrfiles") OR pp.keywordPresent("-pkgovr") OR pp.keywordPresent("-saveimports") OR pp.keywordPresent("-saveimps") OR pp.keywordPresent("-imps") THEN action := Action.CreatePkgOvrFiles; snapshotName := pp.getNext(); (* resource information *) ELSIF pp.keywordPresent("-listpkgkinds") OR pp.keywordPresent("-listkinds") THEN action := Action.ListKinds; ELSIF pp.keywordPresent("-dumpallpkgkinds") OR pp.keywordPresent("-dumppkgkinds") OR pp.keywordPresent("-dumpkinds") THEN action := Action.DumpKinds; (* checks *) ELSIF pp.keywordPresent("-check") THEN action := Action.CheckImports; IF pp.keywordPresent("-label") OR pp.keywordPresent("-l") THEN action := Action.CheckState; stateLabelPattern := pp.getNext(); END; ELSIF pp.keywordPresent("-showpackages") OR pp.keywordPresent("-showpkgs") THEN action := Action.ShowPackages; ELSIF pp.keywordPresent("-showsrcdirectories") OR pp.keywordPresent("-showsdirs") THEN action := Action.ShowSrcDirectories; ELSIF pp.keywordPresent("-dependencies") OR pp.keywordPresent("-showdeps") OR pp.keywordPresent("-deps") THEN action := Action.DependingNodes; ELSIF pp.keywordPresent("-updatesequence") OR pp.keywordPresent("-upseq") OR pp.keywordPresent("-tsort") THEN action := Action.ShowUpdateSequence; ELSIF pp.keywordPresent("-showpackagekinds") OR pp.keywordPresent("-showkinds") OR pp.keywordPresent("-kinds") THEN action := Action.ShowPackageKinds; ELSIF pp.keywordPresent("-showsnapshots") OR pp.keywordPresent("-showsnaps") OR pp.keywordPresent("-snaps") THEN action := Action.ShowSnapshots; sort := Snapshots.Sort.ByName; longListing := pp.keywordPresent("-l"); ELSIF pp.keywordPresent("-showreleases") OR pp.keywordPresent("-showrels") OR pp.keywordPresent("-rels") THEN action := Action.ShowReleases; sort := Snapshots.Sort.ByName; longListing := pp.keywordPresent("-l"); ELSIF pp.keywordPresent("-showsnapshot") OR pp.keywordPresent("-showsnap") OR pp.keywordPresent("-ssnap") THEN action := Action.ShowSnapshot; longListing := pp.keywordPresent("-l"); ELSIF pp.keywordPresent("-showrelease") OR pp.keywordPresent("-showrel") OR pp.keywordPresent("-srel") THEN action := Action.ShowRelease; longListing := pp.keywordPresent("-l"); ELSIF pp.keywordPresent("-editsnapshot") OR pp.keywordPresent("-editsnap") OR pp.keywordPresent("-esnap") THEN action := Action.EditSnapshot; snapshotName := pp.getNext(); ELSIF pp.keywordPresent("-editrelease") OR pp.keywordPresent("-editrel") OR pp.keywordPresent("-erel") THEN action := Action.EditRelease; snapshotName := pp.getNext(); ELSIF pp.keywordPresent("-showpackagepaths") OR pp.keywordPresent("-showpkgpaths") OR pp.keywordPresent("-spp") THEN action := Action.ShowPackagePaths; ELSIF pp.keywordPresent("-showchangesets") OR pp.keywordPresent("-showcs") OR pp.keywordPresent("-scs") THEN action := Action.ShowChangeSets; sort := Snapshots.Sort.ByName ELSIF pp.keywordPresent("-changesetlog") OR pp.keywordPresent("-cslog") OR pp.keywordPresent("-csl") THEN action := Action.ChangeSetLog; sort := Snapshots.Sort.ByDate; ELSIF pp.keywordPresent("-snapshotlog") OR pp.keywordPresent("-snaplog") OR pp.keywordPresent("-ssl") THEN action := Action.SnapshotLog; sort := Snapshots.Sort.ByDate; IF pp.keywordPresent("-mtime") THEN sortByModificationDate := TRUE END; ELSIF pp.keywordPresent("-releaselog") OR pp.keywordPresent("-rellog") OR pp.keywordPresent("-rl") THEN action := Action.ReleaseLog; sort := Snapshots.Sort.ByDate; IF pp.keywordPresent("-mtime") THEN sortByModificationDate := TRUE END; ELSIF pp.keywordPresent("-import") OR pp.keywordPresent("-imp") THEN action := Action.Import; fileName := pp.getNext(); name := pp.getNext(); ELSIF pp.keywordPresent("-export") OR pp.keywordPresent("-exp") THEN action := Action.Export; name := pp.getNext(); fileName := pp.getNext(); (* shipping *) ELSIF pp.keywordPresent("-localship") OR pp.keywordPresent("-shiplocal") THEN action := Action.ShipLocal; ELSIF pp.keywordPresent("-projectship") OR pp.keywordPresent("-shipproject") THEN action := Action.ShipProject; ELSIF pp.keywordPresent("-globalship") OR pp.keywordPresent("-shipglobal") THEN action := Action.ShipGlobal; (* cleaning *) ELSIF pp.keywordPresent("-clean") THEN action := Action.Clean; ELSIF pp.keywordPresent("-realclean") THEN action := Action.RealClean; ELSIF pp.keywordPresent("-newstatecache") OR pp.keywordPresent("-newcache") THEN action := Action.NewStateCache; ELSIF pp.keywordPresent("-purgeunsureversioninfo") OR pp.keywordPresent("-purgeunsureinfo") OR pp.keywordPresent("-pui") THEN action := Action.PurgeUnsureVersionInfo; ELSIF pp.keywordPresent("-purgebuildinfo") OR pp.keywordPresent("-purgebi") OR pp.keywordPresent("-pbi") THEN action := Action.PurgeBuildInfo; (* predicates *) ELSIF pp.keywordPresent("-isrelease") OR pp.keywordPresent("-isrel") OR pp.keywordPresent("-rel") THEN action := Action.IsRelease; ELSIF pp.keywordPresent("-ismodified") OR pp.keywordPresent("-ismod") OR pp.keywordPresent("-mod") THEN action := Action.IsModified; ELSIF pp.keywordPresent("-isoutofdate") OR pp.keywordPresent("-isood") OR pp.keywordPresent("-ood") THEN action := Action.IsOutOfDate; ELSIF pp.keywordPresent("-hasconflicts") OR pp.keywordPresent("-hascfl") OR pp.keywordPresent("-cfl") THEN action := Action.HasConflicts; (* version and configuration control *) ELSIF pp.keywordPresent("-diff") THEN action := Action.Diff; ELSIF pp.keywordPresent("-cdiff") THEN action := Action.CDiff; ELSIF pp.keywordPresent("-udiff") THEN action := Action.UDiff; ELSIF pp.keywordPresent("-editchangeset") OR pp.keywordPresent("-editcs") OR pp.keywordPresent("-ecs") THEN action := Action.EditChangeSet; ELSIF pp.keywordPresent("-mergechangeset") OR pp.keywordPresent("-mergecs") OR pp.keywordPresent("-mcs") THEN action := Action.MergeChangeSet; ELSIF pp.keywordPresent("-showmodified") OR pp.keywordPresent("-showmod") OR pp.keywordPresent("-smod") THEN action := Action.ShowModified; ELSIF pp.keywordPresent("-showoutofdate") OR pp.keywordPresent("-showood") OR pp.keywordPresent("-sood") THEN action := Action.ShowOutOfDate; ELSIF pp.keywordPresent("-showconflicts") OR pp.keywordPresent("-showcfl") OR pp.keywordPresent("-scfl") THEN action := Action.ShowConflicts; ELSIF pp.keywordPresent("-checkout") OR pp.keywordPresent("-co") OR pp.keywordPresent("-get") OR pp.keywordPresent("-up") OR pp.keywordPresent("-upd") OR pp.keywordPresent("-update") THEN action := Action.Checkout; snapshotName := pp.getNext(); ELSIF pp.keywordPresent("-commit") OR pp.keywordPresent("-ci") THEN action := Action.CommitDevel; CheckCommitType(); ELSIF pp.keywordPresent("-commitrelease") OR pp.keywordPresent("-commitrel") OR pp.keywordPresent("-cirel") THEN action := Action.CommitRelease; CheckCommitType(); ELSIF pp.keywordPresent("-commitlocal") OR pp.keywordPresent("-ciloc") OR pp.keywordPresent("-cil") THEN action := Action.CommitLocalFiles; CheckCommitType(); ELSIF pp.keywordPresent("-makesnapshot") OR pp.keywordPresent("-snapshot") OR pp.keywordPresent("-snap") THEN action := Action.NewSnapshot; snapshotName := pp.getNext(); ELSIF pp.keywordPresent("-makerelease") OR pp.keywordPresent("-release") OR pp.keywordPresent("-makerel") THEN action := Action.MakeRelease; snapshotName := pp.getNext(); ELSIF pp.keywordPresent("-makestablerelease") OR pp.keywordPresent("-stablerelease") OR pp.keywordPresent("-makestable") THEN action := Action.StableRelease; snapshotName := pp.getNext(); TRY IF pp.next < NUMBER(pp.arg^) AND NOT pp.parsed[pp.next] THEN newName := pp.getNext(); END; EXCEPT ParseParams.Error => newName := NIL; END; ELSIF pp.keywordPresent("-newrelease") OR pp.keywordPresent("-newrel") THEN action := Action.NewRelease; IF pp.testNext("major") THEN commitType := CommitType.Major; ELSIF pp.testNext("minor") THEN commitType := CommitType.Minor; ELSIF pp.testNext("patch") THEN commitType := CommitType.Patch; ELSE Msg.Fatal("please specify an explicit commit type"); END; snapshotName := pp.getNext(); ELSIF pp.keywordPresent("-orderedapply") OR pp.keywordPresent("-ordapply") OR pp.keywordPresent("-oapp") THEN action := Action.OrderedApply; cmdList := pp.getNext(); ELSIF pp.keywordPresent("-apply") OR pp.keywordPresent("-app") THEN action := Action.Apply; cmdList := pp.getNext(); ELSIF pp.keywordPresent("-applyaction") OR pp.keywordPresent("-action") THEN action := Action.ApplyAction; cmdList := pp.getNext(); ELSIF pp.keywordPresent("-orderedapplyaction") OR pp.keywordPresent("-ordaction") THEN action := Action.OrderedApplyAction; cmdList := pp.getNext(); ELSIF pp.keywordPresent("-orderedselectby") OR pp.keywordPresent("-ordselectby") OR pp.keywordPresent("-osel") THEN action := Action.OrderedSelectBy; cmdList := pp.getNext(); ELSIF pp.keywordPresent("-selectby") OR pp.keywordPresent("-sel") THEN action := Action.SelectBy; cmdList := pp.getNext(); ELSIF pp.keywordPresent("-showstatecache") OR pp.keywordPresent("-showcache") OR pp.keywordPresent("-sc") THEN action := Action.ShowStateCache; ELSIF pp.keywordPresent("-showshortstatus") OR pp.keywordPresent("-shortstatus") OR pp.keywordPresent("-shortstat") OR pp.keywordPresent("-sstat") THEN action := Action.ShowShortStatus; ELSIF pp.keywordPresent("-showlongstatus") OR pp.keywordPresent("-longstatus") OR pp.keywordPresent("-longstat") OR pp.keywordPresent("-lstat") THEN action := Action.ShowLongStatus; ELSE VAR m := "unknown command"; BEGIN TRY m := m & ": " & pp.getNext() EXCEPT ELSE END; m := m & "\n\nFor a short usage help, type `prjm -help'.\n" & "Use `prjm -man' to read the inline manual.\n"; pp.error(m); END; END; (* sorting order overrides, must be evaluated last *) IF pp.keywordPresent("-nosort") THEN sort := Snapshots.Sort.None; ELSIF pp.keywordPresent("-byname") THEN sort := Snapshots.Sort.ByName; ELSIF pp.keywordPresent("-bydate") THEN sort := Snapshots.Sort.ByDate; END; IF pp.keywordPresent("-reverse") OR pp.keywordPresent("-down") THEN sortUp := FALSE; END; (* add more options before this line *) pp.skipParsed(); nTargets := NUMBER(pp.arg^) - pp.next; targets := NEW(TextSeq.T).init(nTargets); FOR i := 1 TO nTargets DO VAR t := pp.getNext(); BEGIN IF Text.GetChar(t, 0) = '-' THEN Msg.Fatal("unrecognized option: " & t, 2); ELSE targets.addhi(t); END; END; END; pp.finish(); EXCEPT ParseParams.Error => Msg.Fatal("parameter error", 3); END; IF NOT FSUtils.IsFile(inCheckpFileName) THEN inCheckpFileName := NIL; END; END EvalArguments;
PROCEDURE---------------------------------------------------------------------------CreateDependencyGraph () = VAR done := FALSE; BEGIN Msg.V("setting up package dependency graph..."); IF nodep THEN TRY Msg.V(" reading package dependency graph from file..."); prjdesc.readDepGraphAsText(prjDepGraphFile); done := TRUE; EXCEPT PrjDesc.Error => Msg.Error("cannot read dependency graph from file " & prjDepGraphFile & ", must rebuild it..."); END; END; IF NOT done THEN Msg.V("building package dependency graph..."); TRY prjdesc.buildDepGraph(PkgVC.confirmation); prjdesc.writeDepGraphAsText(prjDepGraphFile); (* test and debug code prjdesc.writeDepGraphAsText("depgraph.txt"); VAR prjd2 := NEW(PrjDesc.T).init(prjFileName, cfg, FALSE; preferredPkgKind := packageKind); BEGIN TRY prjd2.readDepGraphAsText("depgraph.txt"); Msg.Debug("depgraph read successfully"); prjd2.writeDepGraphAsText("depgraph2.txt"); EXCEPT ELSE Msg.Debug("reading depgraph failed"); END; END; *) EXCEPT PrjDesc.Error(e) => Msg.Fatal(e, 5); END; END; END CreateDependencyGraph;
PROCEDURE---------------------------------------------------------------------------ListAllPackageKinds () = VAR pkgs := prjdesc.packages(); poolset := prjdesc.getPoolSet(); BEGIN Msg.T("The packages in your project are of the following kind:"); FOR i := 0 TO pkgs.size() - 1 DO WITH pkg = pkgs.get(i) DO WITH loc = poolset.pkgType(pkg) DO M(Fmt.F(" %-24s is a %-s package", pkg, loc)); END; END; END; Msg.T(""); END ListAllPackageKinds;
PROCEDURE---------------------------------------------------------------------------ListAllPackagesAndLocations () = VAR pkgs := prjdesc.packages(); poolset := prjdesc.getPoolSet(); BEGIN Msg.T("The following packages are contained in your project:"); FOR i := 0 TO pkgs.size() - 1 DO WITH pkg = pkgs.get(i) DO WITH loc = poolset.pkgPath(pkg) DO M(Fmt.F(" %-24s at %-s", pkg, loc)); END; END; END; Msg.T(""); END ListAllPackagesAndLocations;
PROCEDURE---------------------------------------------------------------------------ListAllSrcDirectories () = (* Ausgabe der lesbaren Source-Directories aller beteiligten Packages (z.B. geeignet als dir-arg fuer m3gdb). Loesung z.Z. nur provisorisch, da nicht fuer die entsprechenden PackageKind erfolgten SourceDeklarationen aus pkgconf.dat beruecksichtigt werden. *) VAR pkgs := prjdesc.packages(); poolset := prjdesc.getPoolSet(); BEGIN FOR i := 0 TO pkgs.size() - 1 DO WITH pkg = pkgs.get(i) DO WITH loc = poolset.pkgPath(pkg) DO M(Pathname.Join(loc, "src", NIL)); END; END; END; Msg.T(""); END ListAllSrcDirectories;
PROCEDURE---------------------------------------------------------------------------ShowUpdateSequence () = VAR pkgs := prjdesc.packageUpdateSequence(); BEGIN Msg.T("The packages are always updated in the following order:"); FOR i := 0 TO pkgs.size() - 1 DO WITH pkg = pkgs.get(i) DO M(Fmt.F(" %-s", pkg)); END; END; Msg.T(""); END ShowUpdateSequence;
PROCEDURE---------------------------------------------------------------------------CheckImports () = VAR memo := Msg.vFlag; BEGIN Msg.vFlag := TRUE; ListAllPackagesAndLocations(); ListAllPackageKinds(); VOutTextSeq("The following packages are imported but ignored:", prjdesc.ignoredPackages()); Msg.vFlag := memo; END CheckImports;
PROCEDURE---------------------------------------------------------------------------CheckStateLabel () = (*-------------------------------------------------------------------------*) PROCEDURE DisplayResults(m : TEXT; res : TextSeq.T) = BEGIN IF res.size() = 0 THEN M("no " & m & " found matching pattern " & stateLabelPattern); ELSE OutTextSeq(m & " found matching pattern " & stateLabelPattern & ":", res); END; END DisplayResults; VAR res : TextSeq.T; BEGIN IF stateLabelPattern = NIL THEN RETURN END; TRY IF nTargets = 0 THEN res := prjdesc.checkCurrentLabels(stateLabelPattern, lazy); DisplayResults("current state labels", res); ELSE prjdesc.cacheAllStateLabels(lazy); FOR i := 0 TO nTargets - 1 DO WITH name = targets.get(i) DO IF Text.Equal(name, "current") THEN res := prjdesc.checkCurrentLabelsGen(stateLabelPattern, TRUE); DisplayResults("current state labels", res); ELSIF TextUtils.MemberOfTextSeq(prjdesc.snapshots(), name) THEN Msg.V(" checking snapshot " & name); res := prjdesc.checkLabelsOfSnapshot(name, stateLabelPattern, TRUE); DisplayResults("state labels of snapshot " & name, res); ELSIF TextUtils.MemberOfTextSeq(prjdesc.releases(), name) THEN Msg.V(" checking release " & name); res := prjdesc.checkLabelsOfRelease(name, stateLabelPattern, TRUE); DisplayResults("state labels of release " & name, res); ELSE Msg.Error(name & " is no snapshot or release"); END; END; END; END; EXCEPT PrjDesc.Error(e) => Msg.Fatal("checking state labels aborted: " & e, 2); END; END CheckStateLabel;
PROCEDURE---------------------------------------------------------------------------GetAndCheckPackages () : TextSeq.T = VAR pkgs, all, notreleased, tmpPkgs : TextSeq.T; selText := ""; BEGIN IF onlyNotReleased THEN TRY notreleased := prjdesc.selectPackages("isrelease", FALSE, FALSE, TRUE); EXCEPT PrjDesc.Error(t) => Msg.Fatal(t); END; END; IF nTargets = 0 THEN IF onlyModified THEN pkgs := modifiedPkgs; IF modifiedAndDeps THEN selText := "modified and dependend"; ELSE selText := "modified"; END; ELSIF onlyOutOfDate THEN pkgs := outOfDatePkgs; IF outOfDateAndDeps THEN selText := "out-of-date and dependend"; ELSE selText := "out-of-date"; END; ELSE pkgs := prjdesc.packages(); selText := ""; END; IF onlyNotReleased THEN tmpPkgs := pkgs; pkgs := NEW(TextSeq.T).init(notreleased.size()); FOR i := 0 TO notreleased.size() - 1 DO WITH pkg = notreleased.get(i) DO IF MemberOfTextSeq(tmpPkgs, pkg) THEN pkgs.addhi(pkg); END; END; END; IF Text.Empty(selText) THEN selText := "unreleased"; ELSE selText := "unreleased and " & selText; END; END; IF selText = NIL THEN selText := "all"; END; VOutTextSeq("using " & selText & " packages:", pkgs); ELSE pkgs := NEW(TextSeq.T).init(targets.size()); IF onlyModified THEN all := modifiedPkgs; ELSIF onlyOutOfDate THEN all := outOfDatePkgs; ELSE all := prjdesc.packages(); END; FOR i := 0 TO targets.size() - 1 DO WITH pkg = targets.get(i) DO IF MemberOfTextSeq(all, pkg) THEN IF onlyNotReleased THEN IF MemberOfTextSeq(notreleased, pkg) THEN pkgs.addhi(pkg); END; ELSE pkgs.addhi(pkg); END; ELSE Msg.Error("package " & pkg & " is not contained in the project"); END; END; END; IF dependendPkgs THEN pkgs := prjdesc.addDependingPackages(pkgs); END; TOutTextSeq("considering only the following packages:", pkgs); END; RETURN pkgs; END GetAndCheckPackages;
PROCEDURE---------------------------------------------------------------------------ApplySymbolicAction (action : TEXT; inOrder := FALSE) : INTEGER = VAR res : INTEGER; pkgs : TextSeq.T; BEGIN pkgs := GetAndCheckPackages(); IF noAction THEN TOutTextSeq("The action `" & action & "' would be applied to the following packages:", pkgs); RETURN 0; END; TRY res := prjdesc.applyToPackages(action, NIL, NIL, pkgs, ordered := inOrder, breakOnZeroReturn := FALSE, breakOnError := stopOnErrors, breakOnFailure := stopOnFailures, tag1Values := tag1vals, tag2Values := tag2vals); EXCEPT PrjDesc.Error(e) => Msg.Fatal("application terminated with exception: " & e, 1000); END; RETURN res; END ApplySymbolicAction;
PROCEDURE---------------------------------------------------------------------------CommitPackages (action : Action; commitType : CommitType;) : INTEGER = VAR commitaction : TEXT; committype : TEXT; res : INTEGER := 0; pkgs : TextSeq.T; pre : TextTextTbl.T; post : TextTextTbl.T; log : TEXT := commitMsg; lb := OSSpecials.LineBreak; checkLogMsg := FALSE; checkaction := "project-change-set"; PROCEDURE GetAndCheckLogMsg() = BEGIN checkLogMsg := CommitHookDefined("external-project-change-set-hook"); IF log = NIL THEN (* get change set description *) log := lb & lb & "PKG: Please enter a log message for change set " & changeSetName &"." & lb & "PKG: It should focus on the meaning of all the changes " & lb & "PKG: in a project or application context." & lb & "PKG: Try to be as exact and informative as you can." & lb & "PKG: All lines beginning with PKG: will be erased." & lb; WITH editor = CompactRC.GetValue(env, "editor") DO log := PkgVCUtils.GetMessage(editor, NIL, msg := log); END; END; IF log = NIL THEN IF checkLogMsg THEN Msg.Fatal("You haven't specified a log message for this " & "change set.\n"); ELSE Msg.Warning("You haven't specified a log message for this " & "change set.\n"); Msg.Warning("You may do this later by manually editing the " & "change set file\n"); Msg.Warning("with \"prjm -editchangeset " & changeSetName & "\"."); END; END; IF log # NIL THEN IF checkLogMsg THEN TRY PkgVCUtils.CheckCommitMsg(log, NIL, prjName, prjRoot, user, NIL, checkaction, changeSetName, env); EXCEPT PkgVCUtils.E(e) => Msg.Fatal("log message not accepted: " & e); END; END; changeSet.setDescription(log); END; END GetAndCheckLogMsg; BEGIN CASE commitType OF CommitType.Major => committype := "major"; | CommitType.Minor => committype := "minor"; | CommitType.Patch => committype := "patch"; END; IF action = Action.CommitDevel THEN commitaction := "commitdevel"; Msg.V("committing development code..."); ELSIF action = Action.CommitRelease THEN commitaction := "commitrelease"; Msg.V("committing release code..."); ELSE Msg.Fatal("internal error: unexpected commit action", 1001); END; pkgs := GetAndCheckPackages(); IF noAction THEN TOutTextSeq("The action `" & commitaction & "' would be applied to the following packages:", pkgs); RETURN 0; END; TRY IF action = Action.CommitRelease THEN EverythingBuiltOkay(); END; IF changeSetName # NIL THEN IF snaps.changeSetDefined(changeSetName) THEN Msg.Error("A change set named " & changeSetName & " already exists."); RETURN 900; END; pre := prjdesc.getTags(pkgs); changeSet := NEW(ChangeSet.T).init(changeSetName); changeSet.setUser(user); changeSet.setDate(Time.Now()); GetAndCheckLogMsg(); END; IF NOT noAction THEN res := prjdesc.applyToPackages(commitaction & committype, NIL, NIL, pkgs, ordered := FALSE, breakOnZeroReturn := FALSE, breakOnError := stopOnErrors, breakOnFailure := stopOnFailures); END; IF res = 0 THEN IF changeSetName # NIL THEN post := prjdesc.getTags(pkgs); changeSet.setDate(Time.Now()); VAR pkg, tag1, tag2 : TEXT; iter := pre.iterate(); BEGIN WHILE iter.next(pkg, tag1) DO IF NOT post.get(pkg, tag2) THEN RAISE ChangeSet.Error ("missing package in post-change-status: " & pkg); END; changeSet.add(pkg, tag1, tag2); END; END; snaps.putChangeSet(changeSetName, changeSet); IF useVC AND NOT noAction THEN IF commitMsg = NIL AND log # NIL THEN log := "new change set " & changeSetName &":" & lb & lb & log & lb & lb & "PKG: Please enter a local commit message for change set " & lb & "PKG: " & changeSetName &"." & lb & "PKG: If you have made no other changes than the creation " & "of this change set," & lb & "PKG: the above message will probably be appropriate. " & lb; WITH editor = CompactRC.GetValue(env, "editor") DO log := PkgVCUtils.GetMessage(editor, NIL, msg := log, failIfUnchanged := FALSE); END; IF log # NIL THEN commitMsg := log; END; ELSIF commitMsg # NIL AND NOT TextUtils.Contains(commitMsg, changeSetName) THEN commitMsg := "new change set " & changeSetName &":" & lb & lb & commitMsg & lb; END; CommitLocalFiles(PkgVC.CommitType.Minor); END; END; END; EXCEPT ChangeSet.Error(e) => res := 900; Msg.Error(e); | Snapshots.Error(e) => res := 900; Msg.Error(e); | PrjDesc.Error(e) => res := 1000; Msg.Error("committing terminated with exception: " & e); (* FIXME: save partial changeset description to temporary file *) END; RETURN res; END CommitPackages;
PROCEDURE---------------------------------------------------------------------------ExecEditChangeSet () = VAR old, new : TEXT; BEGIN IF changeSetName = NIL OR changeSet = NIL THEN Msg.Fatal("no valid change set specified"); END; IF NOT snaps.changeSetDefined(changeSetName) THEN Msg.Fatal("A change set named " & changeSetName & " does not exist."); END; old := changeSet.toText(); WITH editor = CompactRC.GetValue(env, "editor") DO new := PkgVCUtils.GetMessage(editor, NIL, msg := old); END; IF new # NIL THEN Msg.V("saving altered change set description"); WITH cs = NEW(ChangeSet.T).init(changeSet.getName()) DO TRY cs.parse(TextRd.New(new), "<in-memory copy>"); snaps.putChangeSet(changeSetName, cs, ovwr := TRUE); EXCEPT ChangeSet.Error(e) => Msg.Fatal("cannot parse change set description: " & e); | Snapshots.Error(e) => Msg.Fatal("cannot overwrite change set description: " & e); END; END; ELSE Msg.V("change set unchanged"); END; END ExecEditChangeSet;
PROCEDURE---------------------------------------------------------------------------ExecPredicate () = VAR mod : TextSeq.T; BEGIN IF action = Action.IsRelease THEN IF prjdesc.testAllPackagesReleased() THEN Msg.T("All packages are checked out as released versions."); WriteCheckpoint(); Process.Exit(0); ELSE Msg.T("At least one package is no released version."); WriteCheckpoint(); Process.Exit(1); END; ELSIF action = Action.IsModified THEN TRY mod := prjdesc.modifiedPackages(); EXCEPT PrjDesc.Error(e) => Msg.Fatal("test failed with exception: " & e & ", some packages may be modified", 1000); END; IF mod.size() > 0 THEN TOutTextSeq("There are locally modified packages:", mod); WriteCheckpoint(); Process.Exit(0); ELSE Msg.T("No packages are locally modified."); WriteCheckpoint(); Process.Exit(1); END; ELSIF action = Action.IsOutOfDate THEN PurgeUnsureVersionInfoIfNotLazy(); TRY mod := prjdesc.outOfDatePackages(); EXCEPT PrjDesc.Error(e) => Msg.Fatal("test failed with exception: " & e & ", some packages may be out-of-date", 1000); END; IF mod.size() > 0 THEN TOutTextSeq("There are out-of-date packages:", mod); WriteCheckpoint(); Process.Exit(0); ELSE Msg.T("All packages are up-to-date."); WriteCheckpoint(); Process.Exit(1); END; ELSIF action = Action.HasConflicts THEN PurgeUnsureVersionInfoIfNotLazy(); TRY mod := prjdesc.packagesWithConflicts(); EXCEPT PrjDesc.Error(e) => Msg.Fatal("test failed with exception: " & e & ", some packages may have conflicts", 1000); END; IF mod.size() > 0 THEN TOutTextSeq("There are packages with conflicts:", mod); WriteCheckpoint(); Process.Exit(0); ELSE Msg.T("No packages have conflicts."); WriteCheckpoint(); Process.Exit(1); END; ELSE Msg.Fatal("internal error: unexpected predicate action", 1001); END; END ExecPredicate;
PROCEDURE---------------------------------------------------------------------------ExecBuildAction () = VAR buildaction, shipaction : TEXT; res : INTEGER; pkgs : TextSeq.T; BEGIN IF action = Action.BuildGlobal THEN buildaction := "build"; shipaction := "shipglobal"; Msg.V("building for global pool..."); ELSIF action = Action.BuildProject THEN buildaction := "build"; shipaction := "shipproject"; Msg.V("building for project pool..."); ELSIF action = Action.BuildLocal THEN buildaction := "buildlocal"; shipaction := "shiplocal"; Msg.V("building for local pool..."); ELSE Msg.Fatal("internal error: unexpected build action", 1001); END; pkgs := GetAndCheckPackages(); IF noAction THEN TOutTextSeq("The actions `" & buildaction & "' and `" & shipaction & "' would be applied to the following packages in correct order:", pkgs); WriteCheckpoint(); Process.Exit(0); END; IF onlyOutOfDate THEN (* need to get the newest versions first *) TRY prjdesc.checkoutTrunkOrBranchHead(pkgs); EXCEPT PrjDesc.Error(e) => Msg.Fatal("update terminated with exception: " & e, 1000); END; END; TRY res := prjdesc.applyToPackages(buildaction, shipaction, NIL, pkgs, ordered := TRUE, breakOnZeroReturn := FALSE, breakOnError := stopOnErrors, breakOnFailure := stopOnFailures); EXCEPT PrjDesc.Error(e) => WriteCheckpoint(); Msg.Fatal("building terminated with exception: " & e, 1000); END; WriteCheckpoint(); IF res = 0 THEN Msg.V("building terminated successfully"); Process.Exit(0); ELSE Msg.Fatal("building terminated with result code " & Fmt.Int(res), 1000); END; END ExecBuildAction;
PROCEDURE---------------------------------------------------------------------------ExecCleanAction () = VAR cleanaction : TEXT; res : INTEGER; pkgs : TextSeq.T; BEGIN IF action = Action.Clean THEN cleanaction := "clean"; Msg.V("cleaning..."); ELSIF action = Action.RealClean THEN cleanaction := "realclean"; Msg.V("cleaning thoroughly..."); ELSE Msg.Fatal("internal error: unexpected cleaning action", 1001); END; pkgs := GetAndCheckPackages(); IF noAction THEN TOutTextSeq("the action `" & cleanaction & "' would be applied to the following packages:", pkgs); WriteCheckpoint(); Process.Exit(0); END; TRY res := prjdesc.applyToPackages(cleanaction, NIL, NIL, pkgs, ordered := FALSE, breakOnZeroReturn := FALSE, breakOnError := stopOnErrors, breakOnFailure := stopOnFailures); EXCEPT PrjDesc.Error(e) => Msg.Fatal("cleaning terminated with exception: " & e, 1000); END; WriteCheckpoint(); IF res = 0 THEN Msg.V("cleaning terminated successfully"); Process.Exit(0); ELSE Msg.Fatal("cleaning terminated with result code " & Fmt.Int(res), 1000); END; END ExecCleanAction;
PROCEDURE---------------------------------------------------------------------------ExecShipAction () = VAR shipaction : TEXT; res : INTEGER; pkgs : TextSeq.T; BEGIN IF action = Action.ShipGlobal THEN shipaction := "shipglobal"; Msg.V("shipping to global pool..."); ELSIF action = Action.ShipProject THEN shipaction := "shipproject"; Msg.V("shipping to project pool..."); ELSIF action = Action.ShipLocal THEN shipaction := "shiplocal"; Msg.V("shipping to local pool..."); ELSE Msg.Fatal("internal error: unexpected ship action", 1001); END; pkgs := GetAndCheckPackages(); IF noAction THEN TOutTextSeq("The action `" & shipaction & "' would be applied to the following packages in correct order:", pkgs); WriteCheckpoint(); Process.Exit(0); END; TRY res := prjdesc.applyToPackages(shipaction, NIL, NIL, pkgs, ordered := TRUE, breakOnZeroReturn := FALSE, breakOnError := stopOnErrors, breakOnFailure := stopOnFailures); EXCEPT PrjDesc.Error(e) => Msg.Fatal("shipping terminated with exception: " & e, 1000); END; WriteCheckpoint(); IF res = 0 THEN Msg.V("shipping terminated successfully"); Process.Exit(0); ELSE Msg.Fatal("shipping terminated with result code " & Fmt.Int(res), 1000); END; END ExecShipAction;
PROCEDURE---------------------------------------------------------------------------ExecDiffAction () = VAR cmd := "diff"; diffPrefix := ""; res : INTEGER; pkgs : TextSeq.T; pkgs2 : TextSeq.T; curpkgs : TextSeq.T; tag1pkgs : TextSeq.T := NIL; tag2pkgs : TextSeq.T := NIL; nMissing := 0; BEGIN IF action = Action.CDiff THEN diffPrefix := "c"; ELSIF action = Action.UDiff THEN diffPrefix := "u"; END; IF changeSet = NIL THEN pkgs := GetAndCheckPackages(); ELSE pkgs := changeSet.packages(); tag1vals := changeSet.preState(); tag2vals := changeSet.postState(); cmd := "diff2"; END; pkgs2 := NEW(TextSeq.T).init(); curpkgs := prjdesc.packages(); IF tag1prjdesc # NIL THEN tag1pkgs := tag1prjdesc.packages(); cmd := "diff1"; END; IF tag2prjdesc # NIL THEN tag2pkgs := tag2prjdesc.packages(); cmd := "diff2"; END; FOR i:= 0 TO pkgs.size() - 1 DO WITH pkg = pkgs.get(i) DO IF tag1pkgs # NIL AND NOT MemberOfTextSeq(tag1pkgs, pkg) THEN M("package " & pkg & " is not contained in snapshot " & tag1); INC(nMissing); ELSIF tag2pkgs # NIL AND NOT MemberOfTextSeq(tag2pkgs, pkg) THEN M("package " & pkg & " is not contained in snapshot " & tag2); INC(nMissing); ELSE pkgs2.addhi(pkg); END; END; END; IF tag1pkgs # NIL THEN FOR i:= 0 TO tag1pkgs.size() - 1 DO WITH pkg = tag1pkgs.get(i) DO IF NOT MemberOfTextSeq(curpkgs, pkg) THEN M("package " & pkg & " is not contained in snapshot " & tag1); INC(nMissing); END; END; END; END; IF tag2pkgs # NIL THEN FOR i:= 0 TO tag2pkgs.size() - 1 DO WITH pkg = tag2pkgs.get(i) DO IF NOT MemberOfTextSeq(curpkgs, pkg) THEN M("package " & pkg & " is not contained in snapshot " & tag1); INC(nMissing); END; END; END; END; IF nMissing > 0 THEN M("Up to " & Fmt.Int(nMissing) & " difference listings will be missing."); END; IF noAction THEN TOutTextSeq("The action `" & diffPrefix & cmd & "' would be applied to the following packages:", pkgs); Process.Exit(0); END; TRY prjdesc.defineGlobalVar("diffPrefix", diffPrefix); res := prjdesc.applyToPackages(cmd, NIL, NIL, pkgs2, ordered := FALSE, breakOnZeroReturn := FALSE, breakOnError := stopOnErrors, breakOnFailure := stopOnFailures, tag1Values := tag1vals, tag2Values := tag2vals); EXCEPT PrjDesc.Error(e) => Msg.Fatal("diffing terminated with exception: " & e, 1000); END; IF res = 0 THEN Msg.V("diffing terminated successfully"); Process.Exit(0); ELSE Msg.Fatal("diffing terminated with result code " & Fmt.Int(res), 1000); END; END ExecDiffAction;
PROCEDURE---------------------------------------------------------------------------ExecMergeChangeSet () = VAR cmd := "merge2"; res : INTEGER; pkgs : TextSeq.T; BEGIN IF changeSet = NIL THEN Msg.Fatal("no change set", 1000); END; pkgs := changeSet.packages(); tag1vals := changeSet.preState(); tag2vals := changeSet.postState(); IF noAction THEN TOutTextSeq("The action `" & cmd & "' with tags from change set " & changeSetName & "\nwould be applied to the following packages:", pkgs); Process.Exit(0); END; TRY res := prjdesc.applyToPackages(cmd, NIL, NIL, pkgs, ordered := FALSE, breakOnZeroReturn := FALSE, breakOnError := stopOnErrors, breakOnFailure := stopOnFailures, tag1Values := tag1vals, tag2Values := tag2vals); EXCEPT PrjDesc.Error(e) => Msg.Fatal("merging terminated with exception: " & e, 1000); END; WriteCheckpoint(); IF res = 0 THEN Msg.V("application of change set " & changeSetName & " was successful"); Process.Exit(0); ELSE Msg.Fatal("application of change set " & changeSetName & " terminated with result code " & Fmt.Int(res), 1000); END; END ExecMergeChangeSet;
PROCEDURE---------------------------------------------------------------------------ExecPackageCommitAction () = VAR res := CommitPackages(action, commitType); BEGIN WriteCheckpoint(); IF res = 0 THEN Msg.V("committing terminated successfully"); Process.Exit(0); ELSE Msg.Fatal("committing terminated with result code " & Fmt.Int(res), 1000); END; END ExecPackageCommitAction;
PROCEDURE---------------------------------------------------------------------------ExecCommitLocalFiles () = BEGIN CommitLocalFiles(commitType); END ExecCommitLocalFiles;
PROCEDURE---------------------------------------------------------------------------CommitLocalFiles (commitType : PkgVC.CommitType) = VAR file : APN.T := NIL; BEGIN TRY IF noAction THEN Msg.V("all local files would be committed now..."); RETURN; END; IF NOT Text.Equal(actPrjFileName, ActStateFN) THEN WITH f = APN.New(actPrjFileName) DO IF NOT PkgVC.VC.known(f) THEN IF NOT PkgVC.VC.add(f) THEN Msg.Fatal("cannot put " & f.denotation() & " under version control", 1000); END; END; END; END; snaps.everythingUnderVersionControl(); IF commitFile # NIL THEN file := APN.New(commitFile); END; PkgVC.VC.commitChanges(commitType, commitMsg, file); EXCEPT PkgVC.E(t) => Msg.Fatal(t); | Snapshots.Error(t) => Msg.Fatal(t); END; END CommitLocalFiles;
PROCEDURE---------------------------------------------------------------------------PackageImportDefs (snap : TextTextTbl.T; pkg : TEXT; relevanceLevel := 2) : TextTextTbl.T = VAR imports : TextSeq.T; tag : Tag.T; ver : Version.T; res : TextTextTbl.T; imp, rev : TEXT; BEGIN imports := prjdesc.packageDependencies(pkg); res := NEW(TextTextTbl.Default).init(); FOR i := 0 TO imports.size() - 1 DO imp := imports.get(i); IF snap.get(imp, rev) THEN tag := Tag.New(rev); ver := tag.version(); IF relevanceLevel < 3 THEN ver.patchlevel := Version.Undefined; END; IF relevanceLevel < 2 THEN ver.minor := Version.Undefined; END; IF relevanceLevel < 1 THEN ver.major := Version.Undefined; END; EVAL res.put(imp, ver.toText()); ELSE Msg.V(imp & " not in snapshot/project, dependency omitted in imports"); END; END; RETURN res; END PackageImportDefs;
PROCEDURE---------------------------------------------------------------------------PkgOvrFile (impdefs : TextTextTbl.T) : TEXT = VAR pkg, ver : TEXT; iter := impdefs.iterate(); res := ""; BEGIN WHILE iter.next(pkg, ver) DO res := res & "import(\"" & pkg & "\", " & ver & ")\n"; END; RETURN res; END PkgOvrFile;
PROCEDURE---------------------------------------------------------------------------WritePkgOvrFile (pn : Pathname.T; data : TEXT; rev : TEXT) = VAR wr : FileWr.T; BEGIN Msg.T("new package imports in " & pn); IF noAction THEN RETURN END; TRY wr := FileWr.Open(pn); Wr.PutText(wr, "# This file was generated by the ComPact Project " & "Manager.\n"); Wr.PutText(wr, "# Date: " & FmtTime.Long(Time.Now()) & "\n"); Wr.PutText(wr, "# Base revision: " & rev & "\n"); Wr.PutText(wr, data); Wr.Close(wr); EXCEPT ELSE Msg.Error("cannot write file " & pn); END; END WritePkgOvrFile;
PROCEDURE---------------------------------------------------------------------------CreatePkgOvrFiles (snap : TextTextTbl.T; pkgs : TextSeq.T := NIL) = VAR iter := snap.iterate(); pkgset := prjdesc.getPoolSet(); pkg, rev : TEXT; loc, pkgOvr : TEXT; impdefs : TextTextTbl.T; BEGIN Msg.V("saving new import information in package roots..."); WHILE iter.next(pkg, rev) DO IF pkgs = NIL OR TextUtils.MemberOfTextSeq(pkgs, pkg) THEN loc := pkgset.pkgPath(pkg); pkgOvr := Pathname.Join(loc, PkgOvrFN, NIL); impdefs := PackageImportDefs(snap, pkg, importRelevanceLevel); WritePkgOvrFile(pkgOvr, PkgOvrFile(impdefs), rev); END; END; END CreatePkgOvrFiles;
PROCEDURE---------------------------------------------------------------------------ExecCreatePkgOvrFiles () = VAR pkgs : TextSeq.T; prjd : PrjDesc.T; snap : TextTextTbl.T; type : TEXT; BEGIN TRY prjd := snaps.getSnapshot(snapshotName); snap := prjd.snapshot(snapshotName); type := "snapshot "; EXCEPT Snapshots.Error => TRY prjd := snaps.getRelease(snapshotName); snap := prjd.release(snapshotName); type := "release "; EXCEPT Snapshots.Error => snap := NIL; END; END; IF snap = NIL THEN Msg.Fatal("no snapshot or release " & snapshotName, 1001); END; pkgs := GetAndCheckPackages(); CreatePkgOvrFiles(snap, pkgs); END ExecCreatePkgOvrFiles;
PROCEDURE---------------------------------------------------------------------------EverythingBuiltOkay () = VAR pkgs := GetAndCheckPackages(); res : INTEGER; BEGIN Msg.V("checking if everything has been successfully built"); TRY res := prjdesc.applyToPackages("builtok", NIL, NIL, pkgs, ordered := TRUE, breakOnZeroReturn := FALSE, breakOnError := TRUE, breakOnFailure := TRUE); IF res = 0 THEN Msg.V("everything seems to have been built okay"); ELSE Msg.Fatal("build check exited with " & Fmt.Int(res), 1); END; EXCEPT PrjDesc.Error(e) => Msg.Fatal("build check failed: " & e, 1); END; END EverythingBuiltOkay;
PROCEDURE---------------------------------------------------------------------------ExecFreezeAction () = VAR snap : TextTextTbl.T; msg : TEXT; res : INTEGER; log : TEXT := commitMsg; lb := OSSpecials.LineBreak; checkLogMsg := FALSE; checkaction := "project-release"; PROCEDURE GetAndSetLogMsg() = BEGIN IF log = NIL THEN log := lb & lb & "PKG: Please enter a log message for snapshot/release " & snapshotName &"." & lb & "PKG: It should focus on its content and intended use. " & lb & "PKG: Try to be as exact and informative as you can." & lb & "PKG: All lines beginning with PKG: will be erased." & lb; WITH editor = CompactRC.GetValue(env, "editor") DO log := PkgVCUtils.GetMessage(editor, NIL, msg := log); END; END; IF log = NIL THEN IF checkLogMsg THEN Msg.Fatal("You haven't specified a log message for this " & "snapshot/release set.\n"); ELSE Msg.Warning("You haven't specified a log message for this " & "snapshot/release set.\n"); Msg.Warning("You may do this later by manually editing the " & "snapshot file\n"); Msg.Warning("with \"prjm -editsnapshot " & snapshotName & "\"."); END; END; IF log # NIL THEN IF checkLogMsg THEN TRY PkgVCUtils.CheckCommitMsg(log, NIL, prjName, prjRoot, user, NIL, checkaction, snapshotName, env); EXCEPT PkgVCUtils.E(e) => Msg.Fatal("log message not accepted: " & e); END; END; prjdesc.setDescription(log); END; END GetAndSetLogMsg; BEGIN TRY IF action = Action.NewSnapshot THEN Msg.V("creating new snapshot..."); prjdesc.newSnapshot(snapshotName); checkLogMsg := CommitHookDefined("external-project-snapshot-hook"); checkaction := "project-snapshot"; ELSIF action = Action.MakeRelease THEN Msg.V("creating release snapshot..."); IF NOT force THEN EverythingBuiltOkay(); END; prjdesc.newRelease(snapshotName); checkLogMsg := CommitHookDefined("external-project-release-hook"); ELSIF action = Action.NewRelease THEN Msg.V("creating new release and release snapshot..."); IF NOT force THEN EverythingBuiltOkay(); END; checkLogMsg := CommitHookDefined("external-project-release-hook"); IF NOT forceRelease THEN onlyNotReleased := TRUE; END; res := CommitPackages(Action.CommitRelease, commitType); IF res # 0 THEN Msg.Fatal("committing terminated with result code " & Fmt.Int(res), 1000); END; IF autoovr THEN Msg.V("creating intermediate release snapshot pre_" & snapshotName); prjdesc.newRelease("pre_" & snapshotName); ELSE Msg.V("creating release snapshot " & snapshotName); prjdesc.newRelease(snapshotName); END; ELSE Msg.Fatal("internal error: unexpected freeze action", 1001); END; EXCEPT PrjDesc.Error(e) => Msg.Fatal(e, 8); END; prjdesc.setUser(user); prjdesc.setCreationDate(Time.Now()); prjdesc.setModificationDate(Time.Now()); IF action = Action.NewRelease AND autoovr THEN prjdesc.setDescription("automatically generated by the Elego ComPact " & "project manager"); ELSE GetAndSetLogMsg(); END; TRY IF action = Action.NewSnapshot THEN Msg.V("writing snapshot..."); snaps.putSnapshot(snapshotName, prjdesc); snap := prjdesc.snapshot(snapshotName); msg := "snapshot created of the following packages:"; ELSE IF action = Action.NewRelease AND autoovr THEN IF savePreReleases THEN Msg.V("writing pre-release..."); snaps.putRelease("pre_" & snapshotName, prjdesc); ELSE Msg.V("abandoning pre-release configuration..."); END; snap := prjdesc.release("pre_" & snapshotName); ELSE Msg.V("writing release..."); snaps.putRelease(snapshotName, prjdesc); snap := prjdesc.release(snapshotName); END; msg := "release created of the following packages:"; END; IF action = Action.NewRelease AND autoovr THEN CreatePkgOvrFiles(snap); TRY Msg.V("adding " & PkgOvrFN & " files..."); EVAL prjdesc.applyCmdListDirectly("pkgvm -add " & PkgOvrFN, NIL, ordered := FALSE, breakOnZeroReturn := FALSE, breakOnError := FALSE, breakOnFailure := TRUE); Msg.V("committing " & PkgOvrFN & " to release branches..."); res := prjdesc.applyToPackages("commitrelease" & "patch", NIL, NIL, NIL, (* all packages *) ordered := FALSE, breakOnZeroReturn := FALSE, breakOnError := stopOnErrors, breakOnFailure := stopOnFailures); IF res # 0 THEN Msg.Error("Couldn't commit all " & PkgOvrFN & " files."); Msg.Error("The new release is incomplete, " & snapshotName & " does not yet exist, but pre_" & snapshotName & " does."); Msg.Fatal("Aborting creation of release " & snapshotName); END; EXCEPT PrjDesc.Error(e) => Msg.Error("error during addition of " & PkgOvrFN & " files."); Msg.Fatal(e, 8); END; TRY GetAndSetLogMsg(); Msg.V("creating release snapshot " & snapshotName); prjdesc.newRelease(snapshotName); Msg.V("writing release..."); snaps.putRelease(snapshotName, prjdesc); snap := prjdesc.release(snapshotName); EXCEPT PrjDesc.Error(e) => Msg.Fatal("cannot make release " & snapshotName & ": " & e, 8); END; END; EXCEPT Snapshots.Error(e) => Msg.Fatal("error writing project state: " & e, 3); END; IF snap = NIL THEN Msg.Fatal("snapshot seems not to have been created"); END; TOutTextTable(msg, snap); IF useVC AND NOT noAction THEN VAR lct := PkgVC.CommitType.Minor; ctname : TEXT; BEGIN IF action = Action.NewSnapshot THEN lct := PkgVC.CommitType.Minor; ctname := "snapshot"; ELSE lct := PkgVC.CommitType.Major; ctname := "release"; END; IF commitMsg = NIL AND log # NIL THEN log := "new " & ctname & " " & snapshotName &":" & lb & lb & log & lb & lb & "PKG: Please enter a local commit message for " & ctname & lb & "PKG: " & snapshotName &"." & lb & "PKG: If you have made no other changes than the creation " & "of this " & ctname & "," & lb & "PKG: the above message will probably be appropriate. " & lb; WITH editor = CompactRC.GetValue(env, "editor") DO log := PkgVCUtils.GetMessage(editor, NIL, msg := log, failIfUnchanged := FALSE); END; IF log # NIL THEN commitMsg := log; END; ELSIF commitMsg # NIL AND NOT TextUtils.Contains(commitMsg, snapshotName) THEN commitMsg := "new " & ctname & " " & snapshotName &":" & lb & lb & commitMsg & lb; END; CommitLocalFiles(lct); END; END; WriteCheckpoint(); Process.Exit(0); END ExecFreezeAction;
PROCEDURE---------------------------------------------------------------------------ExecMakeStableRelease () = VAR release : PrjDesc.T; rel, res : TextTextTbl.T; msg : TEXT; log : TEXT := NIL; lb := OSSpecials.LineBreak; BEGIN TRY release := snaps.getRelease(snapshotName); rel := release.release(snapshotName); IF newName = NIL THEN newName := snapshotName & "_stable"; END; IF rel = NIL THEN Msg.Fatal("release " & snapshotName & " not found"); END; res := NEW(TextTextTbl.Default).init(rel.size()); VAR iter := rel.iterate(); pkg, tag: TEXT; stag : Tag.T; BEGIN WHILE iter.next(pkg, tag) DO stag := Tag.New(tag); stag := Tag.NewStableBranch(stag); EVAL res.put(pkg, stag.denotation()); END; END; IF noAction THEN rel := res; msg := "new stable release would be created of the following packages:"; ELSE release.defineRelease(newName, res); snaps.putRelease(newName, release); rel := release.release(newName); msg := "stable release created of the following packages:"; END; EXCEPT PrjDesc.Error(e) => Msg.Fatal(e); | Snapshots.Error(e) => Msg.Fatal(e); END; TOutTextTable(msg, rel); IF useVC THEN IF commitMsg = NIL THEN log := "new stable release configuration " & newName & ":" & lb & lb & "PKG: Please enter a local commit message for " & lb & "PKG: " & newName &"." & lb & "PKG: If you have made no other changes than the creation " & "of this configuration," & lb & "PKG: the above message will probably be appropriate. " & lb; WITH editor = CompactRC.GetValue(env, "editor") DO log := PkgVCUtils.GetMessage(editor, NIL, msg := log, failIfUnchanged := FALSE); END; IF log # NIL THEN commitMsg := log; END; ELSIF NOT TextUtils.Contains(commitMsg, newName) THEN commitMsg := "new stable release configuration " & newName & ":" & lb & commitMsg & lb; END; CommitLocalFiles(PkgVC.CommitType.Major); END; WriteCheckpoint(); Process.Exit(0); END ExecMakeStableRelease;
PROCEDURE---------------------------------------------------------------------------ExecCheckout () = VAR name : TEXT; rev : TEXT; isrel := FALSE; head := FALSE; tab : TextTextTbl.T; msg : TextSeq.T; (*-------------------------------------------------------------------------*) PROCEDURE InvalidateStateCache() = BEGIN TRY prjdesc.reinit(actPrjFileName, cfg, FALSE, collectionroot, inCheckpFileName, TRUE, env, pkgvcAcc := pkgvcCreator); IF packageKind # NIL THEN prjdesc.setPreferredPkgKind(packageKind); END; prjdesc.invalidateCachedUnsureVersionInfo(); CreateDependencyGraph(); prjdesc.writeCheckpoint(outCheckpFileName); EXCEPT PrjDesc.Error(e) => Msg.Fatal("cannot write checkpoint file: " & e); END; END InvalidateStateCache; BEGIN (* ExecCheckout *) name := snapshotName; TRY IF Text.Equal(name, "head") THEN Msg.V("checking out current development versions..."); head := TRUE; PrjDescLoadHead(); ELSIF MemberOfTextSeq(snaps.listReleases(), name) THEN isrel := TRUE; prjdesc := snaps.getRelease(name); prjdesc.defineGlobalVars(env); prjdesc.defineGlobalVars(vars); prjdesc.writeRelease(ActStateFN, name); Msg.V("checking out release " & name & "..."); ELSIF MemberOfTextSeq(snaps.listSnapshots(), name) THEN prjdesc := snaps.getSnapshot(name); prjdesc.defineGlobalVars(env); prjdesc.defineGlobalVars(vars); prjdesc.writeSnapshot(ActStateFN, name); Msg.V("checking out snapshot " & name & "..."); ELSE Msg.Warning("There is no release or snapshot with name " & name); IF force THEN Msg.Warning("Trying to use " & name & " as CVS tag"); ELSE WITH msg = "Would you like to checkout the project with `" & name & "' as CVS tag" DO IF NOT PkgVC.confirmation.okay(msg) THEN Msg.Fatal("checkout aborted by user"); END; END; END; END; EXCEPT PrjDesc.Error(e) => Msg.Fatal(e); | Snapshots.Error(e) => Msg.Fatal(e); END; IF noAction THEN IF nTargets = 0 THEN msg := NEW(TextSeq.T).init(); IF head THEN FOR i := 0 TO prjdesc.packages().size() - 1 DO WITH pkg = prjdesc.packages().get(i) DO msg .addhi("checking out " & pkg & " as head"); END; END; ELSE IF isrel THEN tab := prjdesc.release(name); ELSE tab := prjdesc.snapshot(name); END; WITH iter = tab.iterate() DO WHILE iter.next(name, rev) DO msg.addhi("checking out " & name & " as " & rev); END; END; END; ELSE msg := targets; END; TOutTextSeq("The following packages would be checked out:", msg); (* WriteCheckpoint(); *) Process.Exit(0); END; TRY IF nTargets = 0 THEN IF head THEN prjdesc.checkoutHead(); ELSIF isrel THEN prjdesc.checkoutRelease(name); ELSE prjdesc.checkoutSnapshot(name); END; ELSE prjdesc.checkoutPackages(targets, name); END; IF updateStateCache THEN InvalidateStateCache(); END; EXCEPT PrjDesc.Error(e) => IF useStateCache THEN WriteCheckpoint(); ELSE InvalidateStateCache(); END; Msg.Fatal("error checking out project: "& e, 3); END; (* WriteCheckpoint(); *) Process.Exit(0); END ExecCheckout;
PROCEDURE---------------------------------------------------------------------------ExecApplyAction () = VAR res : INTEGER; heedOrder := action = Action.OrderedApplyAction; BEGIN res := ApplySymbolicAction(cmdList, heedOrder); WriteCheckpoint(); IF res = 0 THEN Msg.V("application terminated successfully"); ELSIF stopOnErrors THEN Msg.Fatal("application terminated with result code " & Fmt.Int(res), 1000); END; Process.Exit(0); END ExecApplyAction;
PROCEDURE---------------------------------------------------------------------------ExecApplyCmdList () = VAR res : INTEGER; pkgs : TextSeq.T; heedOrder := action = Action.OrderedApply; BEGIN pkgs := GetAndCheckPackages(); IF noAction THEN TOutTextSeq("The action `" & cmdList & "' would be applied to the following packages:", pkgs); WriteCheckpoint(); Process.Exit(0); END; WriteCheckpoint(); IF heedOrder THEN Msg.V("applying `" & cmdList & "' to ordered list of packages..."); ELSE Msg.V("applying `" & cmdList & "' to unordered list of packages..."); END; TRY res := prjdesc.applyCmdListDirectly( cmdList, pkgs, ordered := heedOrder, breakOnZeroReturn := FALSE, breakOnError := stopOnErrors, breakOnFailure := stopOnFailures); EXCEPT PrjDesc.Error(e) => Msg.Fatal("application terminated with exception: " & e, 1000); END; IF res = 0 THEN Msg.V("application terminated successfully"); Process.Exit(0); ELSE IF stopOnErrors THEN Msg.Fatal("application terminated with result code " & Fmt.Int(res), 1000); ELSE Msg.V("last application terminated with result code " & Fmt.Int(res)); Process.Exit(0); END; END; END ExecApplyCmdList;
PROCEDURE---------------------------------------------------------------------------ExecSelectByCmdList () = VAR res : TextSeq.T; pkgs : TextSeq.T; heedOrder := action = Action.OrderedApply; BEGIN pkgs := GetAndCheckPackages(); IF noAction THEN TOutTextSeq("The action `" & cmdList & "' would be applied to the following packages for selecting:", pkgs); WriteCheckpoint(); Process.Exit(0); END; IF heedOrder THEN Msg.V("selecting by `" & cmdList & "' from ordered list of packages..."); ELSE Msg.V("selecting by `" & cmdList & "' from unordered list of packages..."); END; TRY res := prjdesc.selectByCmdList( cmdList, ordered := heedOrder, selectOnZeroReturn := TRUE, breakOnFailure := stopOnFailures); EXCEPT PrjDesc.Error(e) => WriteCheckpoint(); Msg.Fatal("selection terminated with exception: " & e, 1000); END; TOutTextSeq("The following packages were selected:", res); WriteCheckpoint(); Process.Exit(0); END ExecSelectByCmdList;
PROCEDURE---------------------------------------------------------------------------ExecShowDependencies () = VAR all := nTargets = 0; BEGIN IF all THEN targets := prjdesc.packages(); nTargets := targets.size(); END; FOR i := 0 TO nTargets - 1 DO WITH pkg = targets.get(i) DO TOutTextSeq("package " & pkg & " is needed by:", prjdesc.dependendPackages(pkg)); END; END; IF all THEN ShowUpdateSequence(); END; WriteCheckpoint(); Process.Exit(0); END ExecShowDependencies;
PROCEDURE---------------------------------------------------------------------------ExecShowPackages () = BEGIN ListAllPackagesAndLocations(); END ExecShowPackages;
PROCEDURE---------------------------------------------------------------------------ExecShowPackagePaths () = VAR paths := prjdesc.locations(); collectionroot := prjdesc.collectionPath(); crlen := Text.Length(collectionroot); loc : TEXT; arcs : Pathname.Arcs; BEGIN Msg.T("Package paths relative to collectionroot:"); FOR i := 0 TO paths.size() - 1 DO loc := paths.get(i); IF TextUtils.Pos(loc, collectionroot) = 0 THEN loc := Text.Sub(loc, crlen); IF Pathname.Absolute(loc) THEN TRY arcs := Pathname.Decompose(loc); EVAL arcs.remlo(); arcs.addlo(NIL); loc := Pathname.Compose(arcs); EXCEPT Pathname.Invalid => Msg.Error("invalid pathname: " & loc); END; END; END; M(loc); END; Msg.T(""); END ExecShowPackagePaths;
PROCEDURE---------------------------------------------------------------------------ExecShowSrcDirectories () = BEGIN ListAllSrcDirectories(); END ExecShowSrcDirectories;
PROCEDURE---------------------------------------------------------------------------ExecShowPackageKinds () = BEGIN ListAllPackageKinds(); END ExecShowPackageKinds;
PROCEDURE---------------------------------------------------------------------------ExecShowSnapshotOrRelease () = VAR snap : TextTextTbl.T; name : TEXT; type : TEXT := "snapshot or release" ; res : TEXT; prjd : PrjDesc.T; BEGIN FOR i := 0 TO nTargets - 1 DO name := targets.get(i); IF Text.Equal(name, "head") THEN snap := prjdesc.snapshot(name); type := "current configuration "; ELSE TRY prjd := snaps.getSnapshot(name); snap := prjd.snapshot(name); type := "snapshot "; res := prjd.toText(); EXCEPT Snapshots.Error => TRY prjd := snaps.getRelease(name); snap := prjd.release(name); type := "release "; res := prjd.toText(); EXCEPT Snapshots.Error => snap := NIL; | PrjDesc.Error(e) => Msg.Fatal("cannot convert snapshot: " & e); END; | PrjDesc.Error(e) => Msg.Fatal("cannot convert snapshot: " & e); END; END; IF snap = NIL THEN M("no snapshot or release " & name); ELSE IF longListing THEN M(type & name); M(res); ELSE OutTextTable(type & name, snap); END; END; END; END ExecShowSnapshotOrRelease;
PROCEDURE---------------------------------------------------------------------------ExecEditSnapshotOrRelease () = VAR old, new : TEXT; snap : TextTextTbl.T; prjd : PrjDesc.T; type : TEXT; rd : Rd.T; BEGIN IF snapshotName = NIL THEN Msg.Fatal("no valid snapshot/release specified"); END; IF action = Action.EditRelease THEN TRY prjd := snaps.getRelease(snapshotName); snap := prjd.release(snapshotName); type := "release "; EXCEPT Snapshots.Error => Msg.Fatal("A release named " & snapshotName & " does not exist."); END; END; IF action = Action.EditSnapshot THEN TRY prjd := snaps.getSnapshot(snapshotName); snap := prjd.snapshot(snapshotName); type := "snapshot "; EXCEPT Snapshots.Error => Msg.Fatal("A snapshot named " & snapshotName & " does not exist."); END; END; TRY IF action = Action.EditRelease THEN old := prjd.releaseText(snapshotName); ELSE old := prjd.snapshotText(snapshotName); END; EXCEPT PrjDesc.Error(e) => Msg.Fatal("cannot convert " & type & " description: " & e); END; WITH editor = CompactRC.GetValue(env, "editor") DO new := PkgVCUtils.GetMessage(editor, NIL, msg := old); END; IF new # NIL THEN Msg.V("saving altered " & type & " description"); TRY EVAL prjd.init(NIL, cfg, FALSE, collectionroot, inCheckpFileName, FALSE, env, pkgvcAcc := pkgvcCreator, verboseCacheMsgs := verboseCache, preferredPkgKind := packageKind); prjdesc.defineGlobalVars(env); prjdesc.defineGlobalVars(vars); rd := TextRd.New(new); prjd.parse(rd); prjd.setModificationDate(Time.Now()); TRY Rd.Close(rd) EXCEPT ELSE END; IF action = Action.EditRelease THEN snaps.putRelease(snapshotName, prjd, TRUE); ELSE snaps.putSnapshot(snapshotName, prjd, TRUE); END; EXCEPT PrjDesc.Error(e) => Msg.Fatal("cannot parse " & type & " description: " & e); | Snapshots.Error(e) => Msg.Fatal("cannot overwrite " & type & " description: " & e); END; ELSE Msg.V(type & " unchanged"); END; END ExecEditSnapshotOrRelease;
PROCEDURE---------------------------------------------------------------------------ExecExport () = VAR data : TEXT; prjd : PrjDesc.T; cs : ChangeSet.T; type : TEXT; BEGIN IF snaps.releaseDefined(name) THEN TRY prjd := snaps.getRelease(name); type := "release "; data := prjd.releaseText(name); EXCEPT Snapshots.Error(e) => Msg.Fatal("snaps directory or snaps/snaps.idx corrupt: " & e); | PrjDesc.Error(e) => Msg.Fatal("snaps directory or snaps/snaps.idx corrupt: " & e); END; ELSIF snaps.snapshotDefined(name) THEN TRY prjd := snaps.getSnapshot(name); type := "snapshot "; data := prjd.snapshotText(name); EXCEPT Snapshots.Error(e) => Msg.Fatal("snaps directory or snaps/snaps.idx corrupt: " & e); | PrjDesc.Error(e) => Msg.Fatal("snaps directory or snaps/snaps.idx corrupt: " & e); END; ELSIF snaps.changeSetDefined(name) THEN TRY cs := snaps.getChangeSet(name); type := "change set "; data := cs.toText(); EXCEPT Snapshots.Error(e) => Msg.Fatal("snaps directory or snaps/snaps.idx corrupt: " & e); END; ELSE Msg.Fatal("no release, snapshot, or change set named " & name & " defined"); END; IF FSUtils.Exists(fileName) THEN IF NOT FSUtils.IsFile(fileName) THEN Msg.Fatal(fileName & " exists and is no ordinary file"); END; WITH msg = "The file `" & fileName & "' already exists.\n" & "Overwrite" DO IF NOT force AND NOT PkgVC.confirmation.okay(msg) THEN Msg.Fatal("aborted"); END; END; END; TRY IF NOT noAction THEN FSUtils.PutFile(fileName, data); END; EXCEPT FSUtils.E(e) => Msg.Fatal(e); END; Msg.V(type & name & " saved in file " & fileName); END ExecExport;
PROCEDURE---------------------------------------------------------------------------ExecImport () = VAR data : TEXT; prjd : PrjDesc.T; type : TEXT; rd : Rd.T; log : TEXT := NIL; lb := OSSpecials.LineBreak; action := "new "; BEGIN IF NOT FSUtils.Exists(fileName) THEN Msg.Fatal("no file " & fileName); END; IF NOT FSUtils.IsFile(fileName) THEN Msg.Fatal(fileName & "is no ordinary file"); END; TRY data := FSUtils.FileContents(fileName); EXCEPT FSUtils.E(e) => Msg.Fatal(e); END; IF TextUtils.Pos(TextUtils.SkipLeft(data), "changeset") = 0 THEN (* import a change set *) type := "change set"; IF snaps.changeSetDefined(name) THEN WITH msg = "The change set `" & name & "' already exists.\n" & "Overwrite" DO IF NOT force AND NOT PkgVC.confirmation.okay(msg) THEN Msg.Fatal("aborted"); END; END; action := "changed "; END; WITH cs = NEW(ChangeSet.T).init(name) DO TRY cs.parse(TextRd.New(data), "<in-memory copy>"); Msg.V("import change set " & name); IF NOT noAction THEN snaps.putChangeSet(name, cs, ovwr := TRUE); END; EXCEPT ChangeSet.Error(e) => Msg.Fatal("cannot parse change set description: " & e); | Snapshots.Error(e) => Msg.Fatal("cannot overwrite change set description: " & e); END; END; ELSE (* import a snapshot or release *) type := "snapshot or release configuration"; TRY prjd := NEW(PrjDesc.T).init(NIL, cfg, FALSE, collectionroot, inCheckpFileName, FALSE, env, pkgvcAcc := pkgvcCreator, verboseCacheMsgs := verboseCache, preferredPkgKind := packageKind); prjdesc.defineGlobalVars(env); prjdesc.defineGlobalVars(vars); rd := TextRd.New(data); prjd.parse(rd); prjd.setModificationDate(Time.Now()); TRY Rd.Close(rd) EXCEPT ELSE END; IF prjd.release(name) # NIL THEN type := "release configuration"; IF snaps.releaseDefined(name) THEN WITH msg = "The release `" & name & "' already exists.\n" & "Overwrite" DO IF NOT force AND NOT PkgVC.confirmation.okay(msg) THEN Msg.Fatal("aborted"); END; END; action := "changed "; END; Msg.V("import release configuration " & name); IF NOT noAction THEN snaps.putRelease(name, prjd, TRUE); END; ELSIF prjd.snapshot(name) # NIL THEN type := "snapshot configuration"; IF snaps.snapshotDefined(name) THEN WITH msg = "The snapshot `" & name & "' already exists.\n" & "Overwrite" DO IF NOT force AND NOT PkgVC.confirmation.okay(msg) THEN Msg.Fatal("aborted"); END; END; action := "changed "; END; Msg.V("import snapshot configuration " & name); IF NOT noAction THEN snaps.putSnapshot(name, prjd, TRUE); END; ELSE VAR rels := prjd.releases(); snaps := prjd.snapshots(); relText := "<none>"; snapText := "<none>"; BEGIN IF rels.size() > 0 THEN relText := TextUtils.TextSeqToText(rels); END; IF snaps.size() > 0 THEN snapText := TextUtils.TextSeqToText(snaps); END; Msg.Fatal("no snapshot or release configuration `" & name & "' in file " & fileName & "\nincluded releases: " & relText & "\nincluded snapshots: " & snapText); END; END; EXCEPT PrjDesc.Error(e) => Msg.Fatal("cannot parse " & type & " description: " & e); | Snapshots.Error(e) => Msg.Fatal("cannot overwrite " & type & " description: " & e); END; END; IF useVC AND NOT noAction THEN IF commitMsg = NIL THEN log := action & type & " " & name &":" & lb & lb & "PKG: Please enter a local commit message for " & type & lb & "PKG: " & name &"." & lb & "PKG: If you have made no other changes than the import " & "of this " & type & "," & lb & "PKG: the above message will probably be appropriate. " & lb; WITH editor = CompactRC.GetValue(env, "editor") DO log := PkgVCUtils.GetMessage(editor, NIL, msg := log, failIfUnchanged := FALSE); END; IF log # NIL THEN commitMsg := log; END; ELSIF commitMsg # NIL AND NOT TextUtils.Contains(commitMsg, name) THEN commitMsg := action & type & " " & name &":" & lb & lb & commitMsg & lb; END; CommitLocalFiles(PkgVC.CommitType.Minor); END; END ExecImport;
PROCEDURE---------------------------------------------------------------------------ExecShowSnapshots () = BEGIN TRY OutTextSeq("all recorded project snapshots:", snaps.listSnapshots(sort, sortUp)); EXCEPT Snapshots.Error(e) => Msg.Fatal("cannot list snapshots: " & e, 1000); END; END ExecShowSnapshots;
PROCEDURE---------------------------------------------------------------------------ExecShowReleases () = BEGIN TRY OutTextSeq("all released project configurations:", snaps.listReleases(sort, sortUp)); EXCEPT Snapshots.Error(e) => Msg.Fatal("cannot list releases: " & e, 1000); END; END ExecShowReleases;
PROCEDURE---------------------------------------------------------------------------ExecShowChangeSets () = BEGIN TRY OutTextSeq("all recorded project change sets:", snaps.listChangeSets(sort, sortUp)); EXCEPT Snapshots.Error(e) => Msg.Fatal("cannot list change sets: " & e, 1000); END; END ExecShowChangeSets;
PROCEDURE---------------------------------------------------------------------------ExecShowChangeSetLog () = PROCEDURE ShowOne(cs : ChangeSet.T) = BEGIN M("----------------------------"); M(cs.logText()); END ShowOne; VAR csByName : SortedTextChangeSetTbl.T; nameIter : SortedTextChangeSetTbl.Iterator; csByDate : SortedTimeChangeSetTbl.T; dateIter : SortedTimeChangeSetTbl.Iterator; name : TEXT; date : Time.T; cs : ChangeSet.T; BEGIN TRY IF sort = Snapshots.Sort.ByName THEN csByName := snaps.changeSetsByName(); nameIter := csByName.iterateOrdered(sortUp); WHILE nameIter.next(name, cs) DO ShowOne(cs); END; ELSE csByDate := snaps.changeSetsByDate(); dateIter := csByDate.iterateOrdered(sortUp); WHILE dateIter.next(date, cs) DO ShowOne(cs); END; END; EXCEPT Snapshots.Error(e) => Msg.Error(e); END; END ExecShowChangeSetLog;
PROCEDURE---------------------------------------------------------------------------ExecShowSnapshotOrReleaseLog () = PROCEDURE ShowOne(prjd : PrjDesc.T) = BEGIN M("----------------------------"); M(prjd.logText()); END ShowOne; VAR prjdByName : SortedTextPrjDescTbl.T; nameIter : SortedTextPrjDescTbl.Iterator; prjdByDate : SortedTimePrjDescTbl.T; dateIter : SortedTimePrjDescTbl.Iterator; name : TEXT; date : Time.T; prjd : PrjDesc.T; BEGIN TRY IF sort = Snapshots.Sort.ByName THEN IF action = Action.SnapshotLog THEN prjdByName := snaps.snapshotsByName(); ELSE prjdByName := snaps.releasesByName(); END; nameIter := prjdByName.iterateOrdered(sortUp); WHILE nameIter.next(name, prjd) DO ShowOne(prjd); END; ELSE IF action = Action.SnapshotLog THEN prjdByDate := snaps.snapshotsByDate(sortByModificationDate); ELSE prjdByDate := snaps.releasesByDate(sortByModificationDate); END; dateIter := prjdByDate.iterateOrdered(sortUp); WHILE dateIter.next(date, prjd) DO ShowOne(prjd); END; END; EXCEPT Snapshots.Error(e) => Msg.Error(e); END; END ExecShowSnapshotOrReleaseLog;
PROCEDURE---------------------------------------------------------------------------ExecShowModified () = VAR res : INTEGER; pkgs : TextSeq.T; BEGIN pkgs := GetAndCheckPackages(); TRY res := prjdesc.applyToPackages("checkmodified", NIL, NIL, pkgs, ordered := FALSE, breakOnZeroReturn := FALSE, breakOnError := FALSE, breakOnFailure := stopOnFailures); EXCEPT PrjDesc.Error(e) => WriteCheckpoint(); Msg.Fatal("check terminated with exception: " & e, 1000); END; WriteCheckpoint(); Process.Exit(0); END ExecShowModified;
PROCEDURE---------------------------------------------------------------------------ExecShowOutOfDate () = VAR res : INTEGER; pkgs : TextSeq.T; BEGIN pkgs := GetAndCheckPackages(); TRY res := prjdesc.applyToPackages("checkuptodate", NIL, NIL, pkgs, ordered := FALSE, breakOnZeroReturn := FALSE, breakOnError := FALSE, breakOnFailure := stopOnFailures); EXCEPT PrjDesc.Error(e) => WriteCheckpoint(); Msg.Fatal("check terminated with exception: " & e, 1000); END; WriteCheckpoint(); Process.Exit(0); END ExecShowOutOfDate;
PROCEDURE---------------------------------------------------------------------------ExecShowConflicts () = VAR res : INTEGER; pkgs : TextSeq.T; BEGIN pkgs := GetAndCheckPackages(); TRY res := prjdesc.applyToPackages("checkconflicts", NIL, NIL, pkgs, ordered := FALSE, breakOnZeroReturn := FALSE, breakOnError := FALSE, breakOnFailure := stopOnFailures); EXCEPT PrjDesc.Error(e) => WriteCheckpoint(); Msg.Fatal("check terminated with exception: " & e, 1000); END; WriteCheckpoint(); Process.Exit(0); END ExecShowConflicts;
PROCEDURE---------------------------------------------------------------------------ExecShowUpdateSequence () = BEGIN ShowUpdateSequence(); WriteCheckpoint(); Process.Exit(0); END ExecShowUpdateSequence;
PROCEDURE---------------------------------------------------------------------------ExecNewStateCache () = BEGIN Msg.V("re-initializing state cache..."); TRY prjdesc.newCheckpoint(outCheckpFileName); EXCEPT PrjDesc.Error(e) => Msg.Fatal("cannot create new checkpoint: " & e, 1000); END; Process.Exit(0); END ExecNewStateCache;
PROCEDURE---------------------------------------------------------------------------ExecPurgeUnsureVersionInfo () = BEGIN Msg.V("invalidating unsure version info in cache..."); TRY prjdesc.invalidateCachedUnsureVersionInfo(); EXCEPT PrjDesc.Error(e) => Msg.Fatal("cannot clean state cache: " & e, 1000); END; WriteCheckpoint(); Process.Exit(0); END ExecPurgeUnsureVersionInfo;
PROCEDURE---------------------------------------------------------------------------ExecPurgeBuildInfo () = BEGIN Msg.V("invalidating build information in cache..."); TRY prjdesc.invalidateCachedBuildInfo(); EXCEPT PrjDesc.Error(e) => Msg.Fatal("cannot clean state cache: " & e, 1000); END; WriteCheckpoint(); Process.Exit(0); END ExecPurgeBuildInfo;
PROCEDURE---------------------------------------------------------------------------PurgeUnsureVersionInfoIfNotLazy () = BEGIN IF lazy OR NOT useStateCache THEN RETURN END; TRY prjdesc.invalidateCachedUnsureVersionInfo(); EXCEPT PrjDesc.Error(e) => Msg.Fatal("cannot clean state cache: " & e, 1000); END; END PurgeUnsureVersionInfoIfNotLazy;
PROCEDURE---------------------------------------------------------------------------ExecShowStateCache () = VAR cpt : TEXT; BEGIN IF NOT useStateCache THEN Msg.Fatal("Show state cache cannot be used together with -nocache", 3); END; WITH cp = prjdesc.getPoolSet().cachedState() DO TRY cpt := cp.toText(); M(cpt); EXCEPT ELSE Msg.Error("cannot convert checkpoint to text"); END; END; WriteCheckpoint(); Process.Exit(0); END ExecShowStateCache;
PROCEDURE---------------------------------------------------------------------------ExecShowStatus () = VAR cp : Checkpoint.T; dir : TEXT; pkg : TEXT; tag : TEXT; line : TEXT; dirs : TextSeq.T; attr : Checkpoint.AttrSet; PROCEDURE VCAttrToText(attr : Checkpoint.AttrSet) : TEXT = VAR res := ""; BEGIN IF Checkpoint.Attr.Changed IN attr THEN res := res & " changed"; END; IF Checkpoint.Attr.Modified IN attr THEN res := res & " modified"; END; IF Checkpoint.Attr.UpToDate IN attr THEN res := res & " up-to-date"; END; IF Checkpoint.Attr.OutOfDate IN attr THEN res := res & " out-of-date"; END; IF Checkpoint.Attr.Conflicts IN attr THEN res := res & " conflicts"; END; IF Checkpoint.Attr.IsRelease IN attr THEN res := res & " release"; END; RETURN res; END VCAttrToText; PROCEDURE OtherAttrToText(attr : Checkpoint.AttrSet) : TEXT = VAR res := ""; BEGIN IF Checkpoint.Attr.DepMade IN attr THEN res := res & " depend-done"; END; IF Checkpoint.Attr.BuildOkL IN attr THEN res := res & " built-locally"; END; IF Checkpoint.Attr.BuildOk IN attr THEN res := res & " built"; END; IF Checkpoint.Attr.BuildFailed IN attr THEN res := res & " build-failed"; END; IF Checkpoint.Attr.ShippedToLP IN attr THEN res := res & " shipped-to-local-pool"; END; IF Checkpoint.Attr.ShippedToPP IN attr THEN res := res & " shipped-to-project-pool"; END; IF Checkpoint.Attr.ShippedToGP IN attr THEN res := res & " shipped-to-global-pool"; END; RETURN res; END OtherAttrToText; VAR pkgSet : PoolSet.T; BEGIN IF NOT useStateCache THEN Msg.Fatal("Show status is a cache operation, you cannot use it " & "together with -nocache", 3); END; pkgSet := prjdesc.getPoolSet(); cp := pkgSet.cachedState(); dirs := cp.dirs(); FOR i := 0 TO dirs.size() - 1 DO dir := dirs.get(i); pkg := Pathname.Last(dir); TRY tag := cp.getVal(dir, "current-tag"); IF tag = NIL THEN EVAL pkgSet.getAndCacheVersionState(pkg); tag := cp.getVal(dir, "current-tag"); END; attr := cp.getAttr(dir); line := pkg & ": " & tag & VCAttrToText(attr); IF action = Action.ShowLongStatus THEN line := line & OtherAttrToText(attr); END; M(line); EXCEPT Checkpoint.Error(e) => Msg.Error("cannot get attributes of package " & pkg & ": " & e); | PoolSet.Error(e) => Msg.Error("cannot update version state cache of package " & pkg & ": " & e); END; END; WriteCheckpoint(); Process.Exit(0); END ExecShowStatus;
PROCEDURE---------------------------------------------------------------------------ExecListPackageKinds () = (* List all defined packages kinds (from PkgBase.DefaultData). *) BEGIN Msg.V("listing all defined package kinds:"); VAR l := cfg.kindList(); BEGIN WHILE l # NIL DO M(l.head); l := l.tail; END; END; END ExecListPackageKinds;
PROCEDURE---------------------------------------------------------------------------ExecDumpAllPackageKinds () = BEGIN M(cfgData); END ExecDumpAllPackageKinds;
PROCEDURE---------------------------------------------------------------------------WriteCheckpoint () = BEGIN IF NOT useStateCache THEN RETURN END; IF prjdesc = NIL THEN Msg.V("no project description read, not checkpoint update"); RETURN; END; TRY prjdesc.writeCheckpoint(outCheckpFileName); EXCEPT PrjDesc.Error(e) => Msg.Fatal("cannot write checkpoint file: " & e); END; END WriteCheckpoint;
PROCEDURE---------------------------------------------------------------------------Rename (from, to : Pathname.T) = BEGIN Msg.V("renaming " & from & " to " & to & "..."); TRY FS.Rename(from, to); EXCEPT OSError.E => Msg.Fatal("cannot rename file " & from & " to " & to); END; END Rename;
PROCEDURE---------------------------------------------------------------------------PrjDescLoadHead () = BEGIN Msg.V("parsing project description file " & prjFileName & "..."); actPrjFileName := prjFileName; TRY prjdesc := NEW(PrjDesc.T).init(actPrjFileName, cfg, FALSE, collectionroot, inCheckpFileName, useStateCache, env, pkgvcAcc := pkgvcCreator, verboseCacheMsgs := verboseCache, preferredPkgKind := packageKind, depsMandatory := depsMandatory, cacheEarly := cacheEarly); prjdesc.defineGlobalVars(env); prjdesc.defineGlobalVars(vars); EXCEPT PrjDesc.Error(e) => Msg.Fatal(e, 3); END; IF FSUtils.IsFile(ActStateFN) THEN Rename(ActStateFN, OldStateFN); END; END PrjDescLoadHead;
PROCEDURE---------------------------------------------------------------------------PrjDescActState () = BEGIN Msg.V("parsing project description file " & ActStateFN & "..."); actPrjFileName := ActStateFN; TRY prjdesc := NEW(PrjDesc.T).init(actPrjFileName, cfg, FALSE, collectionroot, inCheckpFileName, useStateCache, env, pkgvcAcc := pkgvcCreator, verboseCacheMsgs := verboseCache, preferredPkgKind := packageKind, depsMandatory := depsMandatory, cacheEarly := cacheEarly); prjdesc.defineGlobalVars(env); prjdesc.defineGlobalVars(vars); EXCEPT PrjDesc.Error(e) => Msg.Fatal(e, 3); END; END PrjDescActState;
PROCEDURE---------------------------------------------------------------------------PrjDescOldState () = <* NOWARN *> BEGIN Rename(OldStateFN, ActStateFN); PrjDescActState(); END PrjDescOldState;
BEGIN (* Main *) Msg.tFlag := TRUE; PreEvalArguments(); Msg.V("initializing global variables..."); InitGlobalVars(); Msg.V("evaluating command line arguments..."); EvalArguments(); (* disabled in for CM3 IF DemoCheck1.IsDemoVersion() THEN IF (Msg.vFlag OR Msg.dFlag OR Msg.tFlag) THEN DemoCheck1.Message(); END; ELSE IF NOT Release.KeyCheck(MiniEnv.pass) THEN Msg.Fatal("invalid passphrase"); END; END; *) IF action IN NoCacheAction THEN useStateCache := FALSE; END; IF useStateCache THEN Msg.V("using checkpoint file " & outCheckpFileName); END; IF action = Action.Checkout THEN IF useStateCache THEN updateStateCache := TRUE; END; useStateCache := FALSE; END; IF useInternalVC THEN pkgvcCreator := NEW(PoolSet.PkgVCCreator); pkgvcCreator.env := env; pkgvcCreator.msgif := NIL; ELSE pkgvcCreator := NIL; END; IF packageKind = NIL THEN packageKind := defaultPackageKind; END; IF action IN PreParseAction THEN IF FSUtils.IsFile(ActStateFN) THEN Msg.V("using project description from file " & ActStateFN); PrjDescActState(); ELSE Msg.V("using project description from file " & prjFileName); PrjDescLoadHead() END; END; IF NOT action IN NoSnapsAction THEN InitSnapshots(); END; IF FSUtils.IsFile(prjMagicFile) THEN Msg.Warning("Found an obsolete project magic file, will ignore it..."); END; IF prjdesc # NIL THEN Msg.V("the root of all package collections is " & prjdesc.collectionPath()); IF packageKind # NIL THEN Msg.V("setting preferred package kind to " & packageKind); prjdesc.setPreferredPkgKind(packageKind); END; END; IF action IN PreCheckAction THEN IF prjdesc.missingPackages() # NIL THEN Msg.V("checking out missing packages..."); TRY prjdesc.checkoutPackages(prjdesc.missingPackages()); EXCEPT PrjDesc.Error(e) => Msg.Error("checkout failed: " & e); END; END; Msg.V("checking all packages..."); VAR res : TEXT; BEGIN IF NOT prjdesc.pkgsOkay(res) THEN Msg.Fatal(res, 4); END; END; END; IF externalShell # NIL AND prjdesc # NIL THEN Msg.V("setting external shell to " & externalShell & "..."); prjdesc.setExternalShell(externalShell); END; IF (action IN PreDepAction OR Msg.vFlag OR modifiedAndDeps OR outOfDateAndDeps OR dependendPkgs OR useStateCache) AND action # Action.Checkout AND action # Action.CommitLocalFiles AND action # Action.EditChangeSet AND prjdesc # NIL THEN CreateDependencyGraph(); END; IF Msg.vFlag AND action # Action.Checkout AND action # Action.CommitLocalFiles AND action # Action.EditChangeSet AND prjdesc # NIL THEN CheckImports(); END; IF onlyModified AND prjdesc # NIL THEN Msg.V("looking for locally modified packages..."); TRY IF modifiedAndDeps THEN modifiedPkgs := prjdesc.modifiedAndDependingPackages(); ELSE modifiedPkgs := prjdesc.modifiedPackages(); END; EXCEPT PrjDesc.Error(e) => Msg.Fatal("test failed with exception: " & e & ", some packages may be modified", 1000); END; ELSIF onlyOutOfDate AND prjdesc # NIL THEN Msg.V("looking for out-of-date packages..."); PurgeUnsureVersionInfoIfNotLazy(); TRY IF outOfDateAndDeps THEN outOfDatePkgs := prjdesc.outOfDateAndDependingPackages(); ELSE outOfDatePkgs := prjdesc.outOfDatePackages(); END; EXCEPT PrjDesc.Error(e) => Msg.Fatal("test failed with exception: " & e & ", some packages may be out-of-date", 1000); END; END; IF prjdesc # NIL THEN IF tag1 # NIL THEN IF Text.Equal(tag1, "head") THEN tag1prjdesc := prjdesc; tag1vals := tag1prjdesc.snapshot(tag1); ELSE TRY tag1prjdesc := snaps.getSnapshot(tag1); tag1vals := tag1prjdesc.snapshot(tag1); EXCEPT Snapshots.Error => TRY tag1prjdesc := snaps.getRelease(tag1); tag1vals := tag1prjdesc.release(tag1); EXCEPT Snapshots.Error(e) => Msg.Error(e); END; END; END; END; IF tag2 # NIL THEN IF Text.Equal(tag2, "head") THEN tag2prjdesc := prjdesc; tag2vals := tag2prjdesc.snapshot(tag2); ELSE TRY tag2prjdesc := snaps.getSnapshot(tag2); tag2vals := tag2prjdesc.snapshot(tag2); EXCEPT Snapshots.Error => TRY tag2prjdesc := snaps.getRelease(tag2); tag2vals := tag2prjdesc.release(tag2); EXCEPT Snapshots.Error(e) => Msg.Error(e); END; END; END; END; END; IF changeSetName = NIL AND (action = Action.MergeChangeSet OR action = Action.EditChangeSet) THEN IF nTargets > 0 THEN changeSetName := targets.get(0); END; END; IF changeSetName # NIL AND NOT action IN PkgCommitAction THEN TRY changeSet := snaps.getChangeSet(changeSetName); EXCEPT Snapshots.Error(e) => Msg.Fatal(e) END; END; Msg.V("executing user command..."); IF action IN PredicateAction THEN ExecPredicate(); ELSIF action IN BuildAction THEN ExecBuildAction(); ELSIF action IN CleanAction THEN ExecCleanAction(); ELSIF action IN ShipAction THEN ExecShipAction(); ELSIF action IN DiffAction THEN ExecDiffAction(); ELSIF action IN PkgCommitAction THEN ExecPackageCommitAction(); ELSIF action IN ApplyCmdListAction THEN ExecApplyCmdList(); ELSIF action IN ApplyAction THEN ExecApplyAction(); ELSIF action IN SelectByCmdListAction THEN ExecSelectByCmdList(); ELSIF action IN PkgFreezeAction THEN ExecFreezeAction(); ELSIF action = Action.StableRelease THEN ExecMakeStableRelease(); ELSIF action = Action.Checkout THEN ExecCheckout(); ELSIF action = Action.CommitLocalFiles THEN ExecCommitLocalFiles(); ELSIF action = Action.CheckImports THEN CheckImports(); ELSIF action = Action.CheckState THEN CheckStateLabel(); ELSIF action = Action.DependingNodes THEN ExecShowDependencies(); ELSIF action = Action.ShowPackages THEN ExecShowPackages(); ELSIF action = Action.ShowSrcDirectories THEN ExecShowSrcDirectories(); ELSIF action = Action.ShowPackagePaths THEN ExecShowPackagePaths(); ELSIF action = Action.ShowPackageKinds THEN ExecShowPackageKinds(); ELSIF action = Action.ShowModified THEN ExecShowModified(); ELSIF action = Action.ShowOutOfDate THEN ExecShowOutOfDate(); ELSIF action = Action.ShowConflicts THEN ExecShowConflicts(); ELSIF action = Action.ShowUpdateSequence THEN ExecShowUpdateSequence(); ELSIF action = Action.ShowSnapshot OR action = Action.ShowRelease THEN ExecShowSnapshotOrRelease(); ELSIF action = Action.EditSnapshot OR action = Action.EditRelease THEN ExecEditSnapshotOrRelease(); ELSIF action = Action.ShowSnapshots THEN ExecShowSnapshots(); ELSIF action = Action.ShowReleases THEN ExecShowReleases(); ELSIF action = Action.ShowChangeSets THEN ExecShowChangeSets(); ELSIF action = Action.ChangeSetLog THEN ExecShowChangeSetLog(); ELSIF action = Action.SnapshotLog OR action = Action.ReleaseLog THEN ExecShowSnapshotOrReleaseLog(); ELSIF action = Action.EditChangeSet THEN ExecEditChangeSet(); ELSIF action = Action.MergeChangeSet THEN ExecMergeChangeSet(); ELSIF action = Action.ShowStateCache THEN ExecShowStateCache(); ELSIF action = Action.ShowShortStatus THEN ExecShowStatus(); ELSIF action = Action.ShowLongStatus THEN ExecShowStatus(); ELSIF action = Action.NewStateCache THEN ExecNewStateCache(); ELSIF action = Action.PurgeUnsureVersionInfo THEN ExecPurgeUnsureVersionInfo(); ELSIF action = Action.PurgeBuildInfo THEN ExecPurgeBuildInfo(); ELSIF action = Action.ListKinds THEN ExecListPackageKinds(); ELSIF action = Action.DumpKinds THEN ExecDumpAllPackageKinds(); ELSIF action = Action.CreatePkgOvrFiles THEN ExecCreatePkgOvrFiles(); ELSIF action = Action.BuiltOk THEN EverythingBuiltOkay(); ELSIF action = Action.Import THEN ExecImport(); ELSIF action = Action.Export THEN ExecExport(); ELSE Msg.Fatal("Sorry, this seems to be not yet implemented", 1001); END; WriteCheckpoint(); Process.Exit(0); END ProjectManager.