diff --git a/vsSolutionBuildEvent/Actions/ActionCSharp.cs b/vsSolutionBuildEvent/Actions/ActionCSharp.cs index 62de773f..e948847b 100644 --- a/vsSolutionBuildEvent/Actions/ActionCSharp.cs +++ b/vsSolutionBuildEvent/Actions/ActionCSharp.cs @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015 Denis Kuzmin (reg) + * Copyright (c) 2013-2016 Denis Kuzmin (reg) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -39,7 +39,7 @@ public class ActionCSharp: Action, IAction /// /// Main class for user code. /// - public const string MAIN_CLASS = "vsSolutionBuildEvent.CSharpMode"; + public const string MAIN_CLASS = Settings.APP_NAME + ".CSharpMode"; /// /// Entry point for user code. @@ -49,7 +49,7 @@ public class ActionCSharp: Action, IAction /// /// Prefix to cached bytecode. /// - protected const string PREFIX_CACHE = "cached_vssbe."; + protected const string PREFIX_CACHE = "cached_" + Settings.APP_NAME_SHORT + "."; /// /// Where to look cache. @@ -108,13 +108,24 @@ public override bool process(ISolutionEvent evt) type = load(outputCacheFile(evt), assemblyName(evt)); } + if(type == null) { + Log.Error($"Compiled type is null. Something went wrong for C# Action '{evt.Name}'"); + } + int ret = run(type, cmd, evt); - if(ret != 0) - { - Log.Warn("Return code '{0}'", ret); - return false; + if(ret == 0) { + return true; } - return true; + + string retmsg = $"Return code '{ret}'"; + + if(((IModeCSharp)evt.Mode).TreatWarningsAsErrors) { + Log.Error(retmsg); + } + else { + Log.Warn(retmsg); + } + return false; } /// diff --git a/vsSolutionBuildEvent/Actions/Command.cs b/vsSolutionBuildEvent/Actions/Command.cs index 8bdcb3e3..f26be722 100644 --- a/vsSolutionBuildEvent/Actions/Command.cs +++ b/vsSolutionBuildEvent/Actions/Command.cs @@ -180,8 +180,8 @@ protected bool actionBy(ModeType type, ISolutionEvent evt) } string marker = null; - if(Thread.CurrentThread.Name == Events.LoggingEvent.IDENT_TH) { - marker = Events.LoggingEvent.IDENT_TH; + if(Thread.CurrentThread.Name == LoggingEvent.IDENT_TH) { + marker = LoggingEvent.IDENT_TH; } (new Task(() => { @@ -189,8 +189,14 @@ protected bool actionBy(ModeType type, ISolutionEvent evt) if(Thread.CurrentThread.Name == null && marker != null) { Thread.CurrentThread.Name = marker; } - Log.Trace("Task for another thread is started for '{0}' /{1}", evt.Name, type); - actions[type].process(evt); + + Log.Trace($"Task ({type}) for another thread is started for '{evt.Name}'"); + try { + actions[type].process(evt); + } + catch(Exception ex) { + Log.Error($"Task ({type}) for another thread is failed. '{evt.Name}' Error: `{ex.Message}`"); + } })).Start(); diff --git a/vsSolutionBuildEvent/IsolatedEnv.cs b/vsSolutionBuildEvent/IsolatedEnv.cs index d1b7ffe2..88702f55 100644 --- a/vsSolutionBuildEvent/IsolatedEnv.cs +++ b/vsSolutionBuildEvent/IsolatedEnv.cs @@ -374,7 +374,7 @@ public IsolatedEnv(string solutionFile, TProp properties) /// Solution properties. public IsolatedEnv(TProp properties) { - + slnProperties = properties; } /// diff --git a/vsSolutionBuildEvent/SBEScripts/Bootloader.cs b/vsSolutionBuildEvent/SBEScripts/Bootloader.cs index c74f5958..8e83764c 100644 --- a/vsSolutionBuildEvent/SBEScripts/Bootloader.cs +++ b/vsSolutionBuildEvent/SBEScripts/Bootloader.cs @@ -119,7 +119,7 @@ public virtual void register() register(new UserVariableComponent(this)); register(new OWPComponent(Env)); register(new DTEComponent(Env)); - register(new InternalComponent(Env)); + register(new InternalComponent(this)); register(new MSBuildComponent(this)); register(new BuildComponent(Env)); register(new FunctionComponent(this)); diff --git a/vsSolutionBuildEvent/SBEScripts/Components/BoxComponent.cs b/vsSolutionBuildEvent/SBEScripts/Components/BoxComponent.cs index 4ecf46b3..d1baa54a 100644 --- a/vsSolutionBuildEvent/SBEScripts/Components/BoxComponent.cs +++ b/vsSolutionBuildEvent/SBEScripts/Components/BoxComponent.cs @@ -378,7 +378,7 @@ protected string dataFree(IPM pm, string name) "stData", new string[] { "name", "forceEval" }, new string[] { "The name of package.", "To force evaluate data of package before receiving." }, - CValueType.Void, + CValueType.Mixed, CValueType.String, CValueType.Boolean)] protected string dataGet(ILevel level, IPM pm) { @@ -408,7 +408,7 @@ protected string dataGet(IPM pm, string name, bool forceEval) "stData", new string[] { "name", "count" }, new string[] { "The name of package.", "The number of clones." }, - CValueType.Void, + CValueType.Mixed, CValueType.String, CValueType.Integer)] [Method("clone", "Multiple getting package data.", @@ -416,7 +416,7 @@ protected string dataGet(IPM pm, string name, bool forceEval) "stData", new string[] { "name", "count", "forceEval" }, new string[] { "The name of package.", "The number of clones.", "To force evaluate data of package before receiving." }, - CValueType.Void, + CValueType.Mixed, CValueType.String, CValueType.Integer, CValueType.Boolean)] protected string dataClone(ILevel level, IPM pm) { diff --git a/vsSolutionBuildEvent/SBEScripts/Components/InternalComponent.cs b/vsSolutionBuildEvent/SBEScripts/Components/InternalComponent.cs index c814fa96..aa48c4e1 100644 --- a/vsSolutionBuildEvent/SBEScripts/Components/InternalComponent.cs +++ b/vsSolutionBuildEvent/SBEScripts/Components/InternalComponent.cs @@ -17,6 +17,7 @@ using System; using net.r_eg.vsSBE.Actions; +using net.r_eg.vsSBE.Bridge; using net.r_eg.vsSBE.Events; using net.r_eg.vsSBE.Exceptions; using net.r_eg.vsSBE.SBEScripts.Dom; @@ -47,6 +48,13 @@ public override bool CRegex get { return true; } } + /// Initialization with loader + public InternalComponent(IBootloader loader) + : base(loader) + { + + } + /// Used environment public InternalComponent(IEnvironment env) : base(env) @@ -166,28 +174,27 @@ protected string stEvents(IPM pm) } /// - /// Work with event-item node. - /// `events.Type.item(string name | integer index)` + /// `events.Type.item(string name | integer index)` /// /// Type of available events /// - /// evaluated data + /// [Method( - "item", - "Event item by name", + "item", + "Access to action by name", "", "stEvents", new string[] { "name" }, - new string[] { "Name of the event" }, + new string[] { "Name of the action" }, CValueType.Void, CValueType.String )] [Method( - "item", - "Event item by index", + "item", + "Access to action by index", "", "stEvents", new string[] { "index" }, - new string[] { "Index of the event >= 1" }, + new string[] { "Index of the action >= 1" }, CValueType.Void, CValueType.Integer )] @@ -215,6 +222,9 @@ protected string stEventItem(SolutionEventType type, IPM pm) if(pm.Is(1, LevelType.Property, "Enabled")) { return pEnabled(evt, pm.pinTo(2)); } + if(pm.Is(1, LevelType.Method, "run")) { + return mActionRun(type, evt, pm.pinTo(1)); + } if(pm.Is(1, LevelType.Property, "Status")) { return itemStatus(type, index, pm.pinTo(1)); } @@ -233,11 +243,11 @@ protected string stEventItem(SolutionEventType type, IPM pm) /// `item(...).Status.HasErrors` /// /// Selected event type. - /// Access by index. + /// Access to action by index. /// /// - [Property("Status", "Available statuses for selected event-item.", "item", "stEventItem")] - [Property("HasErrors", "Checking existence of errors after executed action for selected event-item.", "Status", "itemStatus", CValueType.Boolean)] + [Property("Status", "Available states for selected event-action.", "item", "stEventItem")] + [Property("HasErrors", "Checking existence of errors after executed action for selected event-action.", "Status", "itemStatus", CValueType.Boolean)] protected string itemStatus(SolutionEventType type, int index, IPM pm) { if(!pm.Is(LevelType.Property, "Status")) { @@ -283,7 +293,7 @@ protected string pStderr(ISolutionEvent evt, IPM pm) /// Selected event /// /// - [Property("Enabled", "Gets or Sets Enabled status for selected event-item", "item", "stEventItem", CValueType.Boolean, CValueType.Boolean)] + [Property("Enabled", "Gets or Sets Enabled status for selected event-action", "item", "stEventItem", CValueType.Boolean, CValueType.Boolean)] protected string pEnabled(ISolutionEvent evt, IPM pm) { if(pm.FinalEmptyIs(LevelType.RightOperandEmpty)) { @@ -296,6 +306,51 @@ protected string pEnabled(ISolutionEvent evt, IPM pm) return Value.Empty; } + [Method( + "run", + "Execute Action with specific context. Returns true value if it was handled.", + "item", + "stEventItem", + new string[] { "context" }, + new string[] { "Specific context." }, + CValueType.Boolean, + CValueType.Enum + )] + [Method( + "run", + "Execute Action. Returns true value if it was handled.", + "item", + "stEventItem", + new string[] { "" }, + new string[] { "" }, + CValueType.Boolean, + CValueType.Void + )] + protected string mActionRun(SolutionEventType type, ISolutionEvent evt, IPM pm) + { + if(!pm.FinalEmptyIs(LevelType.Method, "run")) { + throw new IncorrectNodeException(pm); + } + ILevel level = pm.FirstLevel; + + BuildType buildType; + if(level.Args == null || level.Args.Length < 1) { + buildType = BuildType.Common; + } + else if(level.Is(ArgumentType.EnumOrConst)) { + buildType = (BuildType)Enum.Parse(typeof(BuildType), (string)level.Args[0].data); + } + else { + throw new ArgumentPMException(level, "run([enum context])"); + } + + ICommand cmd = new Actions.Command(env, script, msbuild); + Log.Info($"Execute action by user-script: '{evt.Name}'(context: {buildType}) /as '{type}' event"); + + cmd.Env.BuildType = buildType; + return Value.from(cmd.exec(evt, type)); + } + protected virtual ISolutionEvent[] getEvent(SolutionEventType type) { try { diff --git a/vsSolutionBuildEvent/UI/WForms/EventsFrm.Designer.cs b/vsSolutionBuildEvent/UI/WForms/EventsFrm.Designer.cs index 38fe06db..c78550da 100644 --- a/vsSolutionBuildEvent/UI/WForms/EventsFrm.Designer.cs +++ b/vsSolutionBuildEvent/UI/WForms/EventsFrm.Designer.cs @@ -475,7 +475,7 @@ private void InitializeComponent() this.menuActionExec.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.E))); this.menuActionExec.Size = new System.Drawing.Size(154, 22); this.menuActionExec.Text = "Execute"; - this.menuActionExec.ToolTipText = "Try current action"; + this.menuActionExec.ToolTipText = "Try current action (Common Context)"; this.menuActionExec.Click += new System.EventHandler(this.menuActionExec_Click); // // toolStripMenuReset diff --git a/vsSolutionBuildEvent/UI/WForms/Logic/Events.cs b/vsSolutionBuildEvent/UI/WForms/Logic/Events.cs index 6b5bcbe5..68258970 100644 --- a/vsSolutionBuildEvent/UI/WForms/Logic/Events.cs +++ b/vsSolutionBuildEvent/UI/WForms/Logic/Events.cs @@ -872,6 +872,7 @@ public void execAction() SolutionEventType type = SBE.type; Log.Info("Action: execute action '{0}':'{1}' manually :: emulate '{2}' event", evt.Name, evt.Caption, type); + cmd.Env.BuildType = BuildType.Common; //TODO: IBuild.updateBuildType try { bool res = cmd.exec(evt, type); Log.Info("Action: '{0}':'{1}' completed as - '{2}'", evt.Name, evt.Caption, res.ToString()); diff --git a/vsSolutionBuildEventTest/SBEScripts/Components/InternalComponentTest.cs b/vsSolutionBuildEventTest/SBEScripts/Components/InternalComponentTest.cs index 82313ae3..e17c7493 100644 --- a/vsSolutionBuildEventTest/SBEScripts/Components/InternalComponentTest.cs +++ b/vsSolutionBuildEventTest/SBEScripts/Components/InternalComponentTest.cs @@ -5,53 +5,111 @@ using net.r_eg.vsSBE.SBEScripts; using net.r_eg.vsSBE.SBEScripts.Components; using net.r_eg.vsSBE.SBEScripts.Exceptions; +using net.r_eg.vsSBE.Scripts; namespace net.r_eg.vsSBE.Test.SBEScripts.Components { - [TestClass()] + [TestClass] public class InternalComponentTest { + private IBootloader bootloader; + private IEnvironment env = new StubEnv(); + private IUserVariable uvariable = new UserVariable(); + + private IBootloader Loader + { + get { + if(bootloader == null) { + bootloader = new Bootloader(env, uvariable); + bootloader.register(); + } + return bootloader; + } + } + + [TestMethod] + public void eventsItemRunTest1() + { + var target = new InternalComponentAccessor(); + + try { + target.parse("[Core events.Pre.item(1).run]"); + Assert.Fail("1"); + } + catch(Exception ex) { Assert.IsTrue(ex.GetType() == typeof(IncorrectNodeException), ex.GetType().ToString()); } + + try { + target.parse("[Core events.Pre.item(1).run() = true]"); + Assert.Fail("2"); + } + catch(Exception ex) { Assert.IsTrue(ex.GetType() == typeof(NotSupportedOperationException), ex.GetType().ToString()); } + + try { + target.parse("[Core events.Pre.item(1).run(): true]"); + Assert.Fail("3"); + } + catch(Exception ex) { Assert.IsTrue(ex.GetType() == typeof(NotSupportedOperationException), ex.GetType().ToString()); } + + try { + target.parse("[Core events.Pre.item(1).run().m]"); + Assert.Fail("4"); + } + catch(Exception ex) { Assert.IsTrue(ex.GetType() == typeof(NotSupportedOperationException), ex.GetType().ToString()); } + } + + [TestMethod] + public void eventsItemRunTest2() + { + var target = new InternalComponentAccessor(); + Assert.AreEqual(Value.from(true), target.parse("[Core events.Pre.item(1).run()]")); + Assert.AreEqual(Value.from(true), target.parse("[Core events.Pre.item(1).run(Common)]")); + Assert.AreEqual(Value.from(false), target.parse("[Core events.Pre.item(2).run()]")); + Assert.AreEqual(Value.from(false), target.parse("[Core events.Pre.item(3).run()]")); + Assert.AreEqual(Value.from(false), target.parse("[Core events.Pre.item(3).run(Common)]")); + Assert.AreEqual(Value.from(true), target.parse("[Core events.Pre.item(3).run(Rebuild)]")); + } + /// ///A test for parse /// - [TestMethod()] + [TestMethod] [ExpectedException(typeof(SyntaxIncorrectException))] public void parseTest() { - InternalComponent target = new InternalComponent(new StubEnv()); + InternalComponent target = new InternalComponent(Loader); target.parse("#[vsSBE events.Type.item(1)]"); } /// ///A test for parse /// - [TestMethod()] + [TestMethod] [ExpectedException(typeof(SyntaxIncorrectException))] public void parseTest2() { - InternalComponent target = new InternalComponent(new StubEnv()); + InternalComponent target = new InternalComponent(Loader); target.parse("vsSBE events.Type.item(1)"); } /// ///A test for parse /// - [TestMethod()] + [TestMethod] [ExpectedException(typeof(SubtypeNotFoundException))] public void parseTest3() { - InternalComponent target = new InternalComponent(new StubEnv()); + InternalComponent target = new InternalComponent(Loader); target.parse("[vsSBE NoExist.Type]"); } /// ///A test for parse - stEvents /// - [TestMethod()] + [TestMethod] [ExpectedException(typeof(OperandNotFoundException))] public void stEventsParseTest1() { - InternalComponent target = new InternalComponent(new StubEnv()); + InternalComponent target = new InternalComponent(Loader); target.parse("[vsSBE events.Type.item(name)]"); } @@ -62,7 +120,7 @@ public void stEventsParseTest1() [ExpectedException(typeof(OperandNotFoundException))] public void stEventsParseTest2() { - InternalComponent target = new InternalComponent(new StubEnv()); + InternalComponent target = new InternalComponent(Loader); target.parse("[vsSBE events.Type.item(1).test]"); } @@ -142,7 +200,7 @@ public void pStatusParseTest3() [ExpectedException(typeof(IncorrectNodeException))] public void startUpProjectTest1() { - var target = new InternalComponent(new StubEnv()); + var target = new InternalComponent(Loader); target.parse("[Core StartUpProject: test]"); } @@ -242,12 +300,26 @@ protected override ISolutionEvent[] getEvent(SolutionEventType type) return evt; } - evt = new SBEEvent[2]{ + evt = new SBEEvent[3]{ + new SBEEvent(){ + Name = "Name1", + SupportMSBuild = false, + SupportSBEScripts = false, + Mode = new ModeFile() { Command = "" }, + Enabled = true + }, new SBEEvent(){ - Name = "Name1", Enabled = true + Name = "Name2", + Mode = new ModeFile() { Command = "" }, + Enabled = false }, new SBEEvent(){ - Name = "Name2", Enabled = false + Name = "Name3", + SupportMSBuild = false, + SupportSBEScripts = false, + BuildType = Bridge.BuildType.Rebuild, + Mode = new ModeFile() { Command = "" }, + Enabled = true } }; return evt;