@profoundlogic/codermake 1.0.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/lib/ssh.js CHANGED
@@ -1 +1 @@
1
- (function(_0x2c8f10,_0x2c8011){const _0x9b4e64=_0x3ce1,_0x2a0a15=_0x2c8f10();while(!![]){try{const _0x1126ca=parseInt(_0x9b4e64(0x174))/0x1+-parseInt(_0x9b4e64(0x16b))/0x2*(-parseInt(_0x9b4e64(0x190))/0x3)+parseInt(_0x9b4e64(0x188))/0x4*(-parseInt(_0x9b4e64(0x185))/0x5)+-parseInt(_0x9b4e64(0x171))/0x6+-parseInt(_0x9b4e64(0x170))/0x7+-parseInt(_0x9b4e64(0x193))/0x8+parseInt(_0x9b4e64(0x16d))/0x9*(parseInt(_0x9b4e64(0x178))/0xa);if(_0x1126ca===_0x2c8011)break;else _0x2a0a15['push'](_0x2a0a15['shift']());}catch(_0x4337b6){_0x2a0a15['push'](_0x2a0a15['shift']());}}}(_0x2c3a,0x5255e));function _0x2c3a(){const _0x130ffc=['l3nZAc0LqW','C29Tzq','wurWzgm','mJe5mtq3v3HqAuHR','BM93','uMLHD2S','mZKYodCWngzHu0jAyG','mtzesuvPz3m','u2vYDMvYqwXPDMvdB3vUDe1HEd0Z','mJe2tu9WqNjd','u3rYAwn0sg9ZDeTLEunOzwnRAw5Npw5V','D2PJr1i','nde4ndG4n2Hszxndta','mta4mtG3oe15ALziCa','ifbYzs1LC3rHyMXPC2HPBMCGu1niig1HC3rLCIbJB25Uzwn0Aw9UlI4U','ugfZC3DVCMrbDxrOzw50AwnHDgLVBJ1UBW','otC3m0XTrfrwEq','ifntscbTyxn0zxiGywXYzwfKEsbLEgLZDhmSihjLDxnPBMC','C3rHCNrZv2L0Aa','r2rQtNO','nJi5mdyWr0LbEujb','u1niig1HC3rLCIbLEgL0zwqGD2L0AcbJB2rLia','w3nZAf0','ChvZAa','zNjgse0','Bg9N','u2vYDMvYqwXPDMvjBNrLCNzHBd02ma','C3nO','zgv0ywnOzwq','AwDUB3jL','A3rKtNa','s254sxK','ifntscbTyxn0zxiGzxn0ywjSAxnOzwq','otiXmtvYANnVExa','C3nOlq','shPVrLa','mta4AwzSsw5g','wMjHBNC','q29UDhjVBfbHDgG9','q3Lwr28','vwvSCNe'];_0x2c3a=function(){return _0x130ffc;};return _0x2c3a();}import{spawn}from'child_process';import{readdirSync}from'fs';async function waitForSSHSocket(_0x59b38a,_0x4a6ee3,_0x227a66=0x3a98){const _0x58a069={'HzoFP':function(_0x3da1e6,_0x5b45a1){return _0x3da1e6!==_0x5b45a1;},'ktdNp':function(_0x1123b3,_0x39e1be){return _0x1123b3(_0x39e1be);},'GdjNz':function(_0x5711aa,_0xd48051){return _0x5711aa>=_0xd48051;},'Riawk':function(_0xafa9d0,_0x3302dd){return _0xafa9d0-_0x3302dd;},'CyVGo':'exit'};return new Promise((_0x1ebaea,_0x21944b)=>{const _0xab963b=_0x3ce1;let _0x172d5d=![],_0x1a9384=null;_0x4a6ee3['on'](_0x58a069[_0xab963b(0x18b)],_0x5bbe8d=>{const _0x2dc1a1=_0xab963b;_0x1a9384=_0x5bbe8d,!_0x172d5d&&_0x58a069[_0x2dc1a1(0x187)](_0x5bbe8d,0x0)&&(_0x172d5d=!![],_0x58a069[_0x2dc1a1(0x182)](_0x21944b,new Error(_0x2dc1a1(0x179)+_0x5bbe8d)));});const _0x29ec04=Date['now'](),_0x146479=()=>{const _0x1eb06d=_0xab963b;if(_0x172d5d)return;const _0x1d2c27=_0x58a069[_0x1eb06d(0x182)](readdirSync,_0x59b38a);if(_0x1d2c27[_0x1eb06d(0x18e)](_0x151a7e=>_0x151a7e[_0x1eb06d(0x176)](_0x1eb06d(0x186)))){_0x172d5d=!![],_0x1ebaea();return;}if(_0x58a069[_0x1eb06d(0x177)](_0x58a069[_0x1eb06d(0x192)](Date[_0x1eb06d(0x191)](),_0x29ec04),_0x227a66)){_0x172d5d=!![];const _0x32f1f1=_0x1a9384!==null?'\x20(process\x20exited\x20with\x20code\x20'+_0x1a9384+')':'';_0x21944b(new Error('SSH\x20master\x20did\x20not\x20start\x20within\x20'+_0x227a66+'ms'+_0x32f1f1));return;}setTimeout(_0x146479,0x64);};_0x146479();});}function _0x3ce1(_0x272db7,_0x54f42b){_0x272db7=_0x272db7-0x16b;const _0x2c3ac2=_0x2c3a();let _0x3ce139=_0x2c3ac2[_0x272db7];if(_0x3ce1['IITldX']===undefined){var _0xcde3d7=function(_0x1b28c3){const _0x4e37ee='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x27f540='',_0x31287b='';for(let _0x5d311b=0x0,_0x31371d,_0x1fdbf0,_0x3d45c5=0x0;_0x1fdbf0=_0x1b28c3['charAt'](_0x3d45c5++);~_0x1fdbf0&&(_0x31371d=_0x5d311b%0x4?_0x31371d*0x40+_0x1fdbf0:_0x1fdbf0,_0x5d311b++%0x4)?_0x27f540+=String['fromCharCode'](0xff&_0x31371d>>(-0x2*_0x5d311b&0x6)):0x0){_0x1fdbf0=_0x4e37ee['indexOf'](_0x1fdbf0);}for(let _0x2d8424=0x0,_0x2727a8=_0x27f540['length'];_0x2d8424<_0x2727a8;_0x2d8424++){_0x31287b+='%'+('00'+_0x27f540['charCodeAt'](_0x2d8424)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x31287b);};_0x3ce1['EgQBeJ']=_0xcde3d7,_0x3ce1['GoQlGo']={},_0x3ce1['IITldX']=!![];}const _0x1a3e50=_0x2c3ac2[0x0],_0x1aaacc=_0x272db7+_0x1a3e50,_0x36900f=_0x3ce1['GoQlGo'][_0x1aaacc];return!_0x36900f?(_0x3ce139=_0x3ce1['EgQBeJ'](_0x3ce139),_0x3ce1['GoQlGo'][_0x1aaacc]=_0x3ce139):_0x3ce139=_0x36900f,_0x3ce139;}export async function establishSSHMaster(_0x3492ca,_0x21d965={}){const _0x3d0493=_0x3ce1,_0xdd1fd7={'Uelrq':_0x3d0493(0x17a),'wjcGR':function(_0x3afeb3,_0x20ea64){return _0x3afeb3(_0x20ea64);},'YDpdc':'ControlMaster=yes','KnxIy':_0x3d0493(0x16e),'CfPfE':_0x3d0493(0x173),'frFHM':_0x3d0493(0x17e),'Zbanw':_0x3d0493(0x16c)},{host:_0x3c69cf,user:_0x3692b3,sshKey:_0x433f3a,debug:debug=![],debugPrefix:debugPrefix=_0xdd1fd7[_0x3d0493(0x18c)]}=_0x21d965;if(!_0x3c69cf||!_0x3692b3)return;const _0x327f40=_0xdd1fd7[_0x3d0493(0x16f)](readdirSync,_0x3492ca);if(_0x327f40[_0x3d0493(0x18e)](_0x25580e=>_0x25580e['startsWith'](_0x3d0493(0x186)))){if(debug)console['log'](debugPrefix+_0x3d0493(0x175));return;}if(debug)console[_0x3d0493(0x17d)](debugPrefix+_0x3d0493(0x172));const _0x229819=['-o',_0xdd1fd7[_0x3d0493(0x18f)],'-o',_0x3d0493(0x18a)+_0x3492ca+_0x3d0493(0x18d),'-o','ControlPersist=10m','-o',_0xdd1fd7[_0x3d0493(0x183)],'-o',_0xdd1fd7['CfPfE'],'-o',_0xdd1fd7[_0x3d0493(0x17c)],'-o',_0xdd1fd7[_0x3d0493(0x189)],'-N','-f'];_0x433f3a&&_0x229819['push']('-i',_0x433f3a);_0x229819[_0x3d0493(0x17b)](_0x3692b3+'@'+_0x3c69cf);const _0x98b9f2={};_0x98b9f2[_0x3d0493(0x180)]=!![],_0x98b9f2['stdio']=_0x3d0493(0x181);const _0x2995d7=spawn(_0x3d0493(0x17f),_0x229819,_0x98b9f2);_0x2995d7['unref'](),await waitForSSHSocket(_0x3492ca,_0x2995d7,0x3a98);if(debug)console[_0x3d0493(0x17d)](debugPrefix+_0x3d0493(0x184));}
1
+ (function(_0x18125d,_0x270cc3){const _0x176d8b=_0x4a16,_0x59aec6=_0x18125d();while(!![]){try{const _0x1e3612=parseInt(_0x176d8b(0x82))/0x1*(-parseInt(_0x176d8b(0x90))/0x2)+parseInt(_0x176d8b(0x84))/0x3+-parseInt(_0x176d8b(0x97))/0x4+parseInt(_0x176d8b(0x9a))/0x5*(-parseInt(_0x176d8b(0x8f))/0x6)+parseInt(_0x176d8b(0xa5))/0x7+parseInt(_0x176d8b(0x8b))/0x8+-parseInt(_0x176d8b(0x99))/0x9*(parseInt(_0x176d8b(0x9c))/0xa);if(_0x1e3612===_0x270cc3)break;else _0x59aec6['push'](_0x59aec6['shift']());}catch(_0x1655cb){_0x59aec6['push'](_0x59aec6['shift']());}}}(_0x1134,0xc5161));import{spawn}from'child_process';function _0x4a16(_0x545da7,_0xd86be0){_0x545da7=_0x545da7-0x82;const _0x113404=_0x1134();let _0x4a1616=_0x113404[_0x545da7];if(_0x4a16['lZkDfE']===undefined){var _0x48a793=function(_0x531d57){const _0x3e0d2f='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x55eb1f='',_0xc4e4c7='';for(let _0x499b66=0x0,_0x566792,_0x2d79b2,_0x2ce749=0x0;_0x2d79b2=_0x531d57['charAt'](_0x2ce749++);~_0x2d79b2&&(_0x566792=_0x499b66%0x4?_0x566792*0x40+_0x2d79b2:_0x2d79b2,_0x499b66++%0x4)?_0x55eb1f+=String['fromCharCode'](0xff&_0x566792>>(-0x2*_0x499b66&0x6)):0x0){_0x2d79b2=_0x3e0d2f['indexOf'](_0x2d79b2);}for(let _0x15bd03=0x0,_0x47dc9a=_0x55eb1f['length'];_0x15bd03<_0x47dc9a;_0x15bd03++){_0xc4e4c7+='%'+('00'+_0x55eb1f['charCodeAt'](_0x15bd03)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0xc4e4c7);};_0x4a16['aRVuXc']=_0x48a793,_0x4a16['LLGhsk']={},_0x4a16['lZkDfE']=!![];}const _0x511c27=_0x113404[0x0],_0x9b82e5=_0x545da7+_0x511c27,_0x3bf413=_0x4a16['LLGhsk'][_0x9b82e5];return!_0x3bf413?(_0x4a1616=_0x4a16['aRVuXc'](_0x4a1616),_0x4a16['LLGhsk'][_0x9b82e5]=_0x4a1616):_0x4a1616=_0x3bf413,_0x4a1616;}import{readdirSync}from'fs';function _0x1134(){const _0x5d0ae7=['svHerxy','A1HUA1i','ndq0ndeWnfjqz2vvtq','u1niig1HC3rLCIbLEgL0zwqGD2L0AcbJB2rLia','mJmWBvDHq3v1','sfDRBfK','mJeXmZy5mNbzAMjuwG','q29UDhjVBfbLCNnPC3q9mtbT','C3rKAw8','t3L5A2y','ChvZAa','q29UDhjVBfbHDgG9','zwrUtwC','nJe3ntu4ngXzq2Hcua','q29UDhjVBe1HC3rLCJ15zxm','w3nZAf0','yLnTvMe','mJrWvfnKAhG','mJe5mKjXzKPbDq','C3rHCNrZv2L0Aa','u2vYDMvYqwXPDMvjBNrLCNzHBd02ma','u3rYAwn0sg9ZDeTLEunOzwnRAw5Npw5V','C29Tzq','thLyA2W','C3nO','ntC4ndKYvhjXtK9q','BM93','mJy2otrpzgTtBLq','otyZnZi1BwjSuhDK','C3nOlq','ndyWCerdzhbx','Bg9N','Dw5Yzwy','u1niig1HC3rLCIbKAwqGBM90ihn0yxj0ihDPDgHPBIa','ifbYzs1LC3rHyMXPC2HPBMCGu1niig1HC3rLCIbJB25Uzwn0Aw9UlI4U','qM15EvK','ifntscbTyxn0zxiGywXYzwfKEsbLEgLZDhmSihjLDxnPBMC'];_0x1134=function(){return _0x5d0ae7;};return _0x1134();}async function waitForSSHSocket(_0x4359c9,_0x2ffd48,_0x25829d=0x3a98){const _0x131779={'LyXkl':function(_0x208f13,_0x25ebc0){return _0x208f13(_0x25ebc0);}};return new Promise((_0x23165c,_0x56dd01)=>{const _0xd996b={'BmyyY':function(_0x56de98,_0x37b50e){return _0x56de98(_0x37b50e);},'ednMg':function(_0x28c633,_0x8c2a36){return _0x28c633(_0x8c2a36);}};let _0x3178b=![],_0x18bcf0=null;_0x2ffd48['on']('exit',_0x446f2e=>{const _0x39a74b=_0x4a16;_0x18bcf0=_0x446f2e,!_0x3178b&&_0x446f2e!==0x0&&(_0x3178b=!![],_0x131779[_0x39a74b(0x95)](_0x56dd01,new Error(_0x39a74b(0xa6)+_0x446f2e)));});const _0x5f1a00=Date['now'](),_0x46b05e=()=>{const _0x51f8f9=_0x4a16;if(_0x3178b)return;const _0x5ab76d=_0xd996b[_0x51f8f9(0xa1)](readdirSync,_0x4359c9);if(_0x5ab76d['some'](_0xd506dd=>_0xd506dd[_0x51f8f9(0x91)](_0x51f8f9(0x9b)))){_0x3178b=!![],_0x23165c();return;}if(Date[_0x51f8f9(0x98)]()-_0x5f1a00>=_0x25829d){_0x3178b=!![];const _0x14ff01=_0x18bcf0!==null?'\x20(process\x20exited\x20with\x20code\x20'+_0x18bcf0+')':'';_0xd996b[_0x51f8f9(0x8a)](_0x56dd01,new Error(_0x51f8f9(0x9f)+_0x25829d+'ms'+_0x14ff01));return;}setTimeout(_0x46b05e,0x64);};_0x46b05e();});}export async function establishSSHMaster(_0x39faa4,_0x3d572c={}){const _0x10cd18=_0x4a16,_0x3edcf2={'XIeiU':function(_0x1f68e5,_0x4cb9d7){return _0x1f68e5||_0x4cb9d7;},'bSmVa':function(_0x50c1eb,_0x8d4423){return _0x50c1eb(_0x8d4423);},'IXDEv':_0x10cd18(0x85),'HdQwW':_0x10cd18(0x93),'Oyykf':'PasswordAuthentication=no','HWklY':_0x10cd18(0x92),'kXnkR':function(_0xa3ac75,_0x4fdf07,_0x3a3936,_0x245499){return _0xa3ac75(_0x4fdf07,_0x3a3936,_0x245499);},'xscBn':_0x10cd18(0x96)},{host:_0xb606a5,user:_0x3e2be6,sshKey:_0x5cad59,debug:debug=![],debugPrefix:debugPrefix=_0x10cd18(0x8d)}=_0x3d572c;if(_0x3edcf2['XIeiU'](!_0xb606a5,!_0x3e2be6))return;const _0x489535=_0x3edcf2[_0x10cd18(0x8e)](readdirSync,_0x39faa4);if(_0x489535[_0x10cd18(0x94)](_0x2f8864=>_0x2f8864[_0x10cd18(0x91)](_0x10cd18(0x9b)))){if(debug)console['log'](debugPrefix+_0x10cd18(0xa2));return;}if(debug)console[_0x10cd18(0x9d)](debugPrefix+_0x10cd18(0xa0));const _0x116320=['-o',_0x10cd18(0x8c),'-o',_0x10cd18(0x89)+_0x39faa4+'/ssh-%C','-o',_0x3edcf2[_0x10cd18(0xa3)],'-o',_0x3edcf2['HdQwW'],'-o',_0x3edcf2[_0x10cd18(0x87)],'-o',_0x3edcf2[_0x10cd18(0x83)],'-o','ServerAliveCountMax=3','-N','-f'];_0x5cad59&&_0x116320[_0x10cd18(0x88)]('-i',_0x5cad59);_0x116320['push'](_0x3e2be6+'@'+_0xb606a5);const _0x5093aa={};_0x5093aa['detached']=!![],_0x5093aa[_0x10cd18(0x86)]='ignore';const _0x35d0f6=_0x3edcf2[_0x10cd18(0xa4)](spawn,_0x3edcf2['xscBn'],_0x116320,_0x5093aa);_0x35d0f6[_0x10cd18(0x9e)](),await _0x3edcf2['kXnkR'](waitForSSHSocket,_0x39faa4,_0x35d0f6,0x3a98);if(debug)console[_0x10cd18(0x9d)](debugPrefix+'\x20SSH\x20master\x20established');}
@@ -1 +1 @@
1
- (function(_0x5e5d53,_0x432775){const _0x16e5e2=_0x325f,_0xf5475e=_0x5e5d53();while(!![]){try{const _0x2ea922=parseInt(_0x16e5e2(0xd8))/0x1*(parseInt(_0x16e5e2(0xee))/0x2)+parseInt(_0x16e5e2(0xd7))/0x3+parseInt(_0x16e5e2(0xdc))/0x4+-parseInt(_0x16e5e2(0xe3))/0x5*(parseInt(_0x16e5e2(0xeb))/0x6)+parseInt(_0x16e5e2(0xf0))/0x7+-parseInt(_0x16e5e2(0xe2))/0x8+-parseInt(_0x16e5e2(0xe9))/0x9;if(_0x2ea922===_0x432775)break;else _0xf5475e['push'](_0xf5475e['shift']());}catch(_0x15f710){_0xf5475e['push'](_0xf5475e['shift']());}}}(_0x2f72,0x36b0e));function _0x325f(_0x202516,_0x142cb7){_0x202516=_0x202516-0xd6;const _0x2f72fc=_0x2f72();let _0x325f6c=_0x2f72fc[_0x202516];if(_0x325f['jLbZWH']===undefined){var _0x182a94=function(_0x54beb7){const _0x42a87f='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x25c2e6='',_0x3475c9='';for(let _0x197012=0x0,_0x1dc2e4,_0x2b15bf,_0x1f1baf=0x0;_0x2b15bf=_0x54beb7['charAt'](_0x1f1baf++);~_0x2b15bf&&(_0x1dc2e4=_0x197012%0x4?_0x1dc2e4*0x40+_0x2b15bf:_0x2b15bf,_0x197012++%0x4)?_0x25c2e6+=String['fromCharCode'](0xff&_0x1dc2e4>>(-0x2*_0x197012&0x6)):0x0){_0x2b15bf=_0x42a87f['indexOf'](_0x2b15bf);}for(let _0x231d6b=0x0,_0x23752b=_0x25c2e6['length'];_0x231d6b<_0x23752b;_0x231d6b++){_0x3475c9+='%'+('00'+_0x25c2e6['charCodeAt'](_0x231d6b)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x3475c9);};_0x325f['rPPckx']=_0x182a94,_0x325f['ruEVle']={},_0x325f['jLbZWH']=!![];}const _0xbcfdef=_0x2f72fc[0x0],_0x58e6a0=_0x202516+_0xbcfdef,_0x5a7cdf=_0x325f['ruEVle'][_0x58e6a0];return!_0x5a7cdf?(_0x325f6c=_0x325f['rPPckx'](_0x325f6c),_0x325f['ruEVle'][_0x58e6a0]=_0x325f6c):_0x325f6c=_0x5a7cdf,_0x325f6c;}import{writeFileSync,mkdirSync,existsSync}from'fs';import{join}from'path';import{randomUUID}from'crypto';import{tmpdir}from'os';function _0x2f72(){const _0x5a0f32=['nJeYndCYAKrZBLns','DgfYz2v0CY5TAW','yKjVruy','zhPUB1a','vKPZzfK','CNvSzxngAwXL','mtKWnJq1nMPAvgTVyq','nu56s0XSza','DgfYz2v0C0zPBgu','ENjSzvq','t1zcweO','AM9PBG','Dg1WrgLY','mJuXmteZnwDwwfrSqW','CfPquLC','ntyZmJy4z1H3zfLe','Aw5drKu','DxrMoa','mJbwDhzyC0i','y20T','mJC1nZq2mvztEMrrqW','C3rYAw5NAwz5','nty1ndC5veXKv1ny','otK2ogHIt3vQBW','DgfYz2v0lw1HChbPBMCUANnVBG','CMvJDxjZAxzL','vefsr0vuuYa6psa'];_0x2f72=function(){return _0x5a0f32;};return _0x2f72();}function ensureDir(_0x553d0c){const _0x57dd4c=_0x325f;if(!existsSync(_0x553d0c)){const _0x1d8726={};_0x1d8726[_0x57dd4c(0xda)]=!![],mkdirSync(_0x553d0c,_0x1d8726);}}export function writeRules(_0x37b1c5,_0x1138cb,_0x4a125e={},_0x1a99a4=null){const _0x43c1bb=_0x325f,_0x1ef487={'zrleT':function(_0x2c073e){return _0x2c073e();},'OVBXJ':function(_0x3d6ddd,_0x12cf80,_0x450458){return _0x3d6ddd(_0x12cf80,_0x450458);},'pZPRW':_0x43c1bb(0xdd),'dznoP':function(_0x3b27fb,_0x35fee9,_0x257e27){return _0x3b27fb(_0x35fee9,_0x257e27);},'bBoEF':function(_0x4d08bd,_0x19158a){return _0x4d08bd+_0x19158a;},'inCFE':_0x43c1bb(0xed),'VJsdY':function(_0x51f661,_0x4174c4,_0x2c3639,_0x2fa5ab){return _0x51f661(_0x4174c4,_0x2c3639,_0x2fa5ab);}};if(!_0x1a99a4){const _0x3baa4d=randomUUID()['replace'](/-/g,'');_0x1a99a4=join(_0x1ef487[_0x43c1bb(0xe5)](tmpdir),_0x43c1bb(0xef)+_0x3baa4d);}ensureDir(_0x1a99a4);const _0x10902d=_0x1ef487[_0x43c1bb(0xe6)](join,_0x1a99a4,'rules.mk'),_0x29394f=join(_0x1a99a4,_0x1ef487[_0x43c1bb(0xea)]),_0x935756=_0x1ef487[_0x43c1bb(0xdf)](join,_0x1a99a4,_0x43c1bb(0xd9)),_0x4bb048=_0x1ef487[_0x43c1bb(0xde)](_0x37b1c5['join']('\x0a'),'\x0a');writeFileSync(_0x10902d,_0x4bb048,_0x1ef487[_0x43c1bb(0xec)]);const _0x52f2f9=_0x43c1bb(0xdb)+_0x1138cb[_0x43c1bb(0xe7)]('\x20')+'\x0a';_0x1ef487[_0x43c1bb(0xe0)](writeFileSync,_0x29394f,_0x52f2f9,_0x43c1bb(0xed));const _0x106870=JSON[_0x43c1bb(0xd6)](_0x4a125e,null,0x2);_0x1ef487[_0x43c1bb(0xe0)](writeFileSync,_0x935756,_0x106870,_0x43c1bb(0xed));const _0x253e2d={};return _0x253e2d[_0x43c1bb(0xe1)]=_0x10902d,_0x253e2d[_0x43c1bb(0xe4)]=_0x29394f,_0x253e2d['mappingFile']=_0x935756,_0x253e2d[_0x43c1bb(0xe8)]=_0x1a99a4,_0x253e2d;}
1
+ function _0x5bc5(){const _0x2ed8ca=['DxrMoa','CNvSzxmUBwS','mwrhtLbOqq','DgfYz2v0lw1HChbPBMCUANnVBG','CMvWBgfJzq','ota2r0LPDxvb','sNj3DNe','B05nBfG','B1ztvvu','Cg5bDvO','vefsr0vuuYa6psa','mtG1otu0mgPvzgLbva','ndq3nJG4mfLLu3rTsW','mtG4otn2AgrNswW','BwfWCgLUz0zPBgu','AM9PBG','nZy4nJuWB1nVEKPL','CNvSzxngAwXL','ntC0odGXuxnkAKrs','mZeXmZm0CM9ZzKjp','Dg1WrgLY','CMXzu2O','CLzbwNK','ENzivvq','DgfYz2v0CY5TAW','mtq1nZCWnJzRAM1Kyva','CMvJDxjZAxzL','C3rYAw5NAwz5','DgfYz2v0C0zPBgu'];_0x5bc5=function(){return _0x2ed8ca;};return _0x5bc5();}(function(_0x2f9a22,_0x4a9238){const _0xfc7212=_0x3ff9,_0x31f554=_0x2f9a22();while(!![]){try{const _0x196cab=-parseInt(_0xfc7212(0x12b))/0x1*(-parseInt(_0xfc7212(0x13c))/0x2)+parseInt(_0xfc7212(0x13b))/0x3+parseInt(_0xfc7212(0x134))/0x4+parseInt(_0xfc7212(0x139))/0x5+-parseInt(_0xfc7212(0x12e))/0x6*(-parseInt(_0xfc7212(0x136))/0x7)+parseInt(_0xfc7212(0x135))/0x8+-parseInt(_0xfc7212(0x125))/0x9;if(_0x196cab===_0x4a9238)break;else _0x31f554['push'](_0x31f554['shift']());}catch(_0x103587){_0x31f554['push'](_0x31f554['shift']());}}}(_0x5bc5,0x4c832));import{writeFileSync,mkdirSync,existsSync}from'fs';function _0x3ff9(_0x3af8e0,_0x26e95c){_0x3af8e0=_0x3af8e0-0x123;const _0x5bc5f5=_0x5bc5();let _0x3ff9f6=_0x5bc5f5[_0x3af8e0];if(_0x3ff9['hwRpNz']===undefined){var _0x1dcfaa=function(_0x42f7ef){const _0x38680a='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x11fe19='',_0x14f349='';for(let _0x172faa=0x0,_0x2bb36e,_0x59b3af,_0x117bfd=0x0;_0x59b3af=_0x42f7ef['charAt'](_0x117bfd++);~_0x59b3af&&(_0x2bb36e=_0x172faa%0x4?_0x2bb36e*0x40+_0x59b3af:_0x59b3af,_0x172faa++%0x4)?_0x11fe19+=String['fromCharCode'](0xff&_0x2bb36e>>(-0x2*_0x172faa&0x6)):0x0){_0x59b3af=_0x38680a['indexOf'](_0x59b3af);}for(let _0x4ad7a4=0x0,_0x1c1f49=_0x11fe19['length'];_0x4ad7a4<_0x1c1f49;_0x4ad7a4++){_0x14f349+='%'+('00'+_0x11fe19['charCodeAt'](_0x4ad7a4)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x14f349);};_0x3ff9['bFryPL']=_0x1dcfaa,_0x3ff9['BCJVFQ']={},_0x3ff9['hwRpNz']=!![];}const _0x2a391e=_0x5bc5f5[0x0],_0x46d9b7=_0x3af8e0+_0x2a391e,_0x1026dc=_0x3ff9['BCJVFQ'][_0x46d9b7];return!_0x1026dc?(_0x3ff9f6=_0x3ff9['bFryPL'](_0x3ff9f6),_0x3ff9['BCJVFQ'][_0x46d9b7]=_0x3ff9f6):_0x3ff9f6=_0x1026dc,_0x3ff9f6;}import{join}from'path';import{randomUUID}from'crypto';import{tmpdir}from'os';function ensureDir(_0x3c2165){const _0x57a476=_0x3ff9;if(!existsSync(_0x3c2165)){const _0x4d121c={};_0x4d121c[_0x57a476(0x126)]=!![],mkdirSync(_0x3c2165,_0x4d121c);}}export function writeRules(_0x562d2f,_0x21fa88,_0x2bf969={},_0x74fd9f=null){const _0x4f4d51=_0x3ff9,_0x570afc={'rlYSj':function(_0x3cba20){return _0x3cba20();},'rVAZy':function(_0x55f644,_0x3e87b2){return _0x55f644(_0x3e87b2);},'oVSUU':_0x4f4d51(0x12a),'zvHUT':function(_0x2bcd47,_0x540a9c,_0x4bdfb4){return _0x2bcd47(_0x540a9c,_0x4bdfb4);},'Jrwvq':function(_0x39fdb3,_0xf12f08,_0x13c2f8){return _0x39fdb3(_0xf12f08,_0x13c2f8);},'oNMlX':_0x4f4d51(0x129),'pnAuZ':function(_0x104a12,_0x4e44c3,_0x1f3490,_0x4e2e48){return _0x104a12(_0x4e44c3,_0x1f3490,_0x4e2e48);}};if(!_0x74fd9f){const _0x311ad5=randomUUID()[_0x4f4d51(0x12d)](/-/g,'');_0x74fd9f=join(_0x570afc[_0x4f4d51(0x13e)](tmpdir),'cm-'+_0x311ad5);}_0x570afc[_0x4f4d51(0x13f)](ensureDir,_0x74fd9f);const _0x574a1d=join(_0x74fd9f,_0x570afc[_0x4f4d51(0x131)]),_0x147ec0=_0x570afc[_0x4f4d51(0x123)](join,_0x74fd9f,_0x4f4d51(0x124)),_0x55fca2=_0x570afc[_0x4f4d51(0x12f)](join,_0x74fd9f,_0x4f4d51(0x12c)),_0x160a9f=_0x562d2f[_0x4f4d51(0x138)]('\x0a')+'\x0a';writeFileSync(_0x574a1d,_0x160a9f,_0x570afc[_0x4f4d51(0x130)]);const _0x495c0b=_0x4f4d51(0x133)+_0x21fa88[_0x4f4d51(0x138)]('\x20')+'\x0a';writeFileSync(_0x147ec0,_0x495c0b,_0x4f4d51(0x129));const _0x522a3b=JSON[_0x4f4d51(0x127)](_0x2bf969,null,0x2);_0x570afc[_0x4f4d51(0x132)](writeFileSync,_0x55fca2,_0x522a3b,_0x570afc[_0x4f4d51(0x130)]);const _0x1e0d7a={};return _0x1e0d7a[_0x4f4d51(0x13a)]=_0x574a1d,_0x1e0d7a[_0x4f4d51(0x128)]=_0x147ec0,_0x1e0d7a[_0x4f4d51(0x137)]=_0x55fca2,_0x1e0d7a[_0x4f4d51(0x13d)]=_0x74fd9f,_0x1e0d7a;}
@@ -85,28 +85,50 @@ $(LIBRARY_PATH):
85
85
  define BUILD_RPGLE_PGM
86
86
  $(call SETUP_LOG,$(notdir $@))
87
87
  $(SET_LIBL)
88
- system "crtbndrpg pgm($(LIBRARY)/$(basename $(@F))) srcstmf('$<') incdir('src') tgtccsid(*job) output(*print) dbgview(*all)"
88
+ system "crtbndrpg pgm($(LIBRARY)/$(basename $(@F))) srcstmf('$<') incdir('.') tgtccsid(*job) output(*print) dbgview(*all)"
89
89
  endef
90
90
 
91
91
  # Build SQL RPGLE program
92
92
  define BUILD_SQLRPGLE_PGM
93
93
  $(call SETUP_LOG,$(notdir $@))
94
94
  $(SET_LIBL)
95
- system "crtsqlrpgi obj($(LIBRARY)/$(basename $(@F))) objtype(*pgm) srcstmf('$<') cvtccsid(*job) output(*print) rpgppopt(*lvl1) compileopt('incdir(''src'') tgtccsid(*job) output(*print)') dbgview(*source)"
95
+ system "crtsqlrpgi obj($(LIBRARY)/$(basename $(@F))) objtype(*pgm) srcstmf('$<') cvtccsid(*job) output(*print) rpgppopt(*lvl1) compileopt('incdir(''.'') tgtccsid(*job) output(*print)') dbgview(*source)"
96
96
  endef
97
97
 
98
98
  # Build RPGLE module
99
99
  define BUILD_RPGLE_MODULE
100
100
  $(call SETUP_LOG,$(notdir $@))
101
101
  $(SET_LIBL)
102
- system "crtrpgmod module($(LIBRARY)/$(basename $(@F))) srcstmf('$<') incdir('src') tgtccsid(*job) output(*print) dbgview(*all)"
102
+ system "crtrpgmod module($(LIBRARY)/$(basename $(@F))) srcstmf('$<') incdir('.') tgtccsid(*job) output(*print) dbgview(*all)"
103
103
  endef
104
104
 
105
105
  # Build SQL RPGLE module
106
106
  define BUILD_SQLRPGLE_MODULE
107
107
  $(call SETUP_LOG,$(notdir $@))
108
108
  $(SET_LIBL)
109
- system "crtsqlrpgi obj($(LIBRARY)/$(basename $(@F))) objtype(*module) srcstmf('$<') cvtccsid(*job) output(*print) rpgppopt(*lvl1) compileopt('incdir(''src'') tgtccsid(*job) output(*print)') dbgview(*source)"
109
+ system "crtsqlrpgi obj($(LIBRARY)/$(basename $(@F))) objtype(*module) srcstmf('$<') cvtccsid(*job) output(*print) rpgppopt(*lvl1) compileopt('incdir(''.'') tgtccsid(*job) output(*print)') dbgview(*source)"
110
+ endef
111
+
112
+ # Build ILE CL program (bound)
113
+ define BUILD_CLLE_PGM
114
+ $(call SETUP_LOG,$(notdir $@))
115
+ $(SET_LIBL)
116
+ system "crtbndcl pgm($(LIBRARY)/$(basename $(@F))) srcstmf('$<') incdir('.') tgtccsid(*job) output(*print) dbgview(*all)"
117
+ endef
118
+
119
+ # Build OPM CL program
120
+ define BUILD_CLP_PGM
121
+ $(call SETUP_LOG,$(notdir $@))
122
+ $(call CREATE_SOURCE_MEMBER,$<,qclsrc)
123
+ $(SET_LIBL)
124
+ system "crtclpgm pgm($(LIBRARY)/$(basename $(@F))) srcfile($(LIBRARY)/qclsrc) output(*print)"
125
+ endef
126
+
127
+ # Build ILE CL module
128
+ define BUILD_CLLE_MODULE
129
+ $(call SETUP_LOG,$(notdir $@))
130
+ $(SET_LIBL)
131
+ system "crtclmod module($(LIBRARY)/$(basename $(@F))) srcstmf('$<') incdir('.') tgtccsid(*job) output(*print) dbgview(*all)"
110
132
  endef
111
133
 
112
134
  # Build program from modules
@@ -157,6 +179,35 @@ $(SET_LIBL)
157
179
  system "crtlf file($(LIBRARY)/$(basename $(@F))) srcfile($(LIBRARY)/qddssrc)"
158
180
  endef
159
181
 
182
+ # Build printer file
183
+ define BUILD_PRTF_TO_FILE
184
+ $(call SETUP_LOG,$(notdir $@))
185
+ $(call CREATE_SOURCE_MEMBER,$<,qddssrc)
186
+ $(SET_LIBL)
187
+ system "crtprtf file($(LIBRARY)/$(basename $(@F))) srcfile($(LIBRARY)/qddssrc)"
188
+ endef
189
+
190
+ # Build SQL table
191
+ define BUILD_SQLTABLE_TO_FILE
192
+ $(call SETUP_LOG,$(notdir $@))
193
+ $(SET_LIBL)
194
+ system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(LIBRARY))"
195
+ endef
196
+
197
+ # Build SQL index
198
+ define BUILD_SQLINDEX_TO_FILE
199
+ $(call SETUP_LOG,$(notdir $@))
200
+ $(SET_LIBL)
201
+ system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(LIBRARY))"
202
+ endef
203
+
204
+ # Build SQL procedure
205
+ define BUILD_SQLPROC_TO_PGM
206
+ $(call SETUP_LOG,$(notdir $@))
207
+ $(SET_LIBL)
208
+ system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(LIBRARY))"
209
+ endef
210
+
160
211
  # Build message file from CL commands
161
212
  define BUILD_MSGF
162
213
  $(call SETUP_LOG,$(notdir $@))
@@ -182,7 +233,13 @@ endef
182
233
  .PHONY: platform-clean
183
234
  platform-clean:
184
235
  @if [ -n "$(TARGETS)" ] && [ -d $(LIBRARY_PATH) ]; then
185
- for target in $(TARGETS); do
186
- rm -rf "$$target"
236
+ for pass in 1 2; do
237
+ for target in $(TARGETS); do
238
+ if [ "$${target%.file}" != "$$target" ]; then
239
+ (system "dltf $(LIBRARY)/$$(basename $$target .file)" > /dev/null 2>&1) || true
240
+ else
241
+ rm -rf "$$target"
242
+ fi
243
+ done
187
244
  done
188
245
  fi
@@ -183,6 +183,31 @@ $(call REMOTE_BUILD,$(filter-out build/%,$^),system "crtsqlrpgi obj($(LIBRARY)/$
183
183
  touch '$@'
184
184
  endef
185
185
 
186
+ # Build ILE CL program (bound)
187
+ define BUILD_CLLE_PGM
188
+ $(call SETUP_LOG,$(notdir $@))
189
+ $(call REMOTE_BUILD,$(filter-out build/%,$^),system "crtbndcl pgm($(LIBRARY)/$(basename $(@F))) srcstmf('$<') incdir('.') tgtccsid(*job) output(*print) dbgview(*all)")
190
+ touch '$@'
191
+ endef
192
+
193
+ # Build OPM CL program
194
+ define BUILD_CLP_PGM
195
+ $(call SETUP_LOG,$(notdir $@))
196
+ $(call CREATE_SOURCE_MEMBER,$<,qclsrc)
197
+ $(SSH) $(QSHELL) <<'EOF'
198
+ $(SET_LIBL)
199
+ system "crtclpgm pgm($(LIBRARY)/$(basename $(@F))) srcfile($(LIBRARY)/qclsrc) output(*print)"
200
+ EOF
201
+ touch '$@'
202
+ endef
203
+
204
+ # Build ILE CL module
205
+ define BUILD_CLLE_MODULE
206
+ $(call SETUP_LOG,$(notdir $@))
207
+ $(call REMOTE_BUILD,$(filter-out build/%,$^),system "crtclmod module($(LIBRARY)/$(basename $(@F))) srcstmf('$<') incdir('.') tgtccsid(*job) output(*print) dbgview(*all)")
208
+ touch '$@'
209
+ endef
210
+
186
211
  # Build program from modules
187
212
  define BUILD_MODULE_TO_PGM
188
213
  $(call SETUP_LOG,$(notdir $@))
@@ -246,6 +271,38 @@ EOF
246
271
  touch '$@'
247
272
  endef
248
273
 
274
+ # Build printer file
275
+ define BUILD_PRTF_TO_FILE
276
+ $(call SETUP_LOG,$(notdir $@))
277
+ $(call CREATE_SOURCE_MEMBER,$<,qddssrc)
278
+ $(SSH) $(QSHELL) <<'EOF'
279
+ $(SET_LIBL)
280
+ system "crtprtf file($(LIBRARY)/$(basename $(@F))) srcfile($(LIBRARY)/qddssrc)"
281
+ EOF
282
+ touch '$@'
283
+ endef
284
+
285
+ # Build SQL table
286
+ define BUILD_SQLTABLE_TO_FILE
287
+ $(call SETUP_LOG,$(notdir $@))
288
+ $(call REMOTE_BUILD,$(filter-out build/%,$^),system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(LIBRARY))")
289
+ touch '$@'
290
+ endef
291
+
292
+ # Build SQL index
293
+ define BUILD_SQLINDEX_TO_FILE
294
+ $(call SETUP_LOG,$(notdir $@))
295
+ $(call REMOTE_BUILD,$(filter-out build/%,$^),system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(LIBRARY))")
296
+ touch '$@'
297
+ endef
298
+
299
+ # Build SQL procedure
300
+ define BUILD_SQLPROC_TO_PGM
301
+ $(call SETUP_LOG,$(notdir $@))
302
+ $(call REMOTE_BUILD,$(filter-out build/%,$^),system "runsqlstm srcstmf('$<') commit(*none) dftrdbcol($(LIBRARY))")
303
+ touch '$@'
304
+ endef
305
+
249
306
  # Build message file from CL commands
250
307
  define BUILD_MSGF
251
308
  $(call SETUP_LOG,$(notdir $@))
@@ -282,8 +339,14 @@ platform-clean:
282
339
  if [ -n "$$CLEAN_TARGETS" ]; then
283
340
  $(SSH) $(QSHELL) <<EOF
284
341
  if [ -d $(LIBRARY_PATH) ]; then
285
- for target in $$CLEAN_TARGETS; do
286
- rm -rf "$(LIBRARY_PATH)/\$$target"
342
+ for pass in 1 2; do
343
+ for target in $$CLEAN_TARGETS; do
344
+ if [ "\$${target%.file}" != "\$$target" ]; then
345
+ system "dltf $(LIBRARY)/\$${target%.file}" > /dev/null 2>&1 || true
346
+ else
347
+ rm -rf "$(LIBRARY_PATH)/\$$target"
348
+ fi
349
+ done
287
350
  done
288
351
  fi
289
352
  EOF
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@profoundlogic/codermake",
3
- "version": "1.0.2",
3
+ "version": "1.2.0",
4
4
  "description": "Make wrapper framework for IBM i development that simplifies build rules",
5
5
  "main": "dist/bin/index.js",
6
6
  "type": "module",
@@ -37,6 +37,7 @@
37
37
  "dist/bin/",
38
38
  "dist/lib/",
39
39
  "dist/makefiles/",
40
+ "skills/",
40
41
  "README.md",
41
42
  "LICENSE.txt"
42
43
  ]
@@ -0,0 +1,201 @@
1
+ ---
2
+ name: codermake
3
+ description: Build IBM i objects from source code.
4
+ ---
5
+
6
+ # codermake
7
+
8
+ codermake is a Make-based build tool for IBM i projects. It compiles RPG, CL, DDS, and SQL source into IBM i objects (programs, modules, service programs, files, menus, message files, binding directories) either locally on IBM i or remotely via SSH.
9
+
10
+ ## Key constraints
11
+
12
+ - **Never modify Makefiles.** codermake auto-generates Makefiles from `Rules.mk` files. Only edit `Rules.mk`.
13
+ - **Never modify environment variables or `.env` files** unless the user explicitly asks. Build configuration belongs to the user.
14
+ - **Source names and target names do not need to match.** The preprocessor infers the correct recipe from file extensions alone.
15
+
16
+ ## Building
17
+
18
+ Run codermake from the project root:
19
+
20
+ ```bash
21
+ # Build everything
22
+ codermake
23
+
24
+ # Build a single target
25
+ codermake <target> # e.g. codermake mypgm.pgm
26
+
27
+ # Dry run (show what would build, without building)
28
+ codermake -n
29
+
30
+ # Clean all build artifacts
31
+ codermake clean
32
+
33
+ # Show the generated Makefile rules (useful for debugging)
34
+ codermake --print-rules
35
+ ```
36
+
37
+ Build output for each target is logged to `tmp/logs/<target>.log`.
38
+
39
+ ## Rules.mk syntax
40
+
41
+ Each source directory contains a `Rules.mk` file that declares build targets and their prerequisites. codermake automatically adds path prefixes (`src/`, `build/`, etc.) based on file extensions -- you write only bare filenames.
42
+
43
+ ### Basic rules
44
+
45
+ ```makefile
46
+ # program from RPG source
47
+ mypgm.pgm: mypgm.rpgle
48
+
49
+ # program from RPG source, depends on a display file
50
+ mypgm.pgm: mypgm.rpgle myscreen.file
51
+
52
+ # display file from DDS
53
+ myscreen.file: myscreen.dspf
54
+
55
+ # physical file from DDS
56
+ custdata.file: custdata.pf
57
+
58
+ # ILE CL program
59
+ setup.pgm: setup.clle
60
+ ```
61
+
62
+ ### Order-only prerequisites
63
+
64
+ Use `|` for objects that must exist before building the target but should not trigger a rebuild when they change. This is typical for binding directories and database files.
65
+
66
+ ```makefile
67
+ mypgm.pgm: mypgm.rpgle mysrvpgm.srvpgm | mybnddir.bnddir mytable.file
68
+ ```
69
+
70
+ ### Cross-directory references
71
+
72
+ Files with a path separator are treated as relative to the project root (not the Rules.mk directory):
73
+
74
+ ```makefile
75
+ # In app/Rules.mk -- reference an exports file in the common/ directory
76
+ mysrvpgm.srvpgm: mymod.module common/api.exports
77
+ ```
78
+
79
+ ### Message files and binding directories (dual-purpose pattern)
80
+
81
+ The `.msgf` and `.bnddir` extensions serve double duty -- as source when they are the first prerequisite of a matching target type, and as built objects everywhere else:
82
+
83
+ ```makefile
84
+ # Build a message file (source file -> object)
85
+ appmsg.msgf: appmsg.msgf
86
+
87
+ # Build a binding directory (source file -> object)
88
+ mybnddir.bnddir: mybnddir.bnddir
89
+
90
+ # Use them as dependencies (treated as built objects)
91
+ mymenu.menu: mymenu.file appmsg.msgf
92
+ setup.pgm: setup.rpgle | mybnddir.bnddir
93
+ ```
94
+
95
+ The `.msgf` source file contains CL commands (`CRTMSGF`, `ADDMSGD`, etc.). The `.bnddir` source file contains CL commands (`CRTBNDDIR`, `ADDBNDDIRE`, etc.).
96
+
97
+ ### Modules and service programs
98
+
99
+ ```makefile
100
+ # Compile source to a module
101
+ mymod.module: mymod.rpgle
102
+
103
+ # Link modules into a program
104
+ mypgm.pgm: mod1.module mod2.module
105
+
106
+ # Create a service program from modules + export list
107
+ mysrvpgm.srvpgm: mymod.module mymod.exports
108
+ ```
109
+
110
+ The `.exports` file is a text file listing exported procedure symbols:
111
+
112
+ ```
113
+ STRPGMEXP PGMLVL(*CURRENT) SIGNATURE(*GEN)
114
+ EXPORT SYMBOL("myProcedure")
115
+ EXPORT SYMBOL("anotherProc")
116
+ ENDPGMEXP
117
+ ```
118
+
119
+ ## Quick reference: source-to-object mapping
120
+
121
+ | Source extension | Target extension | IBM i object | CL command |
122
+ |---|---|---|---|
123
+ | `.rpgle` | `.pgm` | Program (*PGM) | `CRTBNDRPG` |
124
+ | `.rpgle` | `.module` | Module (*MODULE) | `CRTRPGMOD` |
125
+ | `.sqlrpgle` | `.pgm` | Program (*PGM) | `CRTSQLRPGI OBJTYPE(*PGM)` |
126
+ | `.sqlrpgle` | `.module` | Module (*MODULE) | `CRTSQLRPGI OBJTYPE(*MODULE)` |
127
+ | `.clle` | `.pgm` | Program (*PGM) | `CRTBNDCL` |
128
+ | `.clle` | `.module` | Module (*MODULE) | `CRTCLMOD` |
129
+ | `.clp` / `.cl` | `.pgm` | Program (*PGM) | `CRTCLPGM` |
130
+ | `.proc.sql` | `.pgm` | SQL Procedure (*PGM) | `RUNSQLSTM` |
131
+ | `.module` (1+) | `.pgm` | Program (*PGM) | `CRTPGM` |
132
+ | `.module` + `.exports` | `.srvpgm` | Service Program (*SRVPGM) | `CRTSRVPGM` |
133
+ | `.dspf` | `.file` | Display File (*FILE) | `CRTDSPF` |
134
+ | `.json` (RDF) | `.file` | Display File (*FILE) | `CRTDSPF` |
135
+ | `.pf` | `.file` | Physical File (*FILE) | `CRTPF` |
136
+ | `.lf` | `.file` | Logical File (*FILE) | `CRTLF` |
137
+ | `.prtf` | `.file` | Printer File (*FILE) | `CRTPRTF` |
138
+ | `.table.sql` | `.file` | SQL Table (*FILE) | `RUNSQLSTM` |
139
+ | `.index.sql` | `.file` | SQL Index (*FILE) | `RUNSQLSTM` |
140
+ | `.file` + `.msgf` | `.menu` | Menu (*MENU) | `CRTMNU` |
141
+ | `.msgf` (CL src) | `.msgf` | Message File (*MSGF) | `CRTMSGF` / `ADDMSGD` |
142
+ | `.bnddir` (CL src) | `.bnddir` | Binding Dir (*BNDDIR) | `CRTBNDDIR` / `ADDBNDDIRE` |
143
+
144
+ For full details on every type, see [references/file-types.md](references/file-types.md).
145
+
146
+ ## Adding a new target
147
+
148
+ Follow this procedure when adding a new object to the build:
149
+
150
+ 1. **Create the source file** in the appropriate source directory (e.g., `src/newpgm.rpgle`).
151
+ 2. **Add a rule to `Rules.mk`** in that directory:
152
+ ```makefile
153
+ newpgm.pgm: newpgm.rpgle
154
+ ```
155
+ 3. **Declare dependencies** on any objects that must exist first:
156
+ ```makefile
157
+ newpgm.pgm: newpgm.rpgle myscreen.file mysrvpgm.srvpgm | mybnddir.bnddir
158
+ ```
159
+ 4. **Build and verify:**
160
+ ```bash
161
+ codermake newpgm.pgm
162
+ ```
163
+ 5. **Check logs on failure:** `tmp/logs/newpgm.pgm.log`
164
+
165
+ If the target is a module destined for a service program or multi-module program, also add the downstream rule:
166
+
167
+ ```makefile
168
+ newmod.module: newmod.rpgle
169
+ existing.srvpgm: existing_mod.module newmod.module existing.exports
170
+ ```
171
+
172
+ ## Troubleshooting
173
+
174
+ Build logs are in `tmp/logs/<target>.log`. When a build fails:
175
+
176
+ 1. Open the log file for the failing target.
177
+ 2. Search for error message IDs (e.g., `RNF`, `SQL`, `CPF`, `CPD`).
178
+ 3. For RPG/SQL RPG, look at the message summary near the end of the listing -- severity 30+ messages are errors.
179
+ 4. For DDS/CL, look for `CPF` or `CPD` message IDs in the output.
180
+ 5. Use `codermake --print-rules` to verify the generated Makefile if the target is not being built at all.
181
+
182
+ For detailed guidance on reading compile listings, see [references/compile-listings.md](references/compile-listings.md).
183
+
184
+ ## Environment variables
185
+
186
+ codermake reads its configuration from environment variables (typically set in a `.env` file at the project root).
187
+
188
+ ### Remote builds (from Linux/macOS to IBM i via SSH)
189
+
190
+ | Variable | Description |
191
+ |---|---|
192
+ | `IBMI_BUILD_LIBRARY` | Target IBM i library for compiled objects |
193
+ | `IBMI_HOST` | IBM i hostname or IP address |
194
+ | `IBMI_USER` | SSH username on the IBM i |
195
+ | `IBMI_KEY` | Path to SSH private key (optional) |
196
+
197
+ ### Local builds (on IBM i PASE)
198
+
199
+ | Variable | Description |
200
+ |---|---|
201
+ | `BUILD_LIBRARY` | Target IBM i library for compiled objects |
@@ -0,0 +1,141 @@
1
+ # Compile Listings Reference
2
+
3
+ Guide to finding and interpreting IBM i compile listings produced by codermake builds.
4
+
5
+ ## Where to find logs
6
+
7
+ Every build target produces a log file at:
8
+
9
+ ```
10
+ tmp/logs/<target>.log
11
+ ```
12
+
13
+ For example, building `mypgm.pgm` writes to `tmp/logs/mypgm.pgm.log`.
14
+
15
+ ## RPG listings (.rpgle)
16
+
17
+ RPG compile listings from `CRTBNDRPG` or `CRTRPGMOD` follow a standard structure:
18
+
19
+ 1. **Header** -- compiler version, source file path, compile options
20
+ 2. **Source listing** -- numbered source lines (may include copy members)
21
+ 3. **Additional diagnostics** -- cross-reference tables, data structure layouts
22
+ 4. **Message summary** -- all diagnostic messages grouped by severity
23
+
24
+ ### Reading the message summary
25
+
26
+ The message summary appears near the end of the listing. Each entry shows:
27
+
28
+ ```
29
+ MSG ID SEV LINE TEXT
30
+ RNF7031 00 12 The name or indicator is not referenced.
31
+ RNF7066 00 45 A semicolon is expected ...
32
+ RNF5377 30 78 The type of expression does not match ...
33
+ ```
34
+
35
+ **Severity levels:**
36
+
37
+ | Severity | Meaning | Action |
38
+ |---|---|---|
39
+ | 00 | Informational | Safe to ignore |
40
+ | 10 | Warning | Review but usually benign |
41
+ | 20 | Error (recoverable) | Compiler attempted to continue; fix recommended |
42
+ | 30 | Severe error | Compilation failed; must fix |
43
+ | 40+ | Unrecoverable | Compilation failed; must fix |
44
+
45
+ Search for severity 30+ messages to find the root cause of a build failure. The `LINE` column tells you which source line triggered the error.
46
+
47
+ ### Common RPG message IDs
48
+
49
+ | ID prefix | Area |
50
+ |---|---|
51
+ | `RNF` | RPG compiler messages |
52
+ | `RNS` | RPG compiler (structured) |
53
+ | `SQL` | Embedded SQL messages (in SQLRPGLE) |
54
+
55
+ ## SQL RPG listings (.sqlrpgle)
56
+
57
+ SQL RPG compilation is a two-phase process:
58
+
59
+ 1. **SQL precompile** (`CRTSQLRPGI`) -- translates embedded SQL into RPG call statements
60
+ 2. **RPG compile** -- compiles the resulting RPG source
61
+
62
+ The log contains output from both phases. When debugging:
63
+
64
+ - **SQL errors** appear in the first phase. Look for `SQL` message IDs.
65
+ - **RPG errors** appear in the second phase. Look for `RNF`/`RNS` message IDs.
66
+ - If the SQL precompile fails, the RPG compile does not run.
67
+
68
+ ### SQL precompile messages
69
+
70
+ ```
71
+ SQL0104 30 Position 45 Token "SELEC" was not valid. Valid tokens: ...
72
+ SQL0204 20 Table "MYLIB/NOTABLE" not found.
73
+ ```
74
+
75
+ The position or line number tells you where in the embedded SQL the error occurred.
76
+
77
+ ## CL listings (.clle, .clp, .cl)
78
+
79
+ CL compile errors appear as `CPD` or `CPF` messages:
80
+
81
+ ```
82
+ CPD0727 30 The character value specified is not a valid name.
83
+ CPF0001 40 Error found on CALL command.
84
+ ```
85
+
86
+ For ILE CL (`CRTBNDCL`, `CRTCLMOD`), the listing structure is similar to RPG -- source listing followed by a message summary.
87
+
88
+ For OPM CL (`CRTCLPGM`), the output is typically shorter and errors reference source sequence numbers.
89
+
90
+ ## DDS listings (.dspf, .pf, .lf, .prtf)
91
+
92
+ DDS compilation errors from `CRTDSPF`, `CRTPF`, `CRTLF`, or `CRTPRTF` produce `CPD` messages:
93
+
94
+ ```
95
+ CPD7302 30 Record format SCREEN1 not found in file referenced.
96
+ CPD7344 30 Keyword REF not valid for this type of file.
97
+ ```
98
+
99
+ DDS errors typically reference a specific record format and line within the source.
100
+
101
+ ## SQL DDL listings (.table.sql, .index.sql, .proc.sql)
102
+
103
+ SQL DDL statements executed via `RUNSQLSTM` produce SQL messages:
104
+
105
+ ```
106
+ SQL0104 30 Token "CREAT" was not valid.
107
+ SQL0601 20 Table EMPLOYEE in MYLIB already exists.
108
+ SQL7905 10 Module *N in *N not found.
109
+ ```
110
+
111
+ - Severity 30+ means the statement failed.
112
+ - Severity 20 warnings (like "already exists") may or may not be a problem depending on context.
113
+
114
+ ## Message files and binding directories (.msgf, .bnddir)
115
+
116
+ These execute CL commands from a source file. Errors appear as `CPF` or `CPD` messages from the individual CL commands:
117
+
118
+ ```
119
+ CPF2112 40 Object APPMSG type *MSGF already exists in library MYLIB.
120
+ CPF2105 30 Object MYSRVPGM in MYLIB type *SRVPGM not found.
121
+ ```
122
+
123
+ ## Practical example
124
+
125
+ A build of `mypgm.pgm` fails. Here is how to diagnose it:
126
+
127
+ ```bash
128
+ # 1. Check the log
129
+ cat tmp/logs/mypgm.pgm.log
130
+
131
+ # 2. Search for high-severity messages
132
+ grep -E 'RNF.{4}\s+[34]0|SQL.{4}\s+[34]0|CPD.{4}\s+[34]0|CPF.{4}\s+[34]0' tmp/logs/mypgm.pgm.log
133
+ ```
134
+
135
+ Example output:
136
+
137
+ ```
138
+ RNF5377 30 42 The type of expression does not match the type expected.
139
+ ```
140
+
141
+ This tells you line 42 of the RPG source has a type mismatch. Open the source file, go to line 42, and fix the expression type.