1 : // -*- C++ -*-
2 :
3 : #include <string>
4 : #include <ept/token.h>
5 : #include <ept/core/apt.h>
6 : #include <apt-pkg/algorithms.h>
7 :
8 : #ifndef EPT_APT_ACTION_H
9 : #define EPT_APT_ACTION_H
10 :
11 : namespace ept {
12 : namespace core {
13 : namespace package {
14 :
15 13 : struct Action {
16 : enum Type { Install, ReInstall, Remove, Keep, Purge, SystemUpgrade };
17 : Token m_token;
18 : Type m_type;
19 :
20 4 : Token token() { return m_token; }
21 : Type type() { return m_type; }
22 :
23 4 : void apply( package::Source &pkgs )
24 : {
25 4 : Type a = m_type;
26 4 : pkgDepCache &dc = pkgs.db().state();
27 :
28 4 : if ( a == SystemUpgrade ) {
29 0 : pkgDistUpgrade( dc );
30 : } else {
31 4 : if ( !pkgs.exists( m_token ) )
32 0 : return;
33 4 : pkgCache::PkgIterator p = pkgs.lookupToken( m_token );
34 :
35 4 : pkgProblemResolver fix( &dc );
36 8 : if ( a == Install || a == ReInstall ) {
37 2 : fix.Clear( p );
38 2 : fix.Protect( p );
39 2 : dc.MarkInstall( p, true );
40 2 : fix.InstallProtect();
41 2 : if ( a == ReInstall )
42 0 : dc.SetReInstall( p, true );
43 2 : } else if ( a == Remove || a == Purge ) {
44 0 : fix.Clear( p );
45 0 : fix.Protect( p );
46 0 : fix.Remove( p );
47 0 : dc.MarkDelete( p, a == Purge ? true : false );
48 2 : } else if ( a == Keep ) {
49 2 : fix.Clear( p );
50 2 : fix.Protect( p );
51 2 : dc.MarkKeep( p, true );
52 : }
53 4 : fix.Resolve( true );
54 : }
55 : }
56 :
57 : bool redundant( package::Source &pkgs ) {
58 : if ( m_type == SystemUpgrade ) {
59 : // check whether we have any upgradable packages
60 : return false;
61 : }
62 : if ( !pkgs.exists( m_token ) )
63 : return true;
64 : PackageState s = pkgs.db().packageState( m_token );
65 : Type a = m_type;
66 : // if ( a == Keep && !s.upgradable() )
67 : // return true;
68 : if ( ( a == Install || a == ReInstall )
69 : && ( !s.upgradable() && s.installed() ) )
70 : return true;
71 : if ( ( a == Remove || a == Purge ) && !s.installed() )
72 : return true;
73 : return false;
74 : }
75 :
76 6 : Action( Token t, Type a )
77 6 : : m_token( t ), m_type( a )
78 6 : {}
79 : };
80 :
81 2 : struct ActionList {
82 : typedef std::vector< Action > List;
83 : List m_list;
84 :
85 : void clear() {
86 : m_list.clear();
87 : }
88 :
89 1 : bool empty() {
90 1 : return m_list.empty();
91 : }
92 :
93 3 : void add( Action a ) {
94 3 : List::iterator rm = m_list.end(), i;
95 3 : for ( i = m_list.begin(); i != m_list.end(); ++i ) {
96 2 : if ( i->token() == a.token() ) {
97 2 : rm = i;
98 2 : break;
99 : }
100 : }
101 3 : if ( rm != m_list.end() )
102 2 : m_list.erase( rm );
103 : // if ( a.type() != Action::Keep )
104 3 : m_list.push_back( a );
105 3 : }
106 :
107 : Action latest() {
108 : return m_list.back();
109 : }
110 :
111 1 : void replay( package::Source &pkgs ) {
112 2 : for ( List::iterator i = m_list.begin(); i != m_list.end(); ++i ) {
113 1 : i->apply( pkgs );
114 : }
115 1 : }
116 :
117 : void prune( package::Source &pkgs ) {
118 : List l;
119 : std::swap( l, m_list );
120 : for ( List::iterator i = m_list.begin(); i != m_list.end(); ++i ) {
121 : if ( !i->redundant( pkgs ) )
122 : m_list.push_back( *i );
123 : }
124 : /* We want to do but can't bind reference parameters.... (or
125 : maybe use remove_copy_if or whatever ... ugly
126 : std::remove_if( m_list.begin(), m_list.end(), std::bind2nd(
127 : std::mem_fun_ref( &Action::redundant ), pkgs ) ); */
128 : }
129 : };
130 :
131 : }
132 : }
133 : }
134 :
135 : #endif
|